Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Skaiir committed Apr 17, 2024
1 parent 5435dff commit 5e1e3fb
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export class PropertiesProvider {
SerializationGroup(field, editField),
ConstraintsGroup(field, editField),
ValidationGroup(field, editField),
CustomValidationsGroup(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
@@ -1,21 +1,12 @@
import {
get,
set
} from 'min-dash';
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 { editField, field, idPrefix, index } = props;

const entries = [
{
Expand All @@ -24,45 +15,39 @@ export function CustomValidationEntry(props) {
field,
id: idPrefix + '-condition',
idPrefix,
index
index,
},
{
component: Message,
editField,
field,
id: idPrefix + '-message',
idPrefix,
index
}
index,
},
];

return entries;
}

function Condition(props) {
const {
editField,
field,
id,
index
} = 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);
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' ]);
return get(field, ['validate', 'custom', index, 'condition']);
};

const conditionEntryValidate = useCallback((value) => {
Expand All @@ -79,17 +64,12 @@ function Condition(props) {
id,
label: 'Condition',
setValue,
validate: conditionEntryValidate
validate: conditionEntryValidate,
});
}

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

const debounce = useService('debounce');

Expand All @@ -98,14 +78,14 @@ function Message(props) {
return;
}

const validate = get(field, [ 'validate' ]);
const newValidate = set(validate, [ 'custom', index, 'message' ], value);
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' ]);
return get(field, ['validate', 'custom', index, 'message']);
};

const messageEntryValidate = useCallback((value) => {
Expand All @@ -121,6 +101,6 @@ function Message(props) {
id,
label: 'Message',
setValue,
validate: messageEntryValidate
validate: messageEntryValidate,
});
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
import {
get,
set,
without
} from 'min-dash';
import { get, set, without } from 'min-dash';

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

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

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

export function CustomValidationsGroup(field, editField) {
export function CustomValidationsGroup(field, editField, getService) {
const validate = get(field, ['validate'], {});
const { validatable, keyed } = getService('formFields').get(field.type).config;

const validate = get(field, [ 'validate' ], {});
const shouldRender = [ undefined, VALIDATION_TYPE_OPTIONS.custom.value ].includes(validate.validationType);
const isValidatable = validatable !== undefined ? validatable : keyed;
const isCustomValidation = [undefined, VALIDATION_TYPE_OPTIONS.custom.value].includes(validate.validationType);
const shouldRender = isValidatable && isCustomValidation;

if (!shouldRender) {
return;
Expand All @@ -26,44 +23,38 @@ export function CustomValidationsGroup(field, editField) {
id: 'custom-validation',
label: 'Custom Validations',
component: ListGroup,
...CustomValidationsEntry({ editField, field, id: 'custom-validation-list' })
...CustomValidationsEntry({ editField, field, id: 'custom-validation-list' }),
};
}


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

const addEntry = (e) => {

e.stopPropagation();

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

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

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

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

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

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

return {
Expand All @@ -72,15 +63,16 @@ export function CustomValidationsEntry(props) {
editField,
field,
idPrefix,
index
index,
}),
remove: () => removeEntry(entry)
label: 'Rule ' + (index + 1),
remove: () => removeEntry(entry),
};
});

return {
items,
add: addEntry,
shouldSort: false
shouldSort: false,
};
}
}
5 changes: 4 additions & 1 deletion packages/form-js-viewer/src/core/Validator.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,10 @@ export class Validator {
if ('custom' in evaluatedValidation && value && evaluatedValidation.custom.length) {
const { custom } = evaluatedValidation;
custom.forEach(({ condition, message }) => {
if (condition && !runExpressionEvaluation(this._expressionLanguage, value, expressionContextInfo)) {
if (
condition &&
!runExpressionEvaluation(this._expressionLanguage, condition, { ...expressionContextInfo, value })
) {
errors = [...errors, message];
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ ExpressionField.config = {
label: 'Expression',
group: 'basic-input',
keyed: true,
validatable: false,
emptyValue: null,
escapeGridRender: true,
create: (options = {}) => ({
Expand Down
10 changes: 5 additions & 5 deletions packages/form-js-viewer/src/util/expressions.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ export function buildExpressionContext(context) {
* If the string is not an expression, it is returned as is.
*
* @param {any} expressionLanguage - The expression language to use.
* @param {string} value - The string to evaluate.
* @param {string} expression - The string expression to evaluate.
* @param {Object} expressionContextInfo - The context information to use.
* @returns {any} - Evaluated value or the original value if not an expression.
*/
export function runExpressionEvaluation(expressionLanguage, value, expressionContextInfo) {
if (expressionLanguage && expressionLanguage.isExpression(value)) {
return expressionLanguage.evaluate(value, buildExpressionContext(expressionContextInfo));
export function runExpressionEvaluation(expressionLanguage, expression, expressionContextInfo) {
if (expressionLanguage && expressionLanguage.isExpression(expression)) {
return expressionLanguage.evaluate(expression, buildExpressionContext(expressionContextInfo));
}
return value;
return expression;
}

0 comments on commit 5e1e3fb

Please sign in to comment.