sequential-workflow-designer 0.20.0 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -101,10 +101,10 @@ Add the below code to your head section in HTML document.
101
101
  ```html
102
102
  <head>
103
103
  ...
104
- <link href="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.20.0/css/designer.css" rel="stylesheet">
105
- <link href="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.20.0/css/designer-light.css" rel="stylesheet">
106
- <link href="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.20.0/css/designer-dark.css" rel="stylesheet">
107
- <script src="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.20.0/dist/index.umd.js"></script>
104
+ <link href="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.21.0/css/designer.css" rel="stylesheet">
105
+ <link href="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.21.0/css/designer-light.css" rel="stylesheet">
106
+ <link href="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.21.0/css/designer-dark.css" rel="stylesheet">
107
+ <script src="https://cdn.jsdelivr.net/npm/sequential-workflow-designer@0.21.0/dist/index.umd.js"></script>
108
108
  ```
109
109
 
110
110
  Call the designer by:
package/dist/index.umd.js CHANGED
@@ -760,7 +760,7 @@
760
760
  class Badges {
761
761
  static createForStep(stepContext, view, componentContext) {
762
762
  const g = createG(view.g);
763
- const badges = componentContext.services.badges.map(ext => ext.createForStep(g, stepContext, componentContext));
763
+ const badges = componentContext.services.badges.map(ext => ext.createForStep(g, view, stepContext, componentContext));
764
764
  const position = new Vector(view.width, 0);
765
765
  return new Badges(g, position, badges);
766
766
  }
@@ -834,7 +834,7 @@
834
834
  class StepComponent {
835
835
  static create(view, stepContext, componentContext) {
836
836
  const badges = Badges.createForStep(stepContext, view, componentContext);
837
- return new StepComponent(view, stepContext.step, stepContext.parentSequence, view.hasOutput(), badges);
837
+ return new StepComponent(view, stepContext.step, stepContext.parentSequence, view.hasOutput, badges);
838
838
  }
839
839
  constructor(view, step, parentSequence, hasOutput, badges) {
840
840
  this.view = view;
@@ -920,7 +920,9 @@
920
920
 
921
921
  class StepComponentViewContextFactory {
922
922
  static create(stepContext, componentContext) {
923
+ const preferenceKeyPrefix = stepContext.step.id + ':';
923
924
  return {
925
+ i18n: componentContext.i18n,
924
926
  getStepIconUrl: () => componentContext.iconProvider.getIconUrl(stepContext.step),
925
927
  getStepName: () => componentContext.i18n(`step.${stepContext.step.type}.name`, stepContext.step.name),
926
928
  createSequenceComponent: (parentElement, sequence) => {
@@ -932,8 +934,12 @@
932
934
  };
933
935
  return componentContext.services.sequenceComponent.create(parentElement, sequenceContext, componentContext);
934
936
  },
937
+ createRegionComponentView(parentElement, componentClassName, contentFactory) {
938
+ return componentContext.services.regionComponentView.create(parentElement, componentClassName, stepContext, this, contentFactory);
939
+ },
935
940
  createPlaceholderForArea: componentContext.services.placeholder.createForArea.bind(componentContext.services.placeholder),
936
- i18n: componentContext.i18n
941
+ getPreference: (key) => componentContext.preferenceStorage.getItem(preferenceKeyPrefix + key),
942
+ setPreference: (key, value) => componentContext.preferenceStorage.setItem(preferenceKeyPrefix + key, value)
937
943
  };
938
944
  }
939
945
  }
@@ -952,20 +958,22 @@
952
958
  }
953
959
 
954
960
  class ComponentContext {
955
- static create(stepsConfiguration, validatorConfiguration, state, stepExtensionResolver, i18n, services) {
956
- const validator = new DefinitionValidator(validatorConfiguration, state);
957
- const iconProvider = new IconProvider(stepsConfiguration);
961
+ static create(configuration, state, stepExtensionResolver, definitionWalker, preferenceStorage, i18n, services) {
962
+ const validator = new DefinitionValidator(configuration.validator, state);
963
+ const iconProvider = new IconProvider(configuration.steps);
958
964
  const placeholderController = services.placeholderController.create();
959
965
  const stepComponentFactory = new StepComponentFactory(stepExtensionResolver);
960
- return new ComponentContext(validator, iconProvider, placeholderController, stepComponentFactory, i18n, services);
966
+ return new ComponentContext(validator, iconProvider, placeholderController, stepComponentFactory, definitionWalker, services, preferenceStorage, i18n);
961
967
  }
962
- constructor(validator, iconProvider, placeholderController, stepComponentFactory, i18n, services) {
968
+ constructor(validator, iconProvider, placeholderController, stepComponentFactory, definitionWalker, services, preferenceStorage, i18n) {
963
969
  this.validator = validator;
964
970
  this.iconProvider = iconProvider;
965
971
  this.placeholderController = placeholderController;
966
972
  this.stepComponentFactory = stepComponentFactory;
967
- this.i18n = i18n;
973
+ this.definitionWalker = definitionWalker;
968
974
  this.services = services;
975
+ this.preferenceStorage = preferenceStorage;
976
+ this.i18n = i18n;
969
977
  }
970
978
  }
971
979
 
@@ -1090,13 +1098,41 @@
1090
1098
  }
1091
1099
  }
1092
1100
 
1101
+ class ValidatorFactory {
1102
+ static createForStep(stepContext, view, componentContext) {
1103
+ return () => {
1104
+ if (!componentContext.validator.validateStep(stepContext.step, stepContext.parentSequence)) {
1105
+ return false;
1106
+ }
1107
+ if (view.haveCollapsedChildren) {
1108
+ let allChildrenValid = true;
1109
+ componentContext.definitionWalker.forEachChildren(stepContext.step, (step, _, parentSequence) => {
1110
+ if (!componentContext.validator.validateStep(step, parentSequence)) {
1111
+ allChildrenValid = false;
1112
+ return false;
1113
+ }
1114
+ });
1115
+ if (!allChildrenValid) {
1116
+ return false;
1117
+ }
1118
+ }
1119
+ return true;
1120
+ };
1121
+ }
1122
+ static createForRoot(componentContext) {
1123
+ return () => {
1124
+ return componentContext.validator.validateRoot();
1125
+ };
1126
+ }
1127
+ }
1128
+
1093
1129
  class ValidationErrorBadge {
1094
- static createForStep(parentElement, stepContext, componentContext, configuration) {
1095
- const validator = () => componentContext.validator.validateStep(stepContext.step, stepContext.parentSequence);
1130
+ static createForStep(parentElement, view, stepContext, componentContext, configuration) {
1131
+ const validator = ValidatorFactory.createForStep(stepContext, view, componentContext);
1096
1132
  return new ValidationErrorBadge(parentElement, validator, configuration);
1097
1133
  }
1098
1134
  static createForRoot(parentElement, componentContext, configuration) {
1099
- const validator = () => componentContext.validator.validateRoot();
1135
+ const validator = ValidatorFactory.createForRoot(componentContext);
1100
1136
  return new ValidationErrorBadge(parentElement, validator, configuration);
1101
1137
  }
1102
1138
  constructor(parentElement, validator, configuration) {
@@ -1138,8 +1174,8 @@
1138
1174
  this.id = 'validationError';
1139
1175
  this.createStartValue = () => true;
1140
1176
  }
1141
- createForStep(parentElement, stepContext, componentContext) {
1142
- return ValidationErrorBadge.createForStep(parentElement, stepContext, componentContext, this.configuration.view);
1177
+ createForStep(parentElement, view, stepContext, componentContext) {
1178
+ return ValidationErrorBadge.createForStep(parentElement, view, stepContext, componentContext, this.configuration.view);
1143
1179
  }
1144
1180
  createForRoot(parentElement, componentContext) {
1145
1181
  return ValidationErrorBadge.createForRoot(parentElement, componentContext, this.configuration.view);
@@ -1313,53 +1349,6 @@
1313
1349
  }
1314
1350
  }
1315
1351
 
1316
- class RegionView {
1317
- static create(parent, widths, height) {
1318
- const totalWidth = widths.reduce((result, width) => result + width, 0);
1319
- const lines = [
1320
- drawLine(parent, 0, 0, totalWidth, 0),
1321
- drawLine(parent, 0, 0, 0, height),
1322
- drawLine(parent, 0, height, totalWidth, height),
1323
- drawLine(parent, totalWidth, 0, totalWidth, height)
1324
- ];
1325
- let offsetX = widths[0];
1326
- for (let i = 1; i < widths.length; i++) {
1327
- lines.push(drawLine(parent, offsetX, 0, offsetX, height));
1328
- offsetX += widths[i];
1329
- }
1330
- return new RegionView(lines, totalWidth, height);
1331
- }
1332
- constructor(lines, width, height) {
1333
- this.lines = lines;
1334
- this.width = width;
1335
- this.height = height;
1336
- }
1337
- getClientPosition() {
1338
- return getAbsolutePosition(this.lines[0]);
1339
- }
1340
- resolveClick(click) {
1341
- const regionPosition = this.getClientPosition();
1342
- const d = click.position.subtract(regionPosition);
1343
- return d.x >= 0 && d.y >= 0 && d.x < this.width * click.scale && d.y < this.height * click.scale;
1344
- }
1345
- setIsSelected(isSelected) {
1346
- this.lines.forEach(region => {
1347
- Dom.toggleClass(region, isSelected, 'sqd-selected');
1348
- });
1349
- }
1350
- }
1351
- function drawLine(parent, x1, y1, x2, y2) {
1352
- const line = Dom.svg('line', {
1353
- class: 'sqd-region',
1354
- x1,
1355
- y1,
1356
- x2,
1357
- y2
1358
- });
1359
- parent.insertBefore(line, parent.firstChild);
1360
- return line;
1361
- }
1362
-
1363
1352
  class DefaultSequenceComponentView {
1364
1353
  static create(parent, sequenceContext, componentContext) {
1365
1354
  const phWidth = componentContext.services.placeholder.gapSize.x;
@@ -1486,159 +1475,160 @@
1486
1475
  }
1487
1476
  }
1488
1477
 
1478
+ const COMPONENT_CLASS_NAME$2 = 'container';
1489
1479
  const createContainerStepComponentViewFactory = (cfg) => (parentElement, stepContext, viewContext) => {
1490
- const { step } = stepContext;
1491
- const g = ComponentDom.stepG('container', step.type, step.id);
1492
- parentElement.appendChild(g);
1493
- const name = viewContext.getStepName();
1494
- const labelView = LabelView.create(g, cfg.paddingTop, cfg.label, name, 'primary');
1495
- const sequenceComponent = viewContext.createSequenceComponent(g, step.sequence);
1496
- const halfOfWidestElement = labelView.width / 2;
1497
- const offsetLeft = Math.max(halfOfWidestElement - sequenceComponent.view.joinX, 0) + cfg.paddingX;
1498
- const offsetRight = Math.max(halfOfWidestElement - (sequenceComponent.view.width - sequenceComponent.view.joinX), 0) + cfg.paddingX;
1499
- const width = offsetLeft + sequenceComponent.view.width + offsetRight;
1500
- const height = cfg.paddingTop + cfg.label.height + sequenceComponent.view.height;
1501
- const joinX = sequenceComponent.view.joinX + offsetLeft;
1502
- Dom.translate(labelView.g, joinX, 0);
1503
- Dom.translate(sequenceComponent.view.g, offsetLeft, cfg.paddingTop + cfg.label.height);
1504
- const iconUrl = viewContext.getStepIconUrl();
1505
- const inputView = InputView.createRectInput(g, joinX, 0, cfg.inputSize, cfg.inputIconSize, iconUrl);
1506
- JoinView.createStraightJoin(g, new Vector(joinX, 0), cfg.paddingTop);
1507
- const regionView = RegionView.create(g, [width], height);
1508
- return {
1509
- g,
1510
- width,
1511
- height,
1512
- joinX,
1513
- placeholders: null,
1514
- sequenceComponents: [sequenceComponent],
1515
- getClientPosition() {
1516
- return regionView.getClientPosition();
1517
- },
1518
- resolveClick(click) {
1519
- return regionView.resolveClick(click) || g.contains(click.element) ? true : null;
1520
- },
1521
- setIsDragging(isDragging) {
1522
- inputView.setIsHidden(isDragging);
1523
- },
1524
- setIsSelected(isSelected) {
1525
- regionView.setIsSelected(isSelected);
1526
- },
1527
- setIsDisabled(isDisabled) {
1528
- Dom.toggleClass(g, isDisabled, 'sqd-disabled');
1529
- },
1530
- hasOutput() {
1531
- return sequenceComponent.hasOutput;
1532
- }
1533
- };
1480
+ return viewContext.createRegionComponentView(parentElement, COMPONENT_CLASS_NAME$2, (g, regionViewBuilder) => {
1481
+ const step = stepContext.step;
1482
+ const name = viewContext.getStepName();
1483
+ const labelView = LabelView.create(g, cfg.paddingTop, cfg.label, name, 'primary');
1484
+ const sequenceComponent = viewContext.createSequenceComponent(g, step.sequence);
1485
+ const halfOfWidestElement = labelView.width / 2;
1486
+ const offsetLeft = Math.max(halfOfWidestElement - sequenceComponent.view.joinX, 0) + cfg.paddingX;
1487
+ const offsetRight = Math.max(halfOfWidestElement - (sequenceComponent.view.width - sequenceComponent.view.joinX), 0) + cfg.paddingX;
1488
+ const width = offsetLeft + sequenceComponent.view.width + offsetRight;
1489
+ const height = cfg.paddingTop + cfg.label.height + sequenceComponent.view.height;
1490
+ const joinX = sequenceComponent.view.joinX + offsetLeft;
1491
+ Dom.translate(labelView.g, joinX, 0);
1492
+ Dom.translate(sequenceComponent.view.g, offsetLeft, cfg.paddingTop + cfg.label.height);
1493
+ const iconUrl = viewContext.getStepIconUrl();
1494
+ const inputView = InputView.createRectInput(g, joinX, 0, cfg.inputSize, cfg.inputIconSize, iconUrl);
1495
+ JoinView.createStraightJoin(g, new Vector(joinX, 0), cfg.paddingTop);
1496
+ const regionView = regionViewBuilder(g, [width], height);
1497
+ return {
1498
+ g,
1499
+ width,
1500
+ height,
1501
+ joinX,
1502
+ placeholders: null,
1503
+ sequenceComponents: [sequenceComponent],
1504
+ hasOutput: sequenceComponent.hasOutput,
1505
+ getClientPosition() {
1506
+ return regionView.getClientPosition();
1507
+ },
1508
+ resolveClick(click) {
1509
+ const result = regionView.resolveClick(click);
1510
+ return result === true || (result === null && g.contains(click.element)) ? true : result;
1511
+ },
1512
+ setIsDragging(isDragging) {
1513
+ inputView.setIsHidden(isDragging);
1514
+ },
1515
+ setIsSelected(isSelected) {
1516
+ regionView.setIsSelected(isSelected);
1517
+ },
1518
+ setIsDisabled(isDisabled) {
1519
+ Dom.toggleClass(g, isDisabled, 'sqd-disabled');
1520
+ }
1521
+ };
1522
+ });
1534
1523
  };
1535
1524
 
1525
+ const COMPONENT_CLASS_NAME$1 = 'switch';
1536
1526
  const createSwitchStepComponentViewFactory = (cfg) => (parent, stepContext, viewContext) => {
1537
- const { step } = stepContext;
1538
- const g = ComponentDom.stepG('switch', step.type, step.id);
1539
- parent.appendChild(g);
1540
- const branchNames = Object.keys(step.branches);
1541
- const branchComponents = branchNames.map(branchName => {
1542
- return viewContext.createSequenceComponent(g, step.branches[branchName]);
1543
- });
1544
- const branchLabelViews = branchNames.map(branchName => {
1545
- const labelY = cfg.paddingTop + cfg.nameLabel.height + cfg.connectionHeight;
1546
- const translatedBranchName = viewContext.i18n(`stepComponent.${step.type}.branchName`, branchName);
1547
- return LabelView.create(g, labelY, cfg.branchNameLabel, translatedBranchName, 'secondary');
1548
- });
1549
- const name = viewContext.getStepName();
1550
- const nameLabelView = LabelView.create(g, cfg.paddingTop, cfg.nameLabel, name, 'primary');
1551
- let prevOffsetX = 0;
1552
- const branchSizes = branchComponents.map((component, i) => {
1553
- const halfOfWidestBranchElement = Math.max(branchLabelViews[i].width, cfg.minContainerWidth) / 2;
1554
- const branchOffsetLeft = Math.max(halfOfWidestBranchElement - component.view.joinX, 0) + cfg.paddingX;
1555
- const branchOffsetRight = Math.max(halfOfWidestBranchElement - (component.view.width - component.view.joinX), 0) + cfg.paddingX;
1556
- const width = component.view.width + branchOffsetLeft + branchOffsetRight;
1557
- const joinX = component.view.joinX + branchOffsetLeft;
1558
- const offsetX = prevOffsetX;
1559
- prevOffsetX += width;
1560
- return { width, branchOffsetLeft, offsetX, joinX };
1561
- });
1562
- const centerBranchIndex = Math.floor(branchNames.length / 2);
1563
- const centerBranchSize = branchSizes[centerBranchIndex];
1564
- let joinX = centerBranchSize.offsetX;
1565
- if (branchNames.length % 2 !== 0) {
1566
- joinX += centerBranchSize.joinX;
1567
- }
1568
- const totalBranchesWidth = branchSizes.reduce((result, s) => result + s.width, 0);
1569
- const maxBranchesHeight = Math.max(...branchComponents.map(s => s.view.height));
1570
- const halfOfWidestSwitchElement = nameLabelView.width / 2 + cfg.paddingX;
1571
- const switchOffsetLeft = Math.max(halfOfWidestSwitchElement - joinX, 0);
1572
- const switchOffsetRight = Math.max(halfOfWidestSwitchElement - (totalBranchesWidth - joinX), 0);
1573
- const viewWidth = switchOffsetLeft + totalBranchesWidth + switchOffsetRight;
1574
- const viewHeight = maxBranchesHeight + cfg.paddingTop + cfg.nameLabel.height + cfg.branchNameLabel.height + cfg.connectionHeight * 2;
1575
- const shiftedJoinX = switchOffsetLeft + joinX;
1576
- Dom.translate(nameLabelView.g, shiftedJoinX, 0);
1577
- const branchOffsetTop = cfg.paddingTop + cfg.nameLabel.height + cfg.branchNameLabel.height + cfg.connectionHeight;
1578
- branchComponents.forEach((component, i) => {
1579
- const branchSize = branchSizes[i];
1580
- const branchOffsetLeft = switchOffsetLeft + branchSize.offsetX + branchSize.branchOffsetLeft;
1581
- Dom.translate(branchLabelViews[i].g, switchOffsetLeft + branchSize.offsetX + branchSize.joinX, 0);
1582
- Dom.translate(component.view.g, branchOffsetLeft, branchOffsetTop);
1583
- if (component.hasOutput && stepContext.isOutputConnected) {
1584
- const endOffsetTopOfComponent = cfg.paddingTop + cfg.nameLabel.height + cfg.branchNameLabel.height + cfg.connectionHeight + component.view.height;
1585
- const missingHeight = viewHeight - endOffsetTopOfComponent - cfg.connectionHeight;
1586
- if (missingHeight > 0) {
1587
- JoinView.createStraightJoin(g, new Vector(switchOffsetLeft + branchSize.offsetX + branchSize.joinX, endOffsetTopOfComponent), missingHeight);
1527
+ return viewContext.createRegionComponentView(parent, COMPONENT_CLASS_NAME$1, (g, regionViewBuilder) => {
1528
+ const step = stepContext.step;
1529
+ const branchNames = Object.keys(step.branches);
1530
+ const branchComponents = branchNames.map(branchName => {
1531
+ return viewContext.createSequenceComponent(g, step.branches[branchName]);
1532
+ });
1533
+ const branchLabelViews = branchNames.map(branchName => {
1534
+ const labelY = cfg.paddingTop + cfg.nameLabel.height + cfg.connectionHeight;
1535
+ const translatedBranchName = viewContext.i18n(`stepComponent.${step.type}.branchName`, branchName);
1536
+ return LabelView.create(g, labelY, cfg.branchNameLabel, translatedBranchName, 'secondary');
1537
+ });
1538
+ const name = viewContext.getStepName();
1539
+ const nameLabelView = LabelView.create(g, cfg.paddingTop, cfg.nameLabel, name, 'primary');
1540
+ let prevOffsetX = 0;
1541
+ const branchSizes = branchComponents.map((component, i) => {
1542
+ const halfOfWidestBranchElement = Math.max(branchLabelViews[i].width, cfg.minContainerWidth) / 2;
1543
+ const branchOffsetLeft = Math.max(halfOfWidestBranchElement - component.view.joinX, 0) + cfg.paddingX;
1544
+ const branchOffsetRight = Math.max(halfOfWidestBranchElement - (component.view.width - component.view.joinX), 0) + cfg.paddingX;
1545
+ const width = component.view.width + branchOffsetLeft + branchOffsetRight;
1546
+ const joinX = component.view.joinX + branchOffsetLeft;
1547
+ const offsetX = prevOffsetX;
1548
+ prevOffsetX += width;
1549
+ return { width, branchOffsetLeft, offsetX, joinX };
1550
+ });
1551
+ const centerBranchIndex = Math.floor(branchNames.length / 2);
1552
+ const centerBranchSize = branchSizes[centerBranchIndex];
1553
+ let joinX = centerBranchSize.offsetX;
1554
+ if (branchNames.length % 2 !== 0) {
1555
+ joinX += centerBranchSize.joinX;
1556
+ }
1557
+ const totalBranchesWidth = branchSizes.reduce((result, s) => result + s.width, 0);
1558
+ const maxBranchesHeight = Math.max(...branchComponents.map(s => s.view.height));
1559
+ const halfOfWidestSwitchElement = nameLabelView.width / 2 + cfg.paddingX;
1560
+ const switchOffsetLeft = Math.max(halfOfWidestSwitchElement - joinX, 0);
1561
+ const switchOffsetRight = Math.max(halfOfWidestSwitchElement - (totalBranchesWidth - joinX), 0);
1562
+ const viewWidth = switchOffsetLeft + totalBranchesWidth + switchOffsetRight;
1563
+ const viewHeight = maxBranchesHeight + cfg.paddingTop + cfg.nameLabel.height + cfg.branchNameLabel.height + cfg.connectionHeight * 2;
1564
+ const shiftedJoinX = switchOffsetLeft + joinX;
1565
+ Dom.translate(nameLabelView.g, shiftedJoinX, 0);
1566
+ const branchOffsetTop = cfg.paddingTop + cfg.nameLabel.height + cfg.branchNameLabel.height + cfg.connectionHeight;
1567
+ branchComponents.forEach((component, i) => {
1568
+ const branchSize = branchSizes[i];
1569
+ const branchOffsetLeft = switchOffsetLeft + branchSize.offsetX + branchSize.branchOffsetLeft;
1570
+ Dom.translate(branchLabelViews[i].g, switchOffsetLeft + branchSize.offsetX + branchSize.joinX, 0);
1571
+ Dom.translate(component.view.g, branchOffsetLeft, branchOffsetTop);
1572
+ if (component.hasOutput && stepContext.isOutputConnected) {
1573
+ const endOffsetTopOfComponent = cfg.paddingTop + cfg.nameLabel.height + cfg.branchNameLabel.height + cfg.connectionHeight + component.view.height;
1574
+ const missingHeight = viewHeight - endOffsetTopOfComponent - cfg.connectionHeight;
1575
+ if (missingHeight > 0) {
1576
+ JoinView.createStraightJoin(g, new Vector(switchOffsetLeft + branchSize.offsetX + branchSize.joinX, endOffsetTopOfComponent), missingHeight);
1577
+ }
1578
+ }
1579
+ });
1580
+ let inputView = null;
1581
+ if (cfg.inputSize > 0) {
1582
+ const iconUrl = viewContext.getStepIconUrl();
1583
+ inputView = InputView.createRectInput(g, shiftedJoinX, 0, cfg.inputSize, cfg.inputIconSize, iconUrl);
1584
+ }
1585
+ JoinView.createStraightJoin(g, new Vector(shiftedJoinX, 0), cfg.paddingTop);
1586
+ JoinView.createJoins(g, new Vector(shiftedJoinX, cfg.paddingTop + cfg.nameLabel.height), branchSizes.map(o => new Vector(switchOffsetLeft + o.offsetX + o.joinX, cfg.paddingTop + cfg.nameLabel.height + cfg.connectionHeight)));
1587
+ if (stepContext.isOutputConnected) {
1588
+ const ongoingSequenceIndexes = branchComponents
1589
+ .map((component, index) => (component.hasOutput ? index : null))
1590
+ .filter(index => index !== null);
1591
+ const ongoingJoinTargets = ongoingSequenceIndexes.map((i) => new Vector(switchOffsetLeft + branchSizes[i].offsetX + branchSizes[i].joinX, cfg.paddingTop + cfg.connectionHeight + cfg.nameLabel.height + cfg.branchNameLabel.height + maxBranchesHeight));
1592
+ if (ongoingJoinTargets.length > 0) {
1593
+ JoinView.createJoins(g, new Vector(shiftedJoinX, viewHeight), ongoingJoinTargets);
1588
1594
  }
1589
1595
  }
1596
+ const regions = branchSizes.map(s => s.width);
1597
+ regions[0] += switchOffsetLeft;
1598
+ regions[regions.length - 1] += switchOffsetRight;
1599
+ const regionView = regionViewBuilder(g, regions, viewHeight);
1600
+ return {
1601
+ g,
1602
+ width: viewWidth,
1603
+ height: viewHeight,
1604
+ joinX: shiftedJoinX,
1605
+ placeholders: null,
1606
+ sequenceComponents: branchComponents,
1607
+ hasOutput: branchComponents.some(c => c.hasOutput),
1608
+ getClientPosition() {
1609
+ return regionView.getClientPosition();
1610
+ },
1611
+ resolveClick(click) {
1612
+ const result = regionView.resolveClick(click);
1613
+ return result === true || (result === null && g.contains(click.element)) ? true : result;
1614
+ },
1615
+ setIsDragging(isDragging) {
1616
+ inputView === null || inputView === void 0 ? void 0 : inputView.setIsHidden(isDragging);
1617
+ },
1618
+ setIsSelected(isSelected) {
1619
+ regionView.setIsSelected(isSelected);
1620
+ },
1621
+ setIsDisabled(isDisabled) {
1622
+ Dom.toggleClass(g, isDisabled, 'sqd-disabled');
1623
+ }
1624
+ };
1590
1625
  });
1591
- let inputView = null;
1592
- if (cfg.inputSize > 0) {
1593
- const iconUrl = viewContext.getStepIconUrl();
1594
- inputView = InputView.createRectInput(g, shiftedJoinX, 0, cfg.inputSize, cfg.inputIconSize, iconUrl);
1595
- }
1596
- JoinView.createStraightJoin(g, new Vector(shiftedJoinX, 0), cfg.paddingTop);
1597
- JoinView.createJoins(g, new Vector(shiftedJoinX, cfg.paddingTop + cfg.nameLabel.height), branchSizes.map(o => new Vector(switchOffsetLeft + o.offsetX + o.joinX, cfg.paddingTop + cfg.nameLabel.height + cfg.connectionHeight)));
1598
- if (stepContext.isOutputConnected) {
1599
- const ongoingSequenceIndexes = branchComponents
1600
- .map((component, index) => (component.hasOutput ? index : null))
1601
- .filter(index => index !== null);
1602
- const ongoingJoinTargets = ongoingSequenceIndexes.map((i) => new Vector(switchOffsetLeft + branchSizes[i].offsetX + branchSizes[i].joinX, cfg.paddingTop + cfg.connectionHeight + cfg.nameLabel.height + cfg.branchNameLabel.height + maxBranchesHeight));
1603
- if (ongoingJoinTargets.length > 0) {
1604
- JoinView.createJoins(g, new Vector(shiftedJoinX, viewHeight), ongoingJoinTargets);
1605
- }
1606
- }
1607
- const regions = branchSizes.map(s => s.width);
1608
- regions[0] += switchOffsetLeft;
1609
- regions[regions.length - 1] += switchOffsetRight;
1610
- const regionView = RegionView.create(g, regions, viewHeight);
1611
- return {
1612
- g,
1613
- width: viewWidth,
1614
- height: viewHeight,
1615
- joinX: shiftedJoinX,
1616
- placeholders: null,
1617
- sequenceComponents: branchComponents,
1618
- getClientPosition() {
1619
- return regionView.getClientPosition();
1620
- },
1621
- resolveClick(click) {
1622
- return regionView.resolveClick(click) || g.contains(click.element) ? true : null;
1623
- },
1624
- setIsDragging(isDragging) {
1625
- inputView === null || inputView === void 0 ? void 0 : inputView.setIsHidden(isDragging);
1626
- },
1627
- setIsSelected(isSelected) {
1628
- regionView.setIsSelected(isSelected);
1629
- },
1630
- setIsDisabled(isDisabled) {
1631
- Dom.toggleClass(g, isDisabled, 'sqd-disabled');
1632
- },
1633
- hasOutput() {
1634
- return branchComponents.some(c => c.hasOutput);
1635
- }
1636
- };
1637
1626
  };
1638
1627
 
1628
+ const COMPONENT_CLASS_NAME = 'task';
1639
1629
  const createTaskStepComponentViewFactory = (isInterrupted, cfg) => (parentElement, stepContext, viewContext) => {
1640
1630
  const { step } = stepContext;
1641
- const g = ComponentDom.stepG('task', step.type, step.id);
1631
+ const g = ComponentDom.stepG(COMPONENT_CLASS_NAME, step.type, step.id);
1642
1632
  parentElement.appendChild(g);
1643
1633
  const boxHeight = cfg.paddingY * 2 + cfg.iconSize;
1644
1634
  const text = Dom.svg('text', {
@@ -1688,9 +1678,7 @@
1688
1678
  joinX: boxWidth / 2,
1689
1679
  sequenceComponents: null,
1690
1680
  placeholders: null,
1691
- hasOutput() {
1692
- return !!outputView;
1693
- },
1681
+ hasOutput: !!outputView,
1694
1682
  getClientPosition() {
1695
1683
  return getAbsolutePosition(rect);
1696
1684
  },
@@ -1979,6 +1967,64 @@
1979
1967
  }
1980
1968
  }
1981
1969
 
1970
+ class DefaultRegionView {
1971
+ static create(parent, widths, height) {
1972
+ const totalWidth = widths.reduce((result, width) => result + width, 0);
1973
+ const lines = [
1974
+ drawLine(parent, 0, 0, totalWidth, 0),
1975
+ drawLine(parent, 0, 0, 0, height),
1976
+ drawLine(parent, 0, height, totalWidth, height),
1977
+ drawLine(parent, totalWidth, 0, totalWidth, height)
1978
+ ];
1979
+ let offsetX = widths[0];
1980
+ for (let i = 1; i < widths.length; i++) {
1981
+ lines.push(drawLine(parent, offsetX, 0, offsetX, height));
1982
+ offsetX += widths[i];
1983
+ }
1984
+ return new DefaultRegionView(lines, totalWidth, height);
1985
+ }
1986
+ constructor(lines, width, height) {
1987
+ this.lines = lines;
1988
+ this.width = width;
1989
+ this.height = height;
1990
+ }
1991
+ getClientPosition() {
1992
+ return getAbsolutePosition(this.lines[0]);
1993
+ }
1994
+ resolveClick(click) {
1995
+ const regionPosition = this.getClientPosition();
1996
+ const d = click.position.subtract(regionPosition);
1997
+ if (d.x >= 0 && d.y >= 0 && d.x < this.width * click.scale && d.y < this.height * click.scale) {
1998
+ return true;
1999
+ }
2000
+ return null;
2001
+ }
2002
+ setIsSelected(isSelected) {
2003
+ this.lines.forEach(region => {
2004
+ Dom.toggleClass(region, isSelected, 'sqd-selected');
2005
+ });
2006
+ }
2007
+ }
2008
+ function drawLine(parent, x1, y1, x2, y2) {
2009
+ const line = Dom.svg('line', {
2010
+ class: 'sqd-region',
2011
+ x1,
2012
+ y1,
2013
+ x2,
2014
+ y2
2015
+ });
2016
+ parent.insertBefore(line, parent.firstChild);
2017
+ return line;
2018
+ }
2019
+
2020
+ class DefaultRegionComponentViewExtension {
2021
+ create(parentElement, componentClassName, stepContext, _, contentFactory) {
2022
+ const g = ComponentDom.stepG(componentClassName, stepContext.step.type, stepContext.step.id);
2023
+ parentElement.appendChild(g);
2024
+ return contentFactory(g, DefaultRegionView.create);
2025
+ }
2026
+ }
2027
+
1982
2028
  const defaultResolvers = [sequentialResolver, branchedResolver];
1983
2029
  function branchedResolver(step) {
1984
2030
  const branches = step.branches;
@@ -2663,9 +2709,22 @@
2663
2709
  }
2664
2710
  }
2665
2711
 
2712
+ class MemoryPreferenceStorage {
2713
+ constructor() {
2714
+ this.map = {};
2715
+ }
2716
+ setItem(key, value) {
2717
+ this.map[key] = value;
2718
+ }
2719
+ getItem(key) {
2720
+ var _a;
2721
+ return (_a = this.map[key]) !== null && _a !== void 0 ? _a : null;
2722
+ }
2723
+ }
2724
+
2666
2725
  class DesignerContext {
2667
2726
  static create(parent, startDefinition, configuration, services) {
2668
- var _a, _b, _c, _d;
2727
+ var _a, _b, _c, _d, _e;
2669
2728
  const definition = ObjectCloner.deepClone(startDefinition);
2670
2729
  const layoutController = new LayoutController(parent);
2671
2730
  const isReadonly = !!configuration.isReadonly;
@@ -2684,7 +2743,8 @@
2684
2743
  if (configuration.undoStackSize) {
2685
2744
  historyController = HistoryController.create(configuration.undoStack, state, stateModifier, configuration);
2686
2745
  }
2687
- const componentContext = ComponentContext.create(configuration.steps, configuration.validator, state, stepExtensionResolver, i18n, services);
2746
+ const preferenceStorage = (_e = configuration.preferenceStorage) !== null && _e !== void 0 ? _e : new MemoryPreferenceStorage();
2747
+ const componentContext = ComponentContext.create(configuration, state, stepExtensionResolver, definitionWalker, preferenceStorage, i18n, services);
2688
2748
  return new DesignerContext(theme, state, configuration, services, componentContext, definitionWalker, i18n, stateModifier, layoutController, workspaceController, behaviorController, customActionController, historyController);
2689
2749
  }
2690
2750
  constructor(theme, state, configuration, services, componentContext, definitionWalker, i18n, stateModifier, layoutController, workspaceController, behaviorController, customActionController, historyController) {
@@ -4110,7 +4170,7 @@
4110
4170
  }
4111
4171
 
4112
4172
  const defaultConfiguration$3 = {
4113
- gapWidth: 100,
4173
+ gapWidth: 88,
4114
4174
  gapHeight: 24,
4115
4175
  radius: 6,
4116
4176
  iconSize: 16
@@ -4379,6 +4439,9 @@
4379
4439
  if (ext.placeholder) {
4380
4440
  services.placeholder = ext.placeholder;
4381
4441
  }
4442
+ if (ext.regionComponentView) {
4443
+ services.regionComponentView = ext.regionComponentView;
4444
+ }
4382
4445
  if (ext.viewportController) {
4383
4446
  services.viewportController = ext.viewportController;
4384
4447
  }
@@ -4439,6 +4502,9 @@
4439
4502
  if (!services.placeholder) {
4440
4503
  services.placeholder = RectPlaceholderExtension.create();
4441
4504
  }
4505
+ if (!services.regionComponentView) {
4506
+ services.regionComponentView = new DefaultRegionComponentViewExtension();
4507
+ }
4442
4508
  if (!services.viewportController) {
4443
4509
  services.viewportController = new DefaultViewportControllerExtension();
4444
4510
  }
@@ -4724,6 +4790,8 @@
4724
4790
  exports.ComponentDom = ComponentDom;
4725
4791
  exports.ControlBarApi = ControlBarApi;
4726
4792
  exports.CustomActionController = CustomActionController;
4793
+ exports.DefaultRegionComponentViewExtension = DefaultRegionComponentViewExtension;
4794
+ exports.DefaultRegionView = DefaultRegionView;
4727
4795
  exports.DefaultSequenceComponent = DefaultSequenceComponent;
4728
4796
  exports.DefaultSequenceComponentView = DefaultSequenceComponentView;
4729
4797
  exports.DefaultViewportController = DefaultViewportController;
@@ -4747,7 +4815,6 @@
4747
4815
  exports.QuantifiedScaleViewportCalculator = QuantifiedScaleViewportCalculator;
4748
4816
  exports.RectPlaceholder = RectPlaceholder;
4749
4817
  exports.RectPlaceholderView = RectPlaceholderView;
4750
- exports.RegionView = RegionView;
4751
4818
  exports.ServicesResolver = ServicesResolver;
4752
4819
  exports.SimpleEvent = SimpleEvent;
4753
4820
  exports.StepComponent = StepComponent;