Skip to content

Commit

Permalink
fix: variable name changes when element name/label changes
Browse files Browse the repository at this point in the history
Closes #863
  • Loading branch information
abdul99ahad committed Aug 28, 2024
1 parent 959725f commit bf51fc5
Show file tree
Hide file tree
Showing 12 changed files with 290 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,18 @@ import DmnFactory from './DmnFactory';
import ElementFactory from './ElementFactory';
import IdChangeBehavior from
'dmn-js-shared/lib/features/modeling/behavior/IdChangeBehavior';
import NameChangeBehavior from
'dmn-js-shared/lib/features/modeling/behavior/NameChangeBehavior';
import Modeling from './Modeling';
import Behavior from './behavior';

export default {
__init__: [ 'dmnUpdater', 'idChangeBehavior', 'modeling' ],
__init__: [ 'dmnUpdater', 'idChangeBehavior', 'nameChangeBehavior', 'modeling' ],
__depends__: [ Behavior, CommandStack ],
dmnUpdater: [ 'type', DmnUpdater ],
dmnFactory: [ 'type', DmnFactory ],
elementFactory: [ 'type', ElementFactory ],
idChangeBehavior: [ 'type', IdChangeBehavior ],
nameChangeBehavior: [ 'type', NameChangeBehavior ],
modeling: [ 'type', Modeling ]
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { bootstrapModeler, inject } from 'test/helper';

import decisionTableXML from './name-change-behavior.dmn';

import CoreModule from 'src/core';
import Modeling from 'src/features/modeling';


describe('NameChangeBehavior', function() {

describe('with existing variable', function() {

beforeEach(bootstrapModeler(decisionTableXML, {
modules: [
CoreModule,
Modeling
],
}));


it('should update variable name when element name is changed', inject(
function(modeling, sheet) {

// given
const root = sheet.getRoot(),
decisionTable = root.businessObject;

const decision = decisionTable.$parent;

// when
modeling.editDecisionTableName('foo');

// then
const variable = decision.get('variable');

expect(variable.get('name')).to.equal('foo');
}
));
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="https://www.omg.org/spec/DMN/20191111/MODEL/" xmlns:dmndi="https://www.omg.org/spec/DMN/20191111/DMNDI/" xmlns:dc="http://www.omg.org/spec/DMN/20180521/DC/" xmlns:di="http://www.omg.org/spec/DMN/20180521/DI/" id="dish" name="Desired Dish" namespace="party" exporter="Camunda Modeler" exporterVersion="5.25.0">
<inputData id="InputData_0wikdil" name="Variable" />
<decision id="season" name="Season">
<variable id="InformationItem_var" name="Season" />
<informationRequirement id="InformationRequirement_13flr3u">
<requiredInput href="#InputData_0wikdil" />
</informationRequirement>
<decisionTable id="DecisionTable_0hzuy0u">
<input id="InputClause_1c1qe3j">
<inputExpression id="LiteralExpression_0qgvyx9" typeRef="string" />
</input>
<output id="OutputClause_1xvwwox" typeRef="string" />
</decisionTable>
</decision>
<dmndi:DMNDI>
<dmndi:DMNDiagram>
<dmndi:DMNShape id="DMNShape_1ds1jom" dmnElementRef="InputData_0wikdil">
<dc:Bounds height="45" width="125" x="138" y="198" />
</dmndi:DMNShape>
<dmndi:DMNEdge id="DMNEdge_0qwszuo" dmnElementRef="InformationRequirement_13flr3u">
<di:waypoint x="201" y="198" />
<di:waypoint x="200" y="155" />
<di:waypoint x="200" y="135" />
</dmndi:DMNEdge>
<dmndi:DMNShape id="DMNShape_0d8mpxr" dmnElementRef="season">
<dc:Bounds height="55" width="100" x="150" y="80" />
</dmndi:DMNShape>
</dmndi:DMNDiagram>
</dmndi:DMNDI>
</definitions>
5 changes: 4 additions & 1 deletion packages/dmn-js-drd/src/features/modeling/behavior/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,20 @@ import ReplaceConnectionBehavior from './ReplaceConnectionBehavior';
import ReplaceElementBehavior from './ReplaceElementBehavior';
import IdChangeBehavior from
'dmn-js-shared/lib/features/modeling/behavior/IdChangeBehavior';

import NameChangeBehavior from
'dmn-js-shared/lib/features/modeling/behavior/NameChangeBehavior';
export default {
__init__: [
'createConnectionBehavior',
'idChangeBehavior',
'nameChangeBehavior',
'layoutConnectionBehavior',
'replaceConnectionBehavior',
'replaceElementBehavior'
],
createConnectionBehavior: [ 'type', CreateConnectionBehavior ],
idChangeBehavior: [ 'type', IdChangeBehavior ],
nameChangeBehavior: [ 'type', NameChangeBehavior ],
layoutConnectionBehavior: [ 'type', LayoutConnectionBehavior ],
replaceConnectionBehavior: [ 'type', ReplaceConnectionBehavior ],
replaceElementBehavior: [ 'type', ReplaceElementBehavior ]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import {
forEach
} from 'min-dash';

import { getBusinessObject } from 'dmn-js-shared/lib/util/ModelUtil';

var NAME = 'name',
ID = 'id';

Expand Down Expand Up @@ -37,8 +39,8 @@ UpdatePropertiesHandler.$inject = [ 'elementRegistry', 'moddle' ];
*/
UpdatePropertiesHandler.prototype.execute = function(context) {

var element = context.element,
changed = [ element ];
const { element, properties } = context,
changed = [ element ];

if (!element) {
throw new Error('element required');
Expand All @@ -47,8 +49,7 @@ UpdatePropertiesHandler.prototype.execute = function(context) {
var elementRegistry = this._elementRegistry,
ids = this._moddle.ids;

var businessObject = element.businessObject,
properties = context.properties,
var businessObject = getBusinessObject(element),
oldProperties = (
context.oldProperties ||
getProperties(businessObject, keys(properties))
Expand Down
5 changes: 4 additions & 1 deletion packages/dmn-js-drd/src/features/replace/DrdReplace.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,11 @@ export default function DrdReplace(drdFactory, replace, selection, modeling) {
}

if (target.expression) {

// variable set to element name
var literalExpression = drdFactory.create('dmn:LiteralExpression'),
variable = drdFactory.create('dmn:InformationItem');
variable = drdFactory.create('dmn:InformationItem',
{ name: oldBusinessObject.name });

setBoxedExpression(newBusinessObject, literalExpression, drdFactory, variable);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { bootstrapModeler, inject } from 'test/helper';

import simpleStringEditXML from './name-change-behavior.dmn';

import CoreModule from 'src/core';
import Modeling from 'src/features/modeling';


describe('NameChangeBehavior', function() {

describe('with label change', function() {

beforeEach(bootstrapModeler(simpleStringEditXML, {
modules: [
CoreModule,
Modeling
],
}));


it('should update variable name when label is changed', inject(
function(modeling, elementRegistry) {

// given
const decision = elementRegistry.get('season'),
bo = decision.businessObject,
variable = bo.variable;

// when
modeling.updateLabel(decision,'foo');

// then
expect(variable.get('name')).to.equal('foo');
}
));
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="https://www.omg.org/spec/DMN/20191111/MODEL/" xmlns:dmndi="https://www.omg.org/spec/DMN/20191111/DMNDI/" xmlns:dc="http://www.omg.org/spec/DMN/20180521/DC/" xmlns:di="http://www.omg.org/spec/DMN/20180521/DI/" id="dish" name="Desired Dish" namespace="party" exporter="Camunda Modeler" exporterVersion="5.11.0">
<decision id="season" name="Season">
<variable id="InformationItem_16229yj" name="season" typeRef="string" />
<informationRequirement id="InformationRequirement_13flr3u">
<requiredInput href="#InputData_0wikdil" />
</informationRequirement>
<literalExpression id="LiteralExpression_0hs8xyn">
<text>calendar.getSeason(date)</text>
</literalExpression>
</decision>
<inputData id="InputData_0wikdil" name="Variable" />
<dmndi:DMNDI>
<dmndi:DMNDiagram>
<dmndi:DMNShape dmnElementRef="season">
<dc:Bounds height="55" width="100" x="150" y="80" />
</dmndi:DMNShape>
<dmndi:DMNShape id="DMNShape_1ds1jom" dmnElementRef="InputData_0wikdil">
<dc:Bounds height="45" width="125" x="138" y="198" />
</dmndi:DMNShape>
<dmndi:DMNEdge id="DMNEdge_0qwszuo" dmnElementRef="InformationRequirement_13flr3u">
<di:waypoint x="201" y="198" />
<di:waypoint x="200" y="155" />
<di:waypoint x="200" y="135" />
</dmndi:DMNEdge>
</dmndi:DMNDiagram>
</dmndi:DMNDI>
</definitions>
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,15 @@ export default class Modeling {

this._commandStack.execute('element.updateProperties', context);
}

updateProperties(el, props) {
const context = {
element: el,
properties: props
};

this._commandStack.execute('element.updateProperties', context);
}
}

Modeling.$inject = [ 'commandStack', 'viewer', 'eventBus' ];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import CommandStack from 'diagram-js/lib/command/CommandStack';
import IdChangeBehavior from
'dmn-js-shared/lib/features/modeling/behavior/IdChangeBehavior';

import NameChangeBehavior from
'dmn-js-shared/lib/features/modeling/behavior/NameChangeBehavior';
import Modeling from './Modeling';

export default {
__init__: [ 'idChangeBehavior', 'modeling' ],
__init__: [ 'idChangeBehavior', 'nameChangeBehavior', 'modeling' ],
commandStack: [ 'type', CommandStack ],
idChangeBehavior: [ 'type', IdChangeBehavior ],
nameChangeBehavior: [ 'type', NameChangeBehavior ],
modeling: [ 'type', Modeling ]
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { bootstrapModeler, inject } from 'test/helper';

import simpleStringEditXML from '../../../literal-expression.dmn';

import CoreModule from 'src/core';
import Modeling from 'src/features/modeling';


describe('NameChangeBehavior', function() {

describe('with existing variable', function() {

beforeEach(bootstrapModeler(simpleStringEditXML, {
modules: [
CoreModule,
Modeling
],
}));


it('should update variable name when element name is changed', inject(
function(modeling, viewer) {

// given
const decision = viewer.getDecision();

// when
modeling.editDecisionName('foo');

// then
const variable = decision.get('variable');

expect(variable.get('name')).to.equal('foo');
}
));
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor';

import {
getBusinessObject,
is
} from 'dmn-js-shared/lib/util/ModelUtil';


export default class NameChangeBehavior extends CommandInterceptor {

static $inject = [ 'eventBus', 'modeling' ];

constructor(eventBus, modeling) {
super(eventBus);

this._modeling = modeling;

this.postExecuted('element.updateProperties', this.updateVariableFromElement);
this.postExecuted('element.updateLabel', this.updateVariableFromLabel);
}

updateVariableFromLabel = ({ context }) => {
const { element, newLabel } = context;
const bo = getBusinessObject(element),
variable = bo.variable;

if (!variable) {
return;
}

this._modeling.updateProperties(variable, { name: newLabel });
};

updateVariableFromElement = ({ context }) => {
const { element, properties } = context;
const bo = getBusinessObject(element);

if (!bo.variable) {
return;
}

if (!(is(element, 'dmn:Decision') || is(element, 'dmn:BusinessKnowledgeModel'))) {
return;
}

if (!this.isNameChanged(properties)) {
return;
}

if (this.isVariable(element)) {
return;
}

else if (!this.isElementVariable(element)) {
this.syncElementVariableChange(bo);
}
};

isNameChanged(properties) {
return 'name' in properties;
}

isVariable(element) {
const parent = getParent(element);
return (
is(element, 'dmn:InformationItem') &&
parent && parent.get('variable') === element
);
}

isElementVariable(element) {
const variable = element.get('variable');
return variable && (element.name === variable.name);
}

syncElementVariableChange(businessObject) {
const name = businessObject.get('name');
const variable = businessObject.variable;
this._modeling.updateProperties(variable, { name });
}
}

// helpers //////////////////////

function getParent(element) {
return element.$parent;
}

0 comments on commit bf51fc5

Please sign in to comment.