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/lib/cjs/index.cjs CHANGED
@@ -758,7 +758,7 @@ const BADGE_GAP = 4;
758
758
  class Badges {
759
759
  static createForStep(stepContext, view, componentContext) {
760
760
  const g = createG(view.g);
761
- const badges = componentContext.services.badges.map(ext => ext.createForStep(g, stepContext, componentContext));
761
+ const badges = componentContext.services.badges.map(ext => ext.createForStep(g, view, stepContext, componentContext));
762
762
  const position = new Vector(view.width, 0);
763
763
  return new Badges(g, position, badges);
764
764
  }
@@ -832,7 +832,7 @@ exports.PlaceholderDirection = void 0;
832
832
  class StepComponent {
833
833
  static create(view, stepContext, componentContext) {
834
834
  const badges = Badges.createForStep(stepContext, view, componentContext);
835
- return new StepComponent(view, stepContext.step, stepContext.parentSequence, view.hasOutput(), badges);
835
+ return new StepComponent(view, stepContext.step, stepContext.parentSequence, view.hasOutput, badges);
836
836
  }
837
837
  constructor(view, step, parentSequence, hasOutput, badges) {
838
838
  this.view = view;
@@ -918,7 +918,9 @@ class StepComponent {
918
918
 
919
919
  class StepComponentViewContextFactory {
920
920
  static create(stepContext, componentContext) {
921
+ const preferenceKeyPrefix = stepContext.step.id + ':';
921
922
  return {
923
+ i18n: componentContext.i18n,
922
924
  getStepIconUrl: () => componentContext.iconProvider.getIconUrl(stepContext.step),
923
925
  getStepName: () => componentContext.i18n(`step.${stepContext.step.type}.name`, stepContext.step.name),
924
926
  createSequenceComponent: (parentElement, sequence) => {
@@ -930,8 +932,12 @@ class StepComponentViewContextFactory {
930
932
  };
931
933
  return componentContext.services.sequenceComponent.create(parentElement, sequenceContext, componentContext);
932
934
  },
935
+ createRegionComponentView(parentElement, componentClassName, contentFactory) {
936
+ return componentContext.services.regionComponentView.create(parentElement, componentClassName, stepContext, this, contentFactory);
937
+ },
933
938
  createPlaceholderForArea: componentContext.services.placeholder.createForArea.bind(componentContext.services.placeholder),
934
- i18n: componentContext.i18n
939
+ getPreference: (key) => componentContext.preferenceStorage.getItem(preferenceKeyPrefix + key),
940
+ setPreference: (key, value) => componentContext.preferenceStorage.setItem(preferenceKeyPrefix + key, value)
935
941
  };
936
942
  }
937
943
  }
@@ -950,20 +956,22 @@ class StepComponentFactory {
950
956
  }
951
957
 
952
958
  class ComponentContext {
953
- static create(stepsConfiguration, validatorConfiguration, state, stepExtensionResolver, i18n, services) {
954
- const validator = new DefinitionValidator(validatorConfiguration, state);
955
- const iconProvider = new IconProvider(stepsConfiguration);
959
+ static create(configuration, state, stepExtensionResolver, definitionWalker, preferenceStorage, i18n, services) {
960
+ const validator = new DefinitionValidator(configuration.validator, state);
961
+ const iconProvider = new IconProvider(configuration.steps);
956
962
  const placeholderController = services.placeholderController.create();
957
963
  const stepComponentFactory = new StepComponentFactory(stepExtensionResolver);
958
- return new ComponentContext(validator, iconProvider, placeholderController, stepComponentFactory, i18n, services);
964
+ return new ComponentContext(validator, iconProvider, placeholderController, stepComponentFactory, definitionWalker, services, preferenceStorage, i18n);
959
965
  }
960
- constructor(validator, iconProvider, placeholderController, stepComponentFactory, i18n, services) {
966
+ constructor(validator, iconProvider, placeholderController, stepComponentFactory, definitionWalker, services, preferenceStorage, i18n) {
961
967
  this.validator = validator;
962
968
  this.iconProvider = iconProvider;
963
969
  this.placeholderController = placeholderController;
964
970
  this.stepComponentFactory = stepComponentFactory;
965
- this.i18n = i18n;
971
+ this.definitionWalker = definitionWalker;
966
972
  this.services = services;
973
+ this.preferenceStorage = preferenceStorage;
974
+ this.i18n = i18n;
967
975
  }
968
976
  }
969
977
 
@@ -1088,13 +1096,41 @@ class ValidationErrorBadgeView {
1088
1096
  }
1089
1097
  }
1090
1098
 
1099
+ class ValidatorFactory {
1100
+ static createForStep(stepContext, view, componentContext) {
1101
+ return () => {
1102
+ if (!componentContext.validator.validateStep(stepContext.step, stepContext.parentSequence)) {
1103
+ return false;
1104
+ }
1105
+ if (view.haveCollapsedChildren) {
1106
+ let allChildrenValid = true;
1107
+ componentContext.definitionWalker.forEachChildren(stepContext.step, (step, _, parentSequence) => {
1108
+ if (!componentContext.validator.validateStep(step, parentSequence)) {
1109
+ allChildrenValid = false;
1110
+ return false;
1111
+ }
1112
+ });
1113
+ if (!allChildrenValid) {
1114
+ return false;
1115
+ }
1116
+ }
1117
+ return true;
1118
+ };
1119
+ }
1120
+ static createForRoot(componentContext) {
1121
+ return () => {
1122
+ return componentContext.validator.validateRoot();
1123
+ };
1124
+ }
1125
+ }
1126
+
1091
1127
  class ValidationErrorBadge {
1092
- static createForStep(parentElement, stepContext, componentContext, configuration) {
1093
- const validator = () => componentContext.validator.validateStep(stepContext.step, stepContext.parentSequence);
1128
+ static createForStep(parentElement, view, stepContext, componentContext, configuration) {
1129
+ const validator = ValidatorFactory.createForStep(stepContext, view, componentContext);
1094
1130
  return new ValidationErrorBadge(parentElement, validator, configuration);
1095
1131
  }
1096
1132
  static createForRoot(parentElement, componentContext, configuration) {
1097
- const validator = () => componentContext.validator.validateRoot();
1133
+ const validator = ValidatorFactory.createForRoot(componentContext);
1098
1134
  return new ValidationErrorBadge(parentElement, validator, configuration);
1099
1135
  }
1100
1136
  constructor(parentElement, validator, configuration) {
@@ -1136,8 +1172,8 @@ class ValidationErrorBadgeExtension {
1136
1172
  this.id = 'validationError';
1137
1173
  this.createStartValue = () => true;
1138
1174
  }
1139
- createForStep(parentElement, stepContext, componentContext) {
1140
- return ValidationErrorBadge.createForStep(parentElement, stepContext, componentContext, this.configuration.view);
1175
+ createForStep(parentElement, view, stepContext, componentContext) {
1176
+ return ValidationErrorBadge.createForStep(parentElement, view, stepContext, componentContext, this.configuration.view);
1141
1177
  }
1142
1178
  createForRoot(parentElement, componentContext) {
1143
1179
  return ValidationErrorBadge.createForRoot(parentElement, componentContext, this.configuration.view);
@@ -1311,53 +1347,6 @@ class OutputView {
1311
1347
  }
1312
1348
  }
1313
1349
 
1314
- class RegionView {
1315
- static create(parent, widths, height) {
1316
- const totalWidth = widths.reduce((result, width) => result + width, 0);
1317
- const lines = [
1318
- drawLine(parent, 0, 0, totalWidth, 0),
1319
- drawLine(parent, 0, 0, 0, height),
1320
- drawLine(parent, 0, height, totalWidth, height),
1321
- drawLine(parent, totalWidth, 0, totalWidth, height)
1322
- ];
1323
- let offsetX = widths[0];
1324
- for (let i = 1; i < widths.length; i++) {
1325
- lines.push(drawLine(parent, offsetX, 0, offsetX, height));
1326
- offsetX += widths[i];
1327
- }
1328
- return new RegionView(lines, totalWidth, height);
1329
- }
1330
- constructor(lines, width, height) {
1331
- this.lines = lines;
1332
- this.width = width;
1333
- this.height = height;
1334
- }
1335
- getClientPosition() {
1336
- return getAbsolutePosition(this.lines[0]);
1337
- }
1338
- resolveClick(click) {
1339
- const regionPosition = this.getClientPosition();
1340
- const d = click.position.subtract(regionPosition);
1341
- return d.x >= 0 && d.y >= 0 && d.x < this.width * click.scale && d.y < this.height * click.scale;
1342
- }
1343
- setIsSelected(isSelected) {
1344
- this.lines.forEach(region => {
1345
- Dom.toggleClass(region, isSelected, 'sqd-selected');
1346
- });
1347
- }
1348
- }
1349
- function drawLine(parent, x1, y1, x2, y2) {
1350
- const line = Dom.svg('line', {
1351
- class: 'sqd-region',
1352
- x1,
1353
- y1,
1354
- x2,
1355
- y2
1356
- });
1357
- parent.insertBefore(line, parent.firstChild);
1358
- return line;
1359
- }
1360
-
1361
1350
  class DefaultSequenceComponentView {
1362
1351
  static create(parent, sequenceContext, componentContext) {
1363
1352
  const phWidth = componentContext.services.placeholder.gapSize.x;
@@ -1484,159 +1473,160 @@ class DefaultSequenceComponent {
1484
1473
  }
1485
1474
  }
1486
1475
 
1476
+ const COMPONENT_CLASS_NAME$2 = 'container';
1487
1477
  const createContainerStepComponentViewFactory = (cfg) => (parentElement, stepContext, viewContext) => {
1488
- const { step } = stepContext;
1489
- const g = ComponentDom.stepG('container', step.type, step.id);
1490
- parentElement.appendChild(g);
1491
- const name = viewContext.getStepName();
1492
- const labelView = LabelView.create(g, cfg.paddingTop, cfg.label, name, 'primary');
1493
- const sequenceComponent = viewContext.createSequenceComponent(g, step.sequence);
1494
- const halfOfWidestElement = labelView.width / 2;
1495
- const offsetLeft = Math.max(halfOfWidestElement - sequenceComponent.view.joinX, 0) + cfg.paddingX;
1496
- const offsetRight = Math.max(halfOfWidestElement - (sequenceComponent.view.width - sequenceComponent.view.joinX), 0) + cfg.paddingX;
1497
- const width = offsetLeft + sequenceComponent.view.width + offsetRight;
1498
- const height = cfg.paddingTop + cfg.label.height + sequenceComponent.view.height;
1499
- const joinX = sequenceComponent.view.joinX + offsetLeft;
1500
- Dom.translate(labelView.g, joinX, 0);
1501
- Dom.translate(sequenceComponent.view.g, offsetLeft, cfg.paddingTop + cfg.label.height);
1502
- const iconUrl = viewContext.getStepIconUrl();
1503
- const inputView = InputView.createRectInput(g, joinX, 0, cfg.inputSize, cfg.inputIconSize, iconUrl);
1504
- JoinView.createStraightJoin(g, new Vector(joinX, 0), cfg.paddingTop);
1505
- const regionView = RegionView.create(g, [width], height);
1506
- return {
1507
- g,
1508
- width,
1509
- height,
1510
- joinX,
1511
- placeholders: null,
1512
- sequenceComponents: [sequenceComponent],
1513
- getClientPosition() {
1514
- return regionView.getClientPosition();
1515
- },
1516
- resolveClick(click) {
1517
- return regionView.resolveClick(click) || g.contains(click.element) ? true : null;
1518
- },
1519
- setIsDragging(isDragging) {
1520
- inputView.setIsHidden(isDragging);
1521
- },
1522
- setIsSelected(isSelected) {
1523
- regionView.setIsSelected(isSelected);
1524
- },
1525
- setIsDisabled(isDisabled) {
1526
- Dom.toggleClass(g, isDisabled, 'sqd-disabled');
1527
- },
1528
- hasOutput() {
1529
- return sequenceComponent.hasOutput;
1530
- }
1531
- };
1478
+ return viewContext.createRegionComponentView(parentElement, COMPONENT_CLASS_NAME$2, (g, regionViewBuilder) => {
1479
+ const step = stepContext.step;
1480
+ const name = viewContext.getStepName();
1481
+ const labelView = LabelView.create(g, cfg.paddingTop, cfg.label, name, 'primary');
1482
+ const sequenceComponent = viewContext.createSequenceComponent(g, step.sequence);
1483
+ const halfOfWidestElement = labelView.width / 2;
1484
+ const offsetLeft = Math.max(halfOfWidestElement - sequenceComponent.view.joinX, 0) + cfg.paddingX;
1485
+ const offsetRight = Math.max(halfOfWidestElement - (sequenceComponent.view.width - sequenceComponent.view.joinX), 0) + cfg.paddingX;
1486
+ const width = offsetLeft + sequenceComponent.view.width + offsetRight;
1487
+ const height = cfg.paddingTop + cfg.label.height + sequenceComponent.view.height;
1488
+ const joinX = sequenceComponent.view.joinX + offsetLeft;
1489
+ Dom.translate(labelView.g, joinX, 0);
1490
+ Dom.translate(sequenceComponent.view.g, offsetLeft, cfg.paddingTop + cfg.label.height);
1491
+ const iconUrl = viewContext.getStepIconUrl();
1492
+ const inputView = InputView.createRectInput(g, joinX, 0, cfg.inputSize, cfg.inputIconSize, iconUrl);
1493
+ JoinView.createStraightJoin(g, new Vector(joinX, 0), cfg.paddingTop);
1494
+ const regionView = regionViewBuilder(g, [width], height);
1495
+ return {
1496
+ g,
1497
+ width,
1498
+ height,
1499
+ joinX,
1500
+ placeholders: null,
1501
+ sequenceComponents: [sequenceComponent],
1502
+ hasOutput: sequenceComponent.hasOutput,
1503
+ getClientPosition() {
1504
+ return regionView.getClientPosition();
1505
+ },
1506
+ resolveClick(click) {
1507
+ const result = regionView.resolveClick(click);
1508
+ return result === true || (result === null && g.contains(click.element)) ? true : result;
1509
+ },
1510
+ setIsDragging(isDragging) {
1511
+ inputView.setIsHidden(isDragging);
1512
+ },
1513
+ setIsSelected(isSelected) {
1514
+ regionView.setIsSelected(isSelected);
1515
+ },
1516
+ setIsDisabled(isDisabled) {
1517
+ Dom.toggleClass(g, isDisabled, 'sqd-disabled');
1518
+ }
1519
+ };
1520
+ });
1532
1521
  };
1533
1522
 
1523
+ const COMPONENT_CLASS_NAME$1 = 'switch';
1534
1524
  const createSwitchStepComponentViewFactory = (cfg) => (parent, stepContext, viewContext) => {
1535
- const { step } = stepContext;
1536
- const g = ComponentDom.stepG('switch', step.type, step.id);
1537
- parent.appendChild(g);
1538
- const branchNames = Object.keys(step.branches);
1539
- const branchComponents = branchNames.map(branchName => {
1540
- return viewContext.createSequenceComponent(g, step.branches[branchName]);
1541
- });
1542
- const branchLabelViews = branchNames.map(branchName => {
1543
- const labelY = cfg.paddingTop + cfg.nameLabel.height + cfg.connectionHeight;
1544
- const translatedBranchName = viewContext.i18n(`stepComponent.${step.type}.branchName`, branchName);
1545
- return LabelView.create(g, labelY, cfg.branchNameLabel, translatedBranchName, 'secondary');
1546
- });
1547
- const name = viewContext.getStepName();
1548
- const nameLabelView = LabelView.create(g, cfg.paddingTop, cfg.nameLabel, name, 'primary');
1549
- let prevOffsetX = 0;
1550
- const branchSizes = branchComponents.map((component, i) => {
1551
- const halfOfWidestBranchElement = Math.max(branchLabelViews[i].width, cfg.minContainerWidth) / 2;
1552
- const branchOffsetLeft = Math.max(halfOfWidestBranchElement - component.view.joinX, 0) + cfg.paddingX;
1553
- const branchOffsetRight = Math.max(halfOfWidestBranchElement - (component.view.width - component.view.joinX), 0) + cfg.paddingX;
1554
- const width = component.view.width + branchOffsetLeft + branchOffsetRight;
1555
- const joinX = component.view.joinX + branchOffsetLeft;
1556
- const offsetX = prevOffsetX;
1557
- prevOffsetX += width;
1558
- return { width, branchOffsetLeft, offsetX, joinX };
1559
- });
1560
- const centerBranchIndex = Math.floor(branchNames.length / 2);
1561
- const centerBranchSize = branchSizes[centerBranchIndex];
1562
- let joinX = centerBranchSize.offsetX;
1563
- if (branchNames.length % 2 !== 0) {
1564
- joinX += centerBranchSize.joinX;
1565
- }
1566
- const totalBranchesWidth = branchSizes.reduce((result, s) => result + s.width, 0);
1567
- const maxBranchesHeight = Math.max(...branchComponents.map(s => s.view.height));
1568
- const halfOfWidestSwitchElement = nameLabelView.width / 2 + cfg.paddingX;
1569
- const switchOffsetLeft = Math.max(halfOfWidestSwitchElement - joinX, 0);
1570
- const switchOffsetRight = Math.max(halfOfWidestSwitchElement - (totalBranchesWidth - joinX), 0);
1571
- const viewWidth = switchOffsetLeft + totalBranchesWidth + switchOffsetRight;
1572
- const viewHeight = maxBranchesHeight + cfg.paddingTop + cfg.nameLabel.height + cfg.branchNameLabel.height + cfg.connectionHeight * 2;
1573
- const shiftedJoinX = switchOffsetLeft + joinX;
1574
- Dom.translate(nameLabelView.g, shiftedJoinX, 0);
1575
- const branchOffsetTop = cfg.paddingTop + cfg.nameLabel.height + cfg.branchNameLabel.height + cfg.connectionHeight;
1576
- branchComponents.forEach((component, i) => {
1577
- const branchSize = branchSizes[i];
1578
- const branchOffsetLeft = switchOffsetLeft + branchSize.offsetX + branchSize.branchOffsetLeft;
1579
- Dom.translate(branchLabelViews[i].g, switchOffsetLeft + branchSize.offsetX + branchSize.joinX, 0);
1580
- Dom.translate(component.view.g, branchOffsetLeft, branchOffsetTop);
1581
- if (component.hasOutput && stepContext.isOutputConnected) {
1582
- const endOffsetTopOfComponent = cfg.paddingTop + cfg.nameLabel.height + cfg.branchNameLabel.height + cfg.connectionHeight + component.view.height;
1583
- const missingHeight = viewHeight - endOffsetTopOfComponent - cfg.connectionHeight;
1584
- if (missingHeight > 0) {
1585
- JoinView.createStraightJoin(g, new Vector(switchOffsetLeft + branchSize.offsetX + branchSize.joinX, endOffsetTopOfComponent), missingHeight);
1525
+ return viewContext.createRegionComponentView(parent, COMPONENT_CLASS_NAME$1, (g, regionViewBuilder) => {
1526
+ const step = stepContext.step;
1527
+ const branchNames = Object.keys(step.branches);
1528
+ const branchComponents = branchNames.map(branchName => {
1529
+ return viewContext.createSequenceComponent(g, step.branches[branchName]);
1530
+ });
1531
+ const branchLabelViews = branchNames.map(branchName => {
1532
+ const labelY = cfg.paddingTop + cfg.nameLabel.height + cfg.connectionHeight;
1533
+ const translatedBranchName = viewContext.i18n(`stepComponent.${step.type}.branchName`, branchName);
1534
+ return LabelView.create(g, labelY, cfg.branchNameLabel, translatedBranchName, 'secondary');
1535
+ });
1536
+ const name = viewContext.getStepName();
1537
+ const nameLabelView = LabelView.create(g, cfg.paddingTop, cfg.nameLabel, name, 'primary');
1538
+ let prevOffsetX = 0;
1539
+ const branchSizes = branchComponents.map((component, i) => {
1540
+ const halfOfWidestBranchElement = Math.max(branchLabelViews[i].width, cfg.minContainerWidth) / 2;
1541
+ const branchOffsetLeft = Math.max(halfOfWidestBranchElement - component.view.joinX, 0) + cfg.paddingX;
1542
+ const branchOffsetRight = Math.max(halfOfWidestBranchElement - (component.view.width - component.view.joinX), 0) + cfg.paddingX;
1543
+ const width = component.view.width + branchOffsetLeft + branchOffsetRight;
1544
+ const joinX = component.view.joinX + branchOffsetLeft;
1545
+ const offsetX = prevOffsetX;
1546
+ prevOffsetX += width;
1547
+ return { width, branchOffsetLeft, offsetX, joinX };
1548
+ });
1549
+ const centerBranchIndex = Math.floor(branchNames.length / 2);
1550
+ const centerBranchSize = branchSizes[centerBranchIndex];
1551
+ let joinX = centerBranchSize.offsetX;
1552
+ if (branchNames.length % 2 !== 0) {
1553
+ joinX += centerBranchSize.joinX;
1554
+ }
1555
+ const totalBranchesWidth = branchSizes.reduce((result, s) => result + s.width, 0);
1556
+ const maxBranchesHeight = Math.max(...branchComponents.map(s => s.view.height));
1557
+ const halfOfWidestSwitchElement = nameLabelView.width / 2 + cfg.paddingX;
1558
+ const switchOffsetLeft = Math.max(halfOfWidestSwitchElement - joinX, 0);
1559
+ const switchOffsetRight = Math.max(halfOfWidestSwitchElement - (totalBranchesWidth - joinX), 0);
1560
+ const viewWidth = switchOffsetLeft + totalBranchesWidth + switchOffsetRight;
1561
+ const viewHeight = maxBranchesHeight + cfg.paddingTop + cfg.nameLabel.height + cfg.branchNameLabel.height + cfg.connectionHeight * 2;
1562
+ const shiftedJoinX = switchOffsetLeft + joinX;
1563
+ Dom.translate(nameLabelView.g, shiftedJoinX, 0);
1564
+ const branchOffsetTop = cfg.paddingTop + cfg.nameLabel.height + cfg.branchNameLabel.height + cfg.connectionHeight;
1565
+ branchComponents.forEach((component, i) => {
1566
+ const branchSize = branchSizes[i];
1567
+ const branchOffsetLeft = switchOffsetLeft + branchSize.offsetX + branchSize.branchOffsetLeft;
1568
+ Dom.translate(branchLabelViews[i].g, switchOffsetLeft + branchSize.offsetX + branchSize.joinX, 0);
1569
+ Dom.translate(component.view.g, branchOffsetLeft, branchOffsetTop);
1570
+ if (component.hasOutput && stepContext.isOutputConnected) {
1571
+ const endOffsetTopOfComponent = cfg.paddingTop + cfg.nameLabel.height + cfg.branchNameLabel.height + cfg.connectionHeight + component.view.height;
1572
+ const missingHeight = viewHeight - endOffsetTopOfComponent - cfg.connectionHeight;
1573
+ if (missingHeight > 0) {
1574
+ JoinView.createStraightJoin(g, new Vector(switchOffsetLeft + branchSize.offsetX + branchSize.joinX, endOffsetTopOfComponent), missingHeight);
1575
+ }
1576
+ }
1577
+ });
1578
+ let inputView = null;
1579
+ if (cfg.inputSize > 0) {
1580
+ const iconUrl = viewContext.getStepIconUrl();
1581
+ inputView = InputView.createRectInput(g, shiftedJoinX, 0, cfg.inputSize, cfg.inputIconSize, iconUrl);
1582
+ }
1583
+ JoinView.createStraightJoin(g, new Vector(shiftedJoinX, 0), cfg.paddingTop);
1584
+ 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)));
1585
+ if (stepContext.isOutputConnected) {
1586
+ const ongoingSequenceIndexes = branchComponents
1587
+ .map((component, index) => (component.hasOutput ? index : null))
1588
+ .filter(index => index !== null);
1589
+ 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));
1590
+ if (ongoingJoinTargets.length > 0) {
1591
+ JoinView.createJoins(g, new Vector(shiftedJoinX, viewHeight), ongoingJoinTargets);
1586
1592
  }
1587
1593
  }
1594
+ const regions = branchSizes.map(s => s.width);
1595
+ regions[0] += switchOffsetLeft;
1596
+ regions[regions.length - 1] += switchOffsetRight;
1597
+ const regionView = regionViewBuilder(g, regions, viewHeight);
1598
+ return {
1599
+ g,
1600
+ width: viewWidth,
1601
+ height: viewHeight,
1602
+ joinX: shiftedJoinX,
1603
+ placeholders: null,
1604
+ sequenceComponents: branchComponents,
1605
+ hasOutput: branchComponents.some(c => c.hasOutput),
1606
+ getClientPosition() {
1607
+ return regionView.getClientPosition();
1608
+ },
1609
+ resolveClick(click) {
1610
+ const result = regionView.resolveClick(click);
1611
+ return result === true || (result === null && g.contains(click.element)) ? true : result;
1612
+ },
1613
+ setIsDragging(isDragging) {
1614
+ inputView === null || inputView === void 0 ? void 0 : inputView.setIsHidden(isDragging);
1615
+ },
1616
+ setIsSelected(isSelected) {
1617
+ regionView.setIsSelected(isSelected);
1618
+ },
1619
+ setIsDisabled(isDisabled) {
1620
+ Dom.toggleClass(g, isDisabled, 'sqd-disabled');
1621
+ }
1622
+ };
1588
1623
  });
1589
- let inputView = null;
1590
- if (cfg.inputSize > 0) {
1591
- const iconUrl = viewContext.getStepIconUrl();
1592
- inputView = InputView.createRectInput(g, shiftedJoinX, 0, cfg.inputSize, cfg.inputIconSize, iconUrl);
1593
- }
1594
- JoinView.createStraightJoin(g, new Vector(shiftedJoinX, 0), cfg.paddingTop);
1595
- 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)));
1596
- if (stepContext.isOutputConnected) {
1597
- const ongoingSequenceIndexes = branchComponents
1598
- .map((component, index) => (component.hasOutput ? index : null))
1599
- .filter(index => index !== null);
1600
- 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));
1601
- if (ongoingJoinTargets.length > 0) {
1602
- JoinView.createJoins(g, new Vector(shiftedJoinX, viewHeight), ongoingJoinTargets);
1603
- }
1604
- }
1605
- const regions = branchSizes.map(s => s.width);
1606
- regions[0] += switchOffsetLeft;
1607
- regions[regions.length - 1] += switchOffsetRight;
1608
- const regionView = RegionView.create(g, regions, viewHeight);
1609
- return {
1610
- g,
1611
- width: viewWidth,
1612
- height: viewHeight,
1613
- joinX: shiftedJoinX,
1614
- placeholders: null,
1615
- sequenceComponents: branchComponents,
1616
- getClientPosition() {
1617
- return regionView.getClientPosition();
1618
- },
1619
- resolveClick(click) {
1620
- return regionView.resolveClick(click) || g.contains(click.element) ? true : null;
1621
- },
1622
- setIsDragging(isDragging) {
1623
- inputView === null || inputView === void 0 ? void 0 : inputView.setIsHidden(isDragging);
1624
- },
1625
- setIsSelected(isSelected) {
1626
- regionView.setIsSelected(isSelected);
1627
- },
1628
- setIsDisabled(isDisabled) {
1629
- Dom.toggleClass(g, isDisabled, 'sqd-disabled');
1630
- },
1631
- hasOutput() {
1632
- return branchComponents.some(c => c.hasOutput);
1633
- }
1634
- };
1635
1624
  };
1636
1625
 
1626
+ const COMPONENT_CLASS_NAME = 'task';
1637
1627
  const createTaskStepComponentViewFactory = (isInterrupted, cfg) => (parentElement, stepContext, viewContext) => {
1638
1628
  const { step } = stepContext;
1639
- const g = ComponentDom.stepG('task', step.type, step.id);
1629
+ const g = ComponentDom.stepG(COMPONENT_CLASS_NAME, step.type, step.id);
1640
1630
  parentElement.appendChild(g);
1641
1631
  const boxHeight = cfg.paddingY * 2 + cfg.iconSize;
1642
1632
  const text = Dom.svg('text', {
@@ -1686,9 +1676,7 @@ const createTaskStepComponentViewFactory = (isInterrupted, cfg) => (parentElemen
1686
1676
  joinX: boxWidth / 2,
1687
1677
  sequenceComponents: null,
1688
1678
  placeholders: null,
1689
- hasOutput() {
1690
- return !!outputView;
1691
- },
1679
+ hasOutput: !!outputView,
1692
1680
  getClientPosition() {
1693
1681
  return getAbsolutePosition(rect);
1694
1682
  },
@@ -1977,6 +1965,64 @@ class RectPlaceholder {
1977
1965
  }
1978
1966
  }
1979
1967
 
1968
+ class DefaultRegionView {
1969
+ static create(parent, widths, height) {
1970
+ const totalWidth = widths.reduce((result, width) => result + width, 0);
1971
+ const lines = [
1972
+ drawLine(parent, 0, 0, totalWidth, 0),
1973
+ drawLine(parent, 0, 0, 0, height),
1974
+ drawLine(parent, 0, height, totalWidth, height),
1975
+ drawLine(parent, totalWidth, 0, totalWidth, height)
1976
+ ];
1977
+ let offsetX = widths[0];
1978
+ for (let i = 1; i < widths.length; i++) {
1979
+ lines.push(drawLine(parent, offsetX, 0, offsetX, height));
1980
+ offsetX += widths[i];
1981
+ }
1982
+ return new DefaultRegionView(lines, totalWidth, height);
1983
+ }
1984
+ constructor(lines, width, height) {
1985
+ this.lines = lines;
1986
+ this.width = width;
1987
+ this.height = height;
1988
+ }
1989
+ getClientPosition() {
1990
+ return getAbsolutePosition(this.lines[0]);
1991
+ }
1992
+ resolveClick(click) {
1993
+ const regionPosition = this.getClientPosition();
1994
+ const d = click.position.subtract(regionPosition);
1995
+ if (d.x >= 0 && d.y >= 0 && d.x < this.width * click.scale && d.y < this.height * click.scale) {
1996
+ return true;
1997
+ }
1998
+ return null;
1999
+ }
2000
+ setIsSelected(isSelected) {
2001
+ this.lines.forEach(region => {
2002
+ Dom.toggleClass(region, isSelected, 'sqd-selected');
2003
+ });
2004
+ }
2005
+ }
2006
+ function drawLine(parent, x1, y1, x2, y2) {
2007
+ const line = Dom.svg('line', {
2008
+ class: 'sqd-region',
2009
+ x1,
2010
+ y1,
2011
+ x2,
2012
+ y2
2013
+ });
2014
+ parent.insertBefore(line, parent.firstChild);
2015
+ return line;
2016
+ }
2017
+
2018
+ class DefaultRegionComponentViewExtension {
2019
+ create(parentElement, componentClassName, stepContext, _, contentFactory) {
2020
+ const g = ComponentDom.stepG(componentClassName, stepContext.step.type, stepContext.step.id);
2021
+ parentElement.appendChild(g);
2022
+ return contentFactory(g, DefaultRegionView.create);
2023
+ }
2024
+ }
2025
+
1980
2026
  function readMousePosition(e) {
1981
2027
  return new Vector(e.pageX, e.pageY);
1982
2028
  }
@@ -2478,9 +2524,22 @@ class WorkspaceControllerWrapper {
2478
2524
  }
2479
2525
  }
2480
2526
 
2527
+ class MemoryPreferenceStorage {
2528
+ constructor() {
2529
+ this.map = {};
2530
+ }
2531
+ setItem(key, value) {
2532
+ this.map[key] = value;
2533
+ }
2534
+ getItem(key) {
2535
+ var _a;
2536
+ return (_a = this.map[key]) !== null && _a !== void 0 ? _a : null;
2537
+ }
2538
+ }
2539
+
2481
2540
  class DesignerContext {
2482
2541
  static create(parent, startDefinition, configuration, services) {
2483
- var _a, _b, _c, _d;
2542
+ var _a, _b, _c, _d, _e;
2484
2543
  const definition = ObjectCloner.deepClone(startDefinition);
2485
2544
  const layoutController = new LayoutController(parent);
2486
2545
  const isReadonly = !!configuration.isReadonly;
@@ -2499,7 +2558,8 @@ class DesignerContext {
2499
2558
  if (configuration.undoStackSize) {
2500
2559
  historyController = HistoryController.create(configuration.undoStack, state, stateModifier, configuration);
2501
2560
  }
2502
- const componentContext = ComponentContext.create(configuration.steps, configuration.validator, state, stepExtensionResolver, i18n, services);
2561
+ const preferenceStorage = (_e = configuration.preferenceStorage) !== null && _e !== void 0 ? _e : new MemoryPreferenceStorage();
2562
+ const componentContext = ComponentContext.create(configuration, state, stepExtensionResolver, definitionWalker, preferenceStorage, i18n, services);
2503
2563
  return new DesignerContext(theme, state, configuration, services, componentContext, definitionWalker, i18n, stateModifier, layoutController, workspaceController, behaviorController, customActionController, historyController);
2504
2564
  }
2505
2565
  constructor(theme, state, configuration, services, componentContext, definitionWalker, i18n, stateModifier, layoutController, workspaceController, behaviorController, customActionController, historyController) {
@@ -3925,7 +3985,7 @@ class DefaultPlaceholderControllerExtension {
3925
3985
  }
3926
3986
 
3927
3987
  const defaultConfiguration$3 = {
3928
- gapWidth: 100,
3988
+ gapWidth: 88,
3929
3989
  gapHeight: 24,
3930
3990
  radius: 6,
3931
3991
  iconSize: 16
@@ -4194,6 +4254,9 @@ function merge(services, extensions) {
4194
4254
  if (ext.placeholder) {
4195
4255
  services.placeholder = ext.placeholder;
4196
4256
  }
4257
+ if (ext.regionComponentView) {
4258
+ services.regionComponentView = ext.regionComponentView;
4259
+ }
4197
4260
  if (ext.viewportController) {
4198
4261
  services.viewportController = ext.viewportController;
4199
4262
  }
@@ -4254,6 +4317,9 @@ function setDefaults(services, configuration) {
4254
4317
  if (!services.placeholder) {
4255
4318
  services.placeholder = RectPlaceholderExtension.create();
4256
4319
  }
4320
+ if (!services.regionComponentView) {
4321
+ services.regionComponentView = new DefaultRegionComponentViewExtension();
4322
+ }
4257
4323
  if (!services.viewportController) {
4258
4324
  services.viewportController = new DefaultViewportControllerExtension();
4259
4325
  }
@@ -4539,6 +4605,8 @@ exports.ComponentContext = ComponentContext;
4539
4605
  exports.ComponentDom = ComponentDom;
4540
4606
  exports.ControlBarApi = ControlBarApi;
4541
4607
  exports.CustomActionController = CustomActionController;
4608
+ exports.DefaultRegionComponentViewExtension = DefaultRegionComponentViewExtension;
4609
+ exports.DefaultRegionView = DefaultRegionView;
4542
4610
  exports.DefaultSequenceComponent = DefaultSequenceComponent;
4543
4611
  exports.DefaultSequenceComponentView = DefaultSequenceComponentView;
4544
4612
  exports.DefaultViewportController = DefaultViewportController;
@@ -4561,7 +4629,6 @@ exports.PathBarApi = PathBarApi;
4561
4629
  exports.QuantifiedScaleViewportCalculator = QuantifiedScaleViewportCalculator;
4562
4630
  exports.RectPlaceholder = RectPlaceholder;
4563
4631
  exports.RectPlaceholderView = RectPlaceholderView;
4564
- exports.RegionView = RegionView;
4565
4632
  exports.ServicesResolver = ServicesResolver;
4566
4633
  exports.SimpleEvent = SimpleEvent;
4567
4634
  exports.StepComponent = StepComponent;