Skip to content

Commit

Permalink
fix(editor): add values source modeling behavior
Browse files Browse the repository at this point in the history
Closes #859
  • Loading branch information
Niklas Kiefer committed Nov 2, 2023
1 parent bfbcd58 commit 3be4ad3
Show file tree
Hide file tree
Showing 6 changed files with 237 additions and 32 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor';

import { get } from 'min-dash';

import {
VALUES_SOURCES,
VALUES_SOURCES_PATHS
} from '@bpmn-io/form-js-viewer';

export default class ValuesSourceBehavior extends CommandInterceptor {
constructor(eventBus) {
super(eventBus);

/**
* Cleanup properties on changing the values source.
*
* 1) Remove other sources, e.g. set `values` => remove `valuesKey` and `valuesExpression`
* 2) Remove default values for all other values sources
*/
this.preExecute('formField.edit', function(context) {
const { properties } = context;

const newProperties = {};

if (!isValuesSourceUpdate(properties)) {
return;
}

// clean up value sources that are not to going to be set
Object.values(VALUES_SOURCES).forEach(source => {
const path = VALUES_SOURCES_PATHS[source];
if (get(properties, path) == undefined) {
newProperties[VALUES_SOURCES_PATHS[source]] = undefined;
}
});

// clean up default value
if (
get(properties, VALUES_SOURCES_PATHS[VALUES_SOURCES.EXPRESSION]) !== undefined ||
get(properties, VALUES_SOURCES_PATHS[VALUES_SOURCES.INPUT]) !== undefined
) {
newProperties['defaultValue'] = undefined;
}

context.properties = {
...properties,
...newProperties
};
}, true);
}
}

ValuesSourceBehavior.$inject = [ 'eventBus' ];

// helper ///////////////////

function isValuesSourceUpdate(properties) {
return Object.values(VALUES_SOURCES_PATHS).some(path => {
return get(properties, path) !== undefined;
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,19 @@ import IdBehavior from './IdBehavior';
import KeyBehavior from './KeyBehavior';
import PathBehavior from './PathBehavior';
import ValidateBehavior from './ValidateBehavior';
import ValuesSourceBehavior from './ValuesSourceBehavior';

export default {
__init__: [
'idBehavior',
'keyBehavior',
'pathBehavior',
'validateBehavior'
'validateBehavior',
'valuesSourceBehavior'
],
idBehavior: [ 'type', IdBehavior ],
keyBehavior: [ 'type', KeyBehavior ],
pathBehavior: [ 'type', PathBehavior ],
validateBehavior: [ 'type', ValidateBehavior ]
validateBehavior: [ 'type', ValidateBehavior ],
valuesSourceBehavior: [ 'type', ValuesSourceBehavior ]
};
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,7 @@ function ValuesSourceSelect(props) {

const newProperties = {};

Object.values(VALUES_SOURCES).forEach(source => {

// Clear all values source definitions and default the newly selected one
const newValue = value === source ? VALUES_SOURCES_DEFAULTS[source] : undefined;
newProperties[VALUES_SOURCES_PATHS[source]] = newValue;
});
newProperties[VALUES_SOURCES_PATHS[value]] = VALUES_SOURCES_DEFAULTS[value];

newField = editField(field, newProperties);
return newField;
Expand Down
1 change: 1 addition & 0 deletions packages/form-js-editor/test/spec/defaultValues.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
]
},
{
"id": "language",
"defaultValue": "english",
"key": "language",
"label": "Language",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import {
bootstrapFormEditor,
inject
} from '../../../../TestHelper';

import modelingModule from 'src/features/modeling';

import schema from '../../../defaultValues.json';

describe('features/modeling - ValuesSourceBehavior', function() {

beforeEach(bootstrapFormEditor(schema, {
additionalModules: [
modelingModule
]
}));


it('should NOT remove values source properties', inject(function(formFieldRegistry, modeling) {

// given
const formField = formFieldRegistry.get('language');

// when
modeling.editFormField(
formField,
'label',
'foo'
);

// then
expect(formField.values).to.have.length(2);
}));


describe('should remove other values source properties', function() {

it('execute', inject(function(formFieldRegistry, modeling) {

// given
const formField = formFieldRegistry.get('language');

// when
modeling.editFormField(
formField,
'valuesKey',
''
);

// then
expect(formField.values).to.not.exist;
expect(formField.valuesExpression).to.not.exist;
}));


it('undo', inject(function(formFieldRegistry, modeling, commandStack) {

// given
const formField = formFieldRegistry.get('language');

// when
modeling.editFormField(
formField,
'valuesKey',
''
);

// when
commandStack.undo();

// then
expect(formField.values).to.have.length(2);
}));


it('redo', inject(function(formFieldRegistry, modeling, commandStack) {

// given
const formField = formFieldRegistry.get('language');

// when
modeling.editFormField(
formField,
'valuesKey',
''
);

// when
commandStack.undo();
commandStack.redo();

// then
expect(formField.values).to.not.exist;
expect(formField.valuesExpression).to.not.exist;
}));
});


describe('should remove default value', function() {

it('execute', inject(function(formFieldRegistry, modeling) {

// given
const formField = formFieldRegistry.get('language');

// when
modeling.editFormField(
formField,
'valuesExpression',
'='
);

// then
expect(formField.defaultValue).to.not.exist;
}));


it('undo', inject(function(formFieldRegistry, modeling, commandStack) {

// given
const formField = formFieldRegistry.get('language');

// when
modeling.editFormField(
formField,
'valuesExpression',
'='
);

// when
commandStack.undo();

// then
expect(formField.defaultValue).to.eql('english');
}));


it('redo', inject(function(formFieldRegistry, modeling, commandStack) {

// given
const formField = formFieldRegistry.get('language');

// when
modeling.editFormField(
formField,
'valuesExpression',
'='
);

// when
commandStack.undo();
commandStack.redo();

// then
expect(formField.defaultValue).to.not.exist;
}));
});

});
Original file line number Diff line number Diff line change
Expand Up @@ -773,17 +773,15 @@ describe('properties panel', function() {
// then
expect(editFieldSpy).to.have.been.calledTwice;
expect(editFieldSpy).to.have.been.calledWith(field, {
values: VALUES_SOURCES_DEFAULTS[VALUES_SOURCES.STATIC],
valuesKey: undefined,
valuesExpression: undefined
values: VALUES_SOURCES_DEFAULTS[VALUES_SOURCES.STATIC]
});
});
});


describe('dynamic options', function() {

it('should configure input source & cleanup static source', function() {
it('should configure input source', function() {

// given
const editFieldSpy = spy();
Expand All @@ -807,9 +805,7 @@ describe('properties panel', function() {
// then
expect(editFieldSpy).to.have.been.calledOnce;
expect(editFieldSpy).to.have.been.calledWith(field, {
values: undefined,
valuesKey: '',
valuesExpression: undefined
});
});

Expand Down Expand Up @@ -1123,7 +1119,7 @@ describe('properties panel', function() {

describe('dynamic options', function() {

it('should configure input source & cleanup static source', function() {
it('should configure input source', function() {

// given
const editFieldSpy = spy();
Expand All @@ -1147,9 +1143,7 @@ describe('properties panel', function() {
// then
expect(editFieldSpy).to.have.been.calledOnce;
expect(editFieldSpy).to.have.been.calledWith(field, {
values: undefined,
valuesKey: '',
valuesExpression: undefined
valuesKey: ''
});
});

Expand Down Expand Up @@ -1395,7 +1389,7 @@ describe('properties panel', function() {

describe('dynamic options (valuesKey)', function() {

it('should configure input source & cleanup static source', function() {
it('should configure input source', function() {

// given
const editFieldSpy = spy();
Expand All @@ -1419,9 +1413,7 @@ describe('properties panel', function() {
// then
expect(editFieldSpy).to.have.been.calledOnce;
expect(editFieldSpy).to.have.been.calledWith(field, {
values: undefined,
valuesKey: '',
valuesExpression: undefined
valuesKey: ''
});
});

Expand Down Expand Up @@ -1536,7 +1528,7 @@ describe('properties panel', function() {

describe('dynamic options (valuesExpression)', function() {

it('should configure input source & cleanup other sources', function() {
it('should configure input source', function() {

// given
const editFieldSpy = spy();
Expand All @@ -1560,8 +1552,6 @@ describe('properties panel', function() {
// then
expect(editFieldSpy).to.have.been.calledOnce;
expect(editFieldSpy).to.have.been.calledWith(field, {
values: undefined,
valuesKey: undefined,
valuesExpression: '='
});
});
Expand Down Expand Up @@ -2059,7 +2049,7 @@ describe('properties panel', function() {

describe('dynamic options (valuesKey)', function() {

it('should configure input source & cleanup static source', function() {
it('should configure input source', function() {

// given
const editFieldSpy = spy();
Expand All @@ -2083,9 +2073,7 @@ describe('properties panel', function() {
// then
expect(editFieldSpy).to.have.been.calledOnce;
expect(editFieldSpy).to.have.been.calledWith(field, {
values: undefined,
valuesKey: '',
valuesExpression: undefined
valuesKey: ''
});
});

Expand Down Expand Up @@ -2204,7 +2192,7 @@ describe('properties panel', function() {

describe('dynamic options (valuesExpression)', function() {

it('should configure input source & cleanup other sources', function() {
it('should configure input source', function() {

// given
const editFieldSpy = spy();
Expand All @@ -2228,8 +2216,6 @@ describe('properties panel', function() {
// then
expect(editFieldSpy).to.have.been.calledOnce;
expect(editFieldSpy).to.have.been.calledWith(field, {
values: undefined,
valuesKey: undefined,
valuesExpression: '='
});
});
Expand Down

0 comments on commit 3be4ad3

Please sign in to comment.