/
PropertiesPanel.js
104 lines (81 loc) · 3.42 KB
/
PropertiesPanel.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import { PropertiesPanel as BasePropertiesPanel } from '@bpmn-io/properties-panel';
import { useCallback, useMemo, useState, useLayoutEffect } from 'preact/hooks';
import { reduce, isArray } from 'min-dash';
import { FormPropertiesPanelContext } from './context';
import { PropertiesPanelHeaderProvider } from './PropertiesPanelHeaderProvider';
import { PropertiesPanelPlaceholderProvider } from './PropertiesPanelPlaceholderProvider';
export function PropertiesPanel(props) {
const { eventBus, getProviders, injector } = props;
const formEditor = injector.get('formEditor');
const modeling = injector.get('modeling');
const selectionModule = injector.get('selection');
const propertiesPanelConfig = injector.get('config.propertiesPanel') || {};
const { feelPopupContainer } = propertiesPanelConfig;
const [state, setState] = useState({ selectedFormField: selectionModule.get() || formEditor._getState().schema });
const selectedFormField = state.selectedFormField;
const refresh = useCallback(
(field) => {
// TODO(skaiir): rework state management, re-rendering the whole properties panel is not the way to go
// https://github.com/bpmn-io/form-js/issues/686
setState({ selectedFormField: selectionModule.get() || formEditor._getState().schema });
// notify interested parties on property panel updates
eventBus.fire('propertiesPanel.updated', {
formField: field,
});
},
[eventBus, formEditor, selectionModule],
);
useLayoutEffect(() => {
/**
* TODO(pinussilvestrus): update with actual updated element,
* once we have a proper updater/change support
*/
eventBus.on('changed', refresh);
eventBus.on('import.done', refresh);
eventBus.on('selection.changed', refresh);
return () => {
eventBus.off('changed', refresh);
eventBus.off('import.done', refresh);
eventBus.off('selection.changed', refresh);
};
}, [eventBus, refresh]);
const getService = (type, strict = true) => injector.get(type, strict);
const propertiesPanelContext = { getService };
const onFocus = () => eventBus.fire('propertiesPanel.focusin');
const onBlur = () => eventBus.fire('propertiesPanel.focusout');
const editField = useCallback((formField, key, value) => modeling.editFormField(formField, key, value), [modeling]);
// retrieve groups for selected form field
const providers = getProviders(selectedFormField);
const groups = useMemo(() => {
return reduce(
providers,
function (groups, provider) {
// do not collect groups for multi element state
if (isArray(selectedFormField)) {
return [];
}
const updater = provider.getGroups(selectedFormField, editField);
return updater(groups);
},
[],
);
}, [providers, selectedFormField, editField]);
return (
<div
class="fjs-properties-panel"
data-field={selectedFormField && selectedFormField.id}
onFocusCapture={onFocus}
onBlurCapture={onBlur}>
<FormPropertiesPanelContext.Provider value={propertiesPanelContext}>
<BasePropertiesPanel
element={selectedFormField}
eventBus={eventBus}
groups={groups}
headerProvider={PropertiesPanelHeaderProvider}
placeholderProvider={PropertiesPanelPlaceholderProvider}
feelPopupContainer={feelPopupContainer}
/>
</FormPropertiesPanelContext.Provider>
</div>
);
}