Skip to content

Commit 8becf41

Browse files
committed
feat: implement script component
1 parent 601ec7c commit 8becf41

File tree

20 files changed

+425
-72
lines changed

20 files changed

+425
-72
lines changed

package-lock.json

Lines changed: 33 additions & 40 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/form-js-editor/src/features/palette/components/Palette.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ export const PALETTE_GROUPS = [
4141
label: 'Containers',
4242
id: 'container'
4343
},
44+
{
45+
label: 'Advanced',
46+
id: 'advanced'
47+
},
4448
{
4549
label: 'Action',
4650
id: 'action'

packages/form-js-editor/src/features/properties-panel/entries/ConditionEntry.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ function Condition(props) {
5050
let description = 'Condition under which the field is hidden';
5151

5252
// special case for expression fields which do not render
53-
if (field.type === 'expression') {
53+
if ([ 'expression', 'script' ].includes(field.type)) {
5454
label = 'Deactivate if';
5555
description = 'Condition under which the field is deactivated';
5656
}
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
import { FeelEntry, isFeelEntryEdited, TextAreaEntry, isTextAreaEntryEdited, SelectEntry, isSelectEntryEdited } from '@bpmn-io/properties-panel';
2+
import { get } from 'min-dash';
3+
import { simpleRangeIntegerEntryFactory } from './factories';
4+
5+
import { useService, useVariables } from '../hooks';
6+
7+
export function JSFunctionEntry(props) {
8+
const {
9+
editField,
10+
field
11+
} = props;
12+
13+
const entries = [
14+
{
15+
id: 'variable-mappings',
16+
component: FunctionParameters,
17+
editField: editField,
18+
field: field,
19+
isEdited: isFeelEntryEdited,
20+
isDefaultVisible: (field) => field.type === 'script'
21+
},
22+
{
23+
id: 'function',
24+
component: FunctionDefinition,
25+
editField: editField,
26+
field: field,
27+
isEdited: isTextAreaEntryEdited,
28+
isDefaultVisible: (field) => field.type === 'script'
29+
},
30+
{
31+
id: 'computeOn',
32+
component: JSFunctionComputeOn,
33+
isEdited: isSelectEntryEdited,
34+
editField,
35+
field,
36+
isDefaultVisible: (field) => field.type === 'script'
37+
},
38+
simpleRangeIntegerEntryFactory({
39+
id: 'interval',
40+
label: 'Time interval (ms)',
41+
path: [ 'interval' ],
42+
min: 100,
43+
max: 60000,
44+
props,
45+
isDefaultVisible: (field) => field.type === 'script' && field.computeOn === 'interval'
46+
})
47+
];
48+
49+
return entries;
50+
}
51+
52+
function FunctionParameters(props) {
53+
const {
54+
editField,
55+
field,
56+
id
57+
} = props;
58+
59+
const debounce = useService('debounce');
60+
61+
const variables = useVariables().map(name => ({ name }));
62+
63+
const path = [ 'functionParameters' ];
64+
65+
const getValue = () => {
66+
return get(field, path, '');
67+
};
68+
69+
const setValue = (value) => {
70+
return editField(field, path, value || '');
71+
};
72+
73+
const tooltip = <div>
74+
Functions parameters should be described as an object, e.g.:
75+
<pre><code>{`{
76+
name: user.name,
77+
age: user.age
78+
}`}</code></pre>
79+
</div>;
80+
81+
return FeelEntry({
82+
debounce,
83+
feel: 'required',
84+
element: field,
85+
getValue,
86+
id,
87+
label: 'Function parameters',
88+
tooltip,
89+
description: 'Define the parameters to pass to the javascript sandbox.',
90+
setValue,
91+
variables
92+
});
93+
}
94+
95+
function FunctionDefinition(props) {
96+
const {
97+
editField,
98+
field,
99+
id
100+
} = props;
101+
102+
const debounce = useService('debounce');
103+
104+
const path = [ 'jsFunction' ];
105+
106+
const getValue = () => {
107+
return get(field, path, '');
108+
};
109+
110+
const setValue = (value) => {
111+
return editField(field, path, value || '');
112+
};
113+
114+
return TextAreaEntry({
115+
debounce,
116+
element: field,
117+
getValue,
118+
description: 'Define the javascript function to execute.\nAccess the `data` object and use `setValue` to update the form state.',
119+
id,
120+
label: 'Javascript code',
121+
setValue
122+
});
123+
}
124+
125+
function JSFunctionComputeOn(props) {
126+
const { editField, field, id } = props;
127+
128+
const getValue = () => field.computeOn || '';
129+
130+
const setValue = (value) => {
131+
editField(field, [ 'computeOn' ], value);
132+
};
133+
134+
const getOptions = () => ([
135+
{ value: 'load', label: 'Form load' },
136+
{ value: 'change', label: 'Value change' },
137+
{ value: 'interval', label: 'Time interval' }
138+
]);
139+
140+
return SelectEntry({
141+
id,
142+
label: 'Compute on',
143+
description: 'Define when to execute the function',
144+
getValue,
145+
setValue,
146+
getOptions
147+
});
148+
}

packages/form-js-editor/src/features/properties-panel/entries/KeyEntry.js

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { useService } from '../hooks';
66

77
import { TextFieldEntry, isTextFieldEntryEdited } from '@bpmn-io/properties-panel';
88
import { useCallback } from 'preact/hooks';
9+
import { simpleBoolEntryFactory } from './factories';
910

1011

1112
export function KeyEntry(props) {
@@ -15,20 +16,32 @@ export function KeyEntry(props) {
1516
getService
1617
} = props;
1718

18-
const entries = [];
19-
20-
entries.push({
21-
id: 'key',
22-
component: Key,
23-
editField: editField,
24-
field: field,
25-
isEdited: isTextFieldEntryEdited,
26-
isDefaultVisible: (field) => {
27-
const formFields = getService('formFields');
28-
const { config } = formFields.get(field.type);
29-
return config.keyed;
30-
}
31-
});
19+
const formFields = getService('formFields');
20+
21+
const entries = [
22+
{
23+
id: 'key',
24+
component: Key,
25+
editField: editField,
26+
field: field,
27+
isEdited: isTextFieldEntryEdited,
28+
isDefaultVisible: (field) => {
29+
const { config } = formFields.get(field.type);
30+
return config.keyed;
31+
}
32+
},
33+
simpleBoolEntryFactory({
34+
id: 'doNotSubmit',
35+
label: 'Do not submit',
36+
tooltip: 'Prevents the data associated with this form element from being submitted by the form. Use for intermediate calculations.',
37+
path: [ 'doNotSubmit' ],
38+
props,
39+
isDefaultVisible: (field) => {
40+
const { config } = formFields.get(field.type);
41+
return config.keyed && config.allowDoNotSubmit;
42+
}
43+
})
44+
];
3245

3346
return entries;
3447
}

packages/form-js-editor/src/features/properties-panel/entries/factories/simpleBoolEntryFactory.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export function simpleBoolEntryFactory(options) {
66
id,
77
label,
88
description,
9+
tooltip,
910
path,
1011
props,
1112
getValue,
@@ -25,6 +26,7 @@ export function simpleBoolEntryFactory(options) {
2526
field,
2627
editField,
2728
description,
29+
tooltip,
2830
component: SimpleBoolComponent,
2931
isEdited: isToggleSwitchEntryEdited,
3032
isDefaultVisible,

0 commit comments

Comments
 (0)