Skip to content

Commit

Permalink
wip: custom validation properties panel
Browse files Browse the repository at this point in the history
  • Loading branch information
Skaiir committed Apr 10, 2024
1 parent 14a6f61 commit 022ee05
Show file tree
Hide file tree
Showing 5 changed files with 216 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
SerializationGroup,
ConstraintsGroup,
ValidationGroup,
CustomValidationsGroup,
OptionsGroups,
TableHeaderGroups,
LayoutGroup,
Expand Down Expand Up @@ -72,6 +73,7 @@ export class PropertiesProvider {
SerializationGroup(field, editField),
ConstraintsGroup(field, editField),
ValidationGroup(field, editField),
CustomValidationsGroup(field, editField),
CustomPropertiesGroup(field, editField)
].filter(group => group != null);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import {
get,
set
} from 'min-dash';

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

import { TextFieldEntry, FeelEntry } from '@bpmn-io/properties-panel';
import { useCallback } from 'preact/hooks';


export function CustomValidationEntry(props) {
const {
editField,
field,
idPrefix,
index
} = props;

const entries = [
{
component: Condition,
editField,
field,
id: idPrefix + '-condition',
idPrefix,
index
},
{
component: Message,
editField,
field,
id: idPrefix + '-message',
idPrefix,
index
}
];

return entries;
}

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

const debounce = useService('debounce');


const setValue = (value, error) => {
if (error) {
return;
}

const validate = get(field, [ 'validate' ]);
const newValidate = set(validate, [ 'custom', index, 'condition' ], value);

return editField(field, 'validate', newValidate);
};

const getValue = () => {
return get(field, [ 'validate', 'custom', index, 'condition' ]);
};

const conditionEntryValidate = useCallback((value) => {
if (typeof value !== 'string' || value.length === 0) {
return 'Must not be empty.';
}
}, []);

return FeelEntry({
feel: 'required',
debounce,
element: field,
getValue,
id,
label: 'Condition',
setValue,
validate: conditionEntryValidate
});
}

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

const debounce = useService('debounce');

const setValue = (value, error) => {
if (error) {
return;
}

const validate = get(field, [ 'validate' ]);
const newValidate = set(validate, [ 'custom', index, 'message' ], value);

return editField(field, 'validate', newValidate);
};

const getValue = () => {
return get(field, [ 'validate', 'custom', index, 'message' ]);
};

const messageEntryValidate = useCallback((value) => {
if (typeof value !== 'string' || value.length === 0) {
return 'Must not be empty.';
}
}, []);

return TextFieldEntry({
debounce,
element: field,
getValue,
id,
label: 'Message',
setValue,
validate: messageEntryValidate
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import {
get,
set,
without
} from 'min-dash';

import { arrayAdd } from '../Util';

import {
ListGroup
} from '@bpmn-io/properties-panel';

import { VALIDATION_TYPE_OPTIONS } from './ValidationGroup';
import { CustomValidationEntry } from '../entries/CustomValidationEntry';

export function CustomValidationsGroup(field, editField) {

const validate = get(field, [ 'validate' ], {});
const shouldRender = [ undefined, VALIDATION_TYPE_OPTIONS.custom.value ].includes(validate.validationType);

if (!shouldRender) {
return;
}

return {
id: 'custom-validation',
label: 'Custom Validations',
component: ListGroup,
...CustomValidationsEntry({ editField, field, id: 'custom-validation-list' })
};
}


export function CustomValidationsEntry(props) {
const {
editField,
field,
id: idPrefix
} = props;

const addEntry = (e) => {

e.stopPropagation();

const customValidations = get(field, [ 'validate', 'custom' ], []);
const newIndex = customValidations.length + 1;
const newValue = {
condition: 'false',
message: 'Error'
};

const newArray = arrayAdd(customValidations, newIndex, newValue);
const newValidate = set(field.validate, [ 'custom' ], newArray);

editField(field, [ 'validate' ], newValidate);
};

const removeEntry = (entry) => {
const customValidations = get(field, [ 'validate', 'custom' ], []);
const newArray = without(customValidations, entry);
const newValidate = set(field.validate, [ 'custom' ], newArray);

editField(field, [ 'validate' ], newValidate);
};

const items = get(field, [ 'validate', 'custom' ], []).map((entry, index) => {
const id = idPrefix + '-' + index;

return {
id,
entries: CustomValidationEntry({
editField,
field,
idPrefix,
index
}),
remove: () => removeEntry(entry)
};
});

return {
items,
add: addEntry,
shouldSort: false
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { useService, useVariables } from '../hooks';

import { INPUTS } from '../Util';

const VALIDATION_TYPE_OPTIONS = {
export const VALIDATION_TYPE_OPTIONS = {
custom: {
value: '',
label: 'Custom',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export { GeneralGroup } from './GeneralGroup';
export { SerializationGroup } from './SerializationGroup';
export { ConstraintsGroup } from './ConstraintsGroup';
export { ValidationGroup } from './ValidationGroup';
export { CustomValidationsGroup } from './CustomValidationsGroup';
export { OptionsGroups } from './OptionsGroups';
export { CustomPropertiesGroup } from './CustomPropertiesGroup';
export { AppearanceGroup } from './AppearanceGroup';
Expand Down

0 comments on commit 022ee05

Please sign in to comment.