Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: implement custom validation #1141

Draft
wants to merge 10 commits into
base: develop
Choose a base branch
from
6 changes: 3 additions & 3 deletions .github/workflows/TASKLIST_CARBONISATION.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ jobs:
options: --user 1001:1000
steps:
- name: Checkout form-js
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
uses: actions/checkout@9a9194f87191a7e9055e3e9b95b8cfb13023bb08
with:
path: form-js
- name: Checkout Tasklist
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
uses: actions/checkout@9a9194f87191a7e9055e3e9b95b8cfb13023bb08
with:
repository: camunda/zeebe
token: ${{ secrets.ADD_TO_HTO_PROJECT_PAT }}
Expand Down Expand Up @@ -67,7 +67,7 @@ jobs:
- name: Run Playwright tests
working-directory: ./zeebe/tasklist/client
run: yarn playwright form-js-integration
- uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a
- uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874
if: always()
with:
name: playwright-report
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export class ValidateBehavior extends CommandInterceptor {

delete newValidate.minLength;
delete newValidate.maxLength;
delete newValidate.custom;
delete newValidate.pattern;

properties['validate'] = newValidate;
Expand Down
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 @@ -66,6 +67,7 @@ export class PropertiesProvider {
SerializationGroup(field, editField),
ConstraintsGroup(field, editField),
ValidationGroup(field, editField),
CustomValidationsGroup(field, editField, getService),
CustomPropertiesGroup(field, editField),
].filter((group) => group != null);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ function PrefixAdorner(props) {

const debounce = useService('debounce');

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

return FeelTemplatingEntry({
debounce,
Expand All @@ -72,7 +72,7 @@ function SuffixAdorner(props) {

const debounce = useService('debounce');

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

return FeelTemplatingEntry({
debounce,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ function AltText(props) {

const debounce = useService('debounce');

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

const path = ['alt'];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ function ColumnsExpression(props) {

const debounce = useService('debounce');

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

const getValue = () => {
return get(field, PATH);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ function Condition(props) {

const debounce = useService('debounce');

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

const path = ['conditional', 'hide'];

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

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

import { FeelEntry, isFeelEntryEdited } from '@bpmn-io/properties-panel';
import { useCallback, useMemo } 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 _variables = useVariables();

const variables = useMemo(
() => [{ name: 'value', type: 'keyword', info: 'Returns the current field value.' }, ..._variables],
[_variables],
);

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',
isEdited: isFeelEntryEdited,
debounce,
element: field,
getValue,
id,
label: 'Condition',
setValue,
validate: conditionEntryValidate,
variables,
});
}

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

const debounce = useService('debounce');
const _variables = useVariables();

const variables = useMemo(
() => [{ name: 'value', type: 'keyword', info: 'Returns the current field value.' }, ..._variables],
[_variables],
);

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 FeelEntry({
feel: 'optional',
isEdited: isFeelEntryEdited,
debounce,
element: field,
getValue,
id,
label: 'Message if condition not met',
setValue,
validate: messageEntryValidate,
variables,
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ function Description(props) {

const debounce = useService('debounce');

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

const path = ['description'];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ function ExpressionFieldExpression(props) {
const { editField, field, id } = props;

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

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ function Content(props) {

const debounce = useService('debounce');

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

const path = ['content'];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ function Url(props) {

const debounce = useService('debounce');

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

const path = ['url'];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function Source(props) {

const debounce = useService('debounce');

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

const path = ['source'];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ function Label(props) {

const debounce = useService('debounce');

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

const path = ['label'];

Expand Down Expand Up @@ -89,7 +89,7 @@ function DateLabel(props) {

const debounce = useService('debounce');

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

const path = DATE_LABEL_PATH;

Expand Down Expand Up @@ -118,7 +118,7 @@ function TimeLabel(props) {

const debounce = useService('debounce');

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

const path = TIME_LABEL_PATH;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ function OptionsExpression(props) {

const debounce = useService('debounce');

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

const path = OPTIONS_SOURCES_PATHS[OPTIONS_SOURCES.EXPRESSION];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ function Readonly(props) {

const debounce = useService('debounce');

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

const path = ['readonly'];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ function Source(props) {

const debounce = useService('debounce');

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

const path = ['dataSource'];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ function Text(props) {

const debounce = useService('debounce');

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

const path = ['text'];

Expand Down
Loading
Loading