Skip to content

Commit

Permalink
feat: implement script component
Browse files Browse the repository at this point in the history
  • Loading branch information
Skaiir committed Mar 25, 2024
1 parent 601ec7c commit 8becf41
Show file tree
Hide file tree
Showing 20 changed files with 425 additions and 72 deletions.
73 changes: 33 additions & 40 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ export const PALETTE_GROUPS = [
label: 'Containers',
id: 'container'
},
{
label: 'Advanced',
id: 'advanced'
},
{
label: 'Action',
id: 'action'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ function Condition(props) {
let description = 'Condition under which the field is hidden';

// special case for expression fields which do not render
if (field.type === 'expression') {
if ([ 'expression', 'script' ].includes(field.type)) {
label = 'Deactivate if';
description = 'Condition under which the field is deactivated';
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import { FeelEntry, isFeelEntryEdited, TextAreaEntry, isTextAreaEntryEdited, SelectEntry, isSelectEntryEdited } from '@bpmn-io/properties-panel';
import { get } from 'min-dash';
import { simpleRangeIntegerEntryFactory } from './factories';

import { useService, useVariables } from '../hooks';

export function JSFunctionEntry(props) {
const {
editField,
field
} = props;

const entries = [
{
id: 'variable-mappings',
component: FunctionParameters,
editField: editField,
field: field,
isEdited: isFeelEntryEdited,
isDefaultVisible: (field) => field.type === 'script'
},
{
id: 'function',
component: FunctionDefinition,
editField: editField,
field: field,
isEdited: isTextAreaEntryEdited,
isDefaultVisible: (field) => field.type === 'script'
},
{
id: 'computeOn',
component: JSFunctionComputeOn,
isEdited: isSelectEntryEdited,
editField,
field,
isDefaultVisible: (field) => field.type === 'script'
},
simpleRangeIntegerEntryFactory({
id: 'interval',
label: 'Time interval (ms)',
path: [ 'interval' ],
min: 100,
max: 60000,
props,
isDefaultVisible: (field) => field.type === 'script' && field.computeOn === 'interval'
})
];

return entries;
}

function FunctionParameters(props) {
const {
editField,
field,
id
} = props;

const debounce = useService('debounce');

const variables = useVariables().map(name => ({ name }));

const path = [ 'functionParameters' ];

const getValue = () => {
return get(field, path, '');
};

const setValue = (value) => {
return editField(field, path, value || '');
};

const tooltip = <div>
Functions parameters should be described as an object, e.g.:
<pre><code>{`{
name: user.name,
age: user.age
}`}</code></pre>
</div>;

return FeelEntry({
debounce,
feel: 'required',
element: field,
getValue,
id,
label: 'Function parameters',
tooltip,
description: 'Define the parameters to pass to the javascript sandbox.',
setValue,
variables
});
}

function FunctionDefinition(props) {
const {
editField,
field,
id
} = props;

const debounce = useService('debounce');

const path = [ 'jsFunction' ];

const getValue = () => {
return get(field, path, '');
};

const setValue = (value) => {
return editField(field, path, value || '');
};

return TextAreaEntry({
debounce,
element: field,
getValue,
description: 'Define the javascript function to execute.\nAccess the `data` object and use `setValue` to update the form state.',
id,
label: 'Javascript code',
setValue
});
}

function JSFunctionComputeOn(props) {
const { editField, field, id } = props;

const getValue = () => field.computeOn || '';

const setValue = (value) => {
editField(field, [ 'computeOn' ], value);
};

const getOptions = () => ([
{ value: 'load', label: 'Form load' },
{ value: 'change', label: 'Value change' },
{ value: 'interval', label: 'Time interval' }
]);

return SelectEntry({
id,
label: 'Compute on',
description: 'Define when to execute the function',
getValue,
setValue,
getOptions
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { useService } from '../hooks';

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


export function KeyEntry(props) {
Expand All @@ -15,20 +16,32 @@ export function KeyEntry(props) {
getService
} = props;

const entries = [];

entries.push({
id: 'key',
component: Key,
editField: editField,
field: field,
isEdited: isTextFieldEntryEdited,
isDefaultVisible: (field) => {
const formFields = getService('formFields');
const { config } = formFields.get(field.type);
return config.keyed;
}
});
const formFields = getService('formFields');

const entries = [
{
id: 'key',
component: Key,
editField: editField,
field: field,
isEdited: isTextFieldEntryEdited,
isDefaultVisible: (field) => {
const { config } = formFields.get(field.type);
return config.keyed;
}
},
simpleBoolEntryFactory({
id: 'doNotSubmit',
label: 'Do not submit',
tooltip: 'Prevents the data associated with this form element from being submitted by the form. Use for intermediate calculations.',
path: [ 'doNotSubmit' ],
props,
isDefaultVisible: (field) => {
const { config } = formFields.get(field.type);
return config.keyed && config.allowDoNotSubmit;
}
})
];

return entries;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export function simpleBoolEntryFactory(options) {
id,
label,
description,
tooltip,
path,
props,
getValue,
Expand All @@ -25,6 +26,7 @@ export function simpleBoolEntryFactory(options) {
field,
editField,
description,
tooltip,
component: SimpleBoolComponent,
isEdited: isToggleSwitchEntryEdited,
isDefaultVisible,
Expand Down
Loading

0 comments on commit 8becf41

Please sign in to comment.