in saga/seata-saga-statemachine-designer/src/properties-panel/PropertiesPanel.js [60:232]
export default function PropertiesPanel(props) {
const {
element,
injector,
getProviders,
layoutConfig,
descriptionConfig,
} = props;
const canvas = injector.get('canvas');
const elementRegistry = injector.get('elementRegistry');
const eventBus = injector.get('eventBus');
const [state, setState] = useState({
selectedElement: element,
});
const { selectedElement } = state;
/**
* @param {djs.model.Base | Array<djs.model.Base>} e
*/
const update = (e) => {
if (!e) {
return;
}
const newSelectedElement = e;
setState({
...state,
selectedElement: newSelectedElement,
});
// notify interested parties on property panel updates
eventBus.fire('propertiesPanel.updated', {
element: newSelectedElement,
});
};
// (2) react on element changes
// (2a) selection changed
useEffect(() => {
const onSelectionChanged = (e) => {
const { newSelection = [] } = e;
if (newSelection.length > 1) {
return update(newSelection);
}
const newElement = newSelection[0];
const rootElement = canvas.getRootElement();
if (isImplicitRoot(rootElement)) {
// TODO
}
update(newElement || rootElement);
return null;
};
eventBus.on('selection.changed', onSelectionChanged);
return () => {
eventBus.off('selection.changed', onSelectionChanged);
};
}, []);
// (2b) selected element changed
useEffect(() => {
const onElementsChanged = (e) => {
const { elements } = e;
const updatedElement = findElement(elements, selectedElement);
if (updatedElement && elementExists(updatedElement, elementRegistry)) {
update(updatedElement);
}
};
eventBus.on('elements.changed', onElementsChanged);
return () => {
eventBus.off('elements.changed', onElementsChanged);
};
}, [selectedElement]);
// (2c) root element changed
useEffect(() => {
const onRootAdded = (e) => {
const { element: root } = e;
if (isImplicitRoot(root)) {
return;
}
update(root);
};
eventBus.on('root.added', onRootAdded);
return () => {
eventBus.off('root.added', onRootAdded);
};
}, [selectedElement]);
// (2d) provided entries changed
useEffect(() => {
const onProvidersChanged = () => {
update(selectedElement);
};
eventBus.on('propertiesPanel.providersChanged', onProvidersChanged);
return () => {
eventBus.off('propertiesPanel.providersChanged', onProvidersChanged);
};
}, [selectedElement]);
// (3) create properties panel context
const propertiesPanelContext = useMemo(() => ({
selectedElement,
injector,
getService(type, strict) { return injector.get(type, strict); },
}), [selectedElement, injector]);
// (4) retrieve groups for selected element
const providers = getProviders(selectedElement);
const groups = useMemo(() => {
return reduce(providers, (g, provider) => {
// do not collect groups for multi element state
if (isArray(selectedElement)) {
return [];
}
const updater = provider.getGroups(selectedElement);
return updater(g);
}, []);
}, [providers, selectedElement]);
// (5) notify layout changes
const onLayoutChanged = (layout) => {
eventBus.fire('propertiesPanel.layoutChanged', {
layout,
});
};
// (6) notify description changes
const onDescriptionLoaded = (description) => {
eventBus.fire('propertiesPanel.descriptionLoaded', {
description,
});
};
return (
<PropertiesPanelContext.Provider value={propertiesPanelContext}>
<BasePropertiesPanel
element={selectedElement}
headerProvider={PanelHeaderProvider}
placeholderProvider={PanelPlaceholderProvider}
groups={groups}
layoutConfig={layoutConfig}
layoutChanged={onLayoutChanged}
descriptionConfig={descriptionConfig}
descriptionLoaded={onDescriptionLoaded}
eventBus={eventBus}
/>
</PropertiesPanelContext.Provider>
);
}