@metadev/daga 1.0.0 → 1.2.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.
Files changed (33) hide show
  1. package/Changelog.md +24 -1
  2. package/README.md +1 -1
  3. package/assets/fonts/DMMono-Medium.ttf +0 -0
  4. package/assets/fonts/DMMono-Medium.woff +0 -0
  5. package/assets/fonts/DMMono-Medium.woff2 +0 -0
  6. package/assets/fonts/WonderUnitSans-Medium.ttf +0 -0
  7. package/assets/fonts/WonderUnitSans-Medium.woff +0 -0
  8. package/assets/fonts/WonderUnitSans-Medium.woff2 +0 -0
  9. package/assets/styles/_collapse-button.scss +37 -0
  10. package/assets/styles/_diagram-buttons.scss +132 -0
  11. package/assets/styles/_diagram.scss +15 -0
  12. package/assets/styles/_errors.scss +83 -0
  13. package/assets/styles/_palette.scss +12 -0
  14. package/assets/styles/_property-editor.scss +160 -0
  15. package/assets/styles/daga.scss +152 -0
  16. package/fesm2022/metadev-daga.mjs +1257 -996
  17. package/fesm2022/metadev-daga.mjs.map +1 -1
  18. package/index.d.ts +16 -7
  19. package/lib/collapse-button/collapse-button.component.d.ts +1 -0
  20. package/lib/diagram-editor/diagram/diagram-action.d.ts +10 -1
  21. package/lib/diagram-editor/diagram/diagram-canvas.d.ts +8 -1
  22. package/lib/diagram-editor/diagram/diagram-config.d.ts +8 -0
  23. package/lib/diagram-editor/diagram/diagram-connection.d.ts +12 -3
  24. package/lib/diagram-editor/diagram/diagram-element.d.ts +74 -2
  25. package/lib/diagram-editor/diagram/diagram-field.d.ts +13 -3
  26. package/lib/diagram-editor/diagram/diagram-model.d.ts +10 -42
  27. package/lib/diagram-editor/diagram/diagram-node.d.ts +12 -3
  28. package/lib/diagram-editor/diagram/diagram-port.d.ts +12 -3
  29. package/lib/diagram-editor/diagram/diagram-section.d.ts +12 -2
  30. package/lib/interfaces/canvas.d.ts +7 -1
  31. package/lib/object-editor/object-editor.component.d.ts +1 -0
  32. package/package.json +1 -1
  33. package/assets/styles/styles.scss +0 -181
@@ -7,7 +7,7 @@ import * as i4 from '@angular/forms';
7
7
  import { FormsModule } from '@angular/forms';
8
8
  import * as i3 from '@metadev/lux';
9
9
  import { LuxModule } from '@metadev/lux';
10
- import { Subject, delay, map, combineLatest } from 'rxjs';
10
+ import { Subject, combineLatest, delay, map } from 'rxjs';
11
11
 
12
12
  var Side;
13
13
  (function (Side) {
@@ -71,12 +71,56 @@ class CollapseButtonComponent {
71
71
  selection.style(this.rule, this.collapsed ? this.collapsedValue : this.visibleValue);
72
72
  }
73
73
  }
74
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: CollapseButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
75
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.6", type: CollapseButtonComponent, isStandalone: true, selector: "daga-collapse-button", inputs: { collapsableSelector: "collapsableSelector", collapsableAdditionalSelector: "collapsableAdditionalSelector", collapsed: "collapsed", disabled: "disabled", direction: "direction", rule: "rule", collapsedValue: "collapsedValue", visibleValue: "visibleValue" }, ngImport: i0, template: "<button class=\"collapse-button {{ direction }}\" (click)=\"toggleCollapse()\">\n <img\n *ngIf=\"direction === Side.Bottom && disabled\"\n src=\"/assets/daga/icon/action/drop-vertical-none.svg\"\n />\n <img\n *ngIf=\"direction === Side.Bottom && !disabled && collapsed\"\n src=\"/assets/daga/icon/action/drop-vertical-down.svg\"\n />\n <img\n *ngIf=\"direction === Side.Bottom && !disabled && !collapsed\"\n src=\"/assets/daga/icon/action/drop-vertical-up.svg\"\n />\n\n <img\n *ngIf=\"direction === Side.Top && disabled\"\n src=\"/assets/daga/icon/action/drop-vertical-none.svg\"\n />\n <img\n *ngIf=\"direction === Side.Top && !disabled && collapsed\"\n src=\"/assets/daga/icon/action/drop-vertical-up.svg\"\n />\n <img\n *ngIf=\"direction === Side.Top && !disabled && !collapsed\"\n src=\"/assets/daga/icon/action/drop-vertical-down.svg\"\n />\n\n <img\n *ngIf=\"direction === Side.Left && disabled\"\n src=\"/assets/daga/icon/action/drop-horizontal-none.svg\"\n />\n <img\n *ngIf=\"direction === Side.Left && !disabled && collapsed\"\n src=\"/assets/daga/icon/action/drop-horizontal-left.svg\"\n />\n <img\n *ngIf=\"direction === Side.Left && !disabled && !collapsed\"\n src=\"/assets/daga/icon/action/drop-horizontal-right.svg\"\n />\n\n <img\n *ngIf=\"direction === Side.Right && disabled\"\n src=\"/assets/daga/icon/action/drop-horizontal-none.svg\"\n />\n <img\n *ngIf=\"direction === Side.Right && !disabled && collapsed\"\n src=\"/assets/daga/icon/action/drop-horizontal-right.svg\"\n />\n <img\n *ngIf=\"direction === Side.Right && !disabled && !collapsed\"\n src=\"/assets/daga/icon/action/drop-horizontal-left.svg\"\n />\n</button>\n", styles: [".collapse-button{width:100%;height:100%;min-width:2rem;min-height:2rem;margin:0;border:0;padding:0;background-color:transparent;cursor:pointer}.collapse-button img{width:1.5rem;height:1.5rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
74
+ getClass() {
75
+ switch (this.direction) {
76
+ case Side.Right:
77
+ if (this.disabled) {
78
+ return 'horizontal-none';
79
+ }
80
+ else if (this.collapsed) {
81
+ return 'horizontal-right';
82
+ }
83
+ else {
84
+ return 'horizontal-left';
85
+ }
86
+ case Side.Bottom:
87
+ if (this.disabled) {
88
+ return 'vertical-none';
89
+ }
90
+ else if (this.collapsed) {
91
+ return 'vertical-down';
92
+ }
93
+ else {
94
+ return 'vertical-up';
95
+ }
96
+ case Side.Left:
97
+ if (this.disabled) {
98
+ return 'horizontal-none';
99
+ }
100
+ else if (this.collapsed) {
101
+ return 'horizontal-left';
102
+ }
103
+ else {
104
+ return 'horizontal-right';
105
+ }
106
+ case Side.Top:
107
+ if (this.disabled) {
108
+ return 'vertical-none';
109
+ }
110
+ else if (this.collapsed) {
111
+ return 'vertical-up';
112
+ }
113
+ else {
114
+ return 'vertical-down';
115
+ }
116
+ }
117
+ }
118
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: CollapseButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
119
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.1.2", type: CollapseButtonComponent, isStandalone: true, selector: "daga-collapse-button", inputs: { collapsableSelector: "collapsableSelector", collapsableAdditionalSelector: "collapsableAdditionalSelector", collapsed: "collapsed", disabled: "disabled", direction: "direction", rule: "rule", collapsedValue: "collapsedValue", visibleValue: "visibleValue" }, ngImport: i0, template: "<button class=\"collapse-button {{ direction }}\" (click)=\"toggleCollapse()\">\n <div [class]=\"getClass()\"></div>\n</button>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
76
120
  }
77
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: CollapseButtonComponent, decorators: [{
121
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: CollapseButtonComponent, decorators: [{
78
122
  type: Component,
79
- args: [{ standalone: true, selector: 'daga-collapse-button', imports: [CommonModule], template: "<button class=\"collapse-button {{ direction }}\" (click)=\"toggleCollapse()\">\n <img\n *ngIf=\"direction === Side.Bottom && disabled\"\n src=\"/assets/daga/icon/action/drop-vertical-none.svg\"\n />\n <img\n *ngIf=\"direction === Side.Bottom && !disabled && collapsed\"\n src=\"/assets/daga/icon/action/drop-vertical-down.svg\"\n />\n <img\n *ngIf=\"direction === Side.Bottom && !disabled && !collapsed\"\n src=\"/assets/daga/icon/action/drop-vertical-up.svg\"\n />\n\n <img\n *ngIf=\"direction === Side.Top && disabled\"\n src=\"/assets/daga/icon/action/drop-vertical-none.svg\"\n />\n <img\n *ngIf=\"direction === Side.Top && !disabled && collapsed\"\n src=\"/assets/daga/icon/action/drop-vertical-up.svg\"\n />\n <img\n *ngIf=\"direction === Side.Top && !disabled && !collapsed\"\n src=\"/assets/daga/icon/action/drop-vertical-down.svg\"\n />\n\n <img\n *ngIf=\"direction === Side.Left && disabled\"\n src=\"/assets/daga/icon/action/drop-horizontal-none.svg\"\n />\n <img\n *ngIf=\"direction === Side.Left && !disabled && collapsed\"\n src=\"/assets/daga/icon/action/drop-horizontal-left.svg\"\n />\n <img\n *ngIf=\"direction === Side.Left && !disabled && !collapsed\"\n src=\"/assets/daga/icon/action/drop-horizontal-right.svg\"\n />\n\n <img\n *ngIf=\"direction === Side.Right && disabled\"\n src=\"/assets/daga/icon/action/drop-horizontal-none.svg\"\n />\n <img\n *ngIf=\"direction === Side.Right && !disabled && collapsed\"\n src=\"/assets/daga/icon/action/drop-horizontal-right.svg\"\n />\n <img\n *ngIf=\"direction === Side.Right && !disabled && !collapsed\"\n src=\"/assets/daga/icon/action/drop-horizontal-left.svg\"\n />\n</button>\n", styles: [".collapse-button{width:100%;height:100%;min-width:2rem;min-height:2rem;margin:0;border:0;padding:0;background-color:transparent;cursor:pointer}.collapse-button img{width:1.5rem;height:1.5rem}\n"] }]
123
+ args: [{ standalone: true, selector: 'daga-collapse-button', imports: [CommonModule], template: "<button class=\"collapse-button {{ direction }}\" (click)=\"toggleCollapse()\">\n <div [class]=\"getClass()\"></div>\n</button>\n" }]
80
124
  }], propDecorators: { collapsableSelector: [{
81
125
  type: Input
82
126
  }], collapsableAdditionalSelector: [{
@@ -223,8 +267,8 @@ class AdjacencyLayout {
223
267
  arrangeNode(nodesToBeArranged[0], nodeArrangement, [0, 0], nodesToBeArranged);
224
268
  }
225
269
  // place nodes according to arrangement
226
- const maximumWidth = Math.max(...model.nodes.map((n) => n.width));
227
- const maximumHeight = Math.max(...model.nodes.map((n) => n.height));
270
+ const maximumWidth = Math.max(...model.nodes.all().map((n) => n.width));
271
+ const maximumHeight = Math.max(...model.nodes.all().map((n) => n.height));
228
272
  const gapSize = (model.canvas?.gridSize || 0) * 2;
229
273
  for (let y = nodeArrangement.minY(); y <= nodeArrangement.maxY(); ++y) {
230
274
  for (let x = nodeArrangement.minX(); x <= nodeArrangement.maxX(); ++x) {
@@ -294,8 +338,8 @@ class BreadthAdjacencyLayout {
294
338
  }
295
339
  }
296
340
  // place nodes according to arrangement
297
- const maximumWidth = Math.max(...model.nodes.map((n) => n.width));
298
- const maximumHeight = Math.max(...model.nodes.map((n) => n.height));
341
+ const maximumWidth = Math.max(...model.nodes.all().map((n) => n.width));
342
+ const maximumHeight = Math.max(...model.nodes.all().map((n) => n.height));
299
343
  const gapSize = (model.canvas?.gridSize || 0) * 2;
300
344
  for (let y = nodeArrangement.minY(); y <= nodeArrangement.maxY(); ++y) {
301
345
  for (let x = nodeArrangement.minX(); x <= nodeArrangement.maxX(); ++x) {
@@ -514,7 +558,7 @@ class ForceLayout {
514
558
  temperature = temperature * coolingFactor;
515
559
  // calculate the center of the diagram for applying gravity
516
560
  const diagramCenterCoords = [0, 0];
517
- if (gravityFactor !== 0) {
561
+ if (gravityFactor > 0) {
518
562
  for (const node of model.nodes) {
519
563
  diagramCenterCoords[0] =
520
564
  diagramCenterCoords[0] + node.coords[0] + node.width / 2;
@@ -585,7 +629,7 @@ class ForceLayout {
585
629
  newNode2Coords[1] + shiftNodeIfOverlap * (Math.random() * 2 - 1);
586
630
  }
587
631
  // apply gravity force
588
- if (gravityFactor !== 0) {
632
+ if (gravityFactor > 0) {
589
633
  newNode2Coords[0] =
590
634
  newNode2Coords[0] -
591
635
  (node2CenterCoords[0] - diagramCenterCoords[0]) * gravityFactor;
@@ -634,7 +678,7 @@ class HorizontalLayout {
634
678
  return model;
635
679
  }
636
680
  const gapSize = (model.canvas?.gridSize || 0) * 2;
637
- const nodesToBeArranged = model.nodes;
681
+ const nodesToBeArranged = model.nodes.all();
638
682
  nodesToBeArranged.sort((a, b) => b.type.priority - a.type.priority);
639
683
  let widthAccumulator = 0;
640
684
  for (const node of nodesToBeArranged) {
@@ -654,8 +698,8 @@ class PriorityLayout {
654
698
  // nothing to arrange...
655
699
  return model;
656
700
  }
657
- const maximumPriority = Math.max(...model.nodeTypes.map((n) => n.priority));
658
- const minimumPriority = Math.min(...model.nodeTypes.map((n) => n.priority));
701
+ const maximumPriority = Math.max(...model.nodes.types.all().map((n) => n.priority));
702
+ const minimumPriority = Math.min(...model.nodes.types.all().map((n) => n.priority));
659
703
  if (maximumPriority === minimumPriority) {
660
704
  // if there's no disparity in priorities, just use breadth layout
661
705
  new BreadthLayout().apply(model);
@@ -664,7 +708,7 @@ class PriorityLayout {
664
708
  const gapSize = (model.canvas?.gridSize || 0) * 2;
665
709
  const nodesToBeArranged = [...model.nodes];
666
710
  const nodeArrangement = [];
667
- const nodesWithMaximumPriorityToBeArranged = model.getNodes(maximumPriority);
711
+ const nodesWithMaximumPriorityToBeArranged = model.nodes.filter(undefined, maximumPriority);
668
712
  const nodesWithMaximumPriority = [];
669
713
  if (nodesWithMaximumPriorityToBeArranged.length > 1) {
670
714
  // use bfs to sort nodes by distance to the first node
@@ -762,7 +806,7 @@ class VerticalLayout {
762
806
  return model;
763
807
  }
764
808
  const gapSize = (model.canvas?.gridSize || 0) * 2;
765
- const nodesToBeArranged = model.nodes;
809
+ const nodesToBeArranged = model.nodes.all();
766
810
  nodesToBeArranged.sort((a, b) => b.type.priority - a.type.priority);
767
811
  let heightAccumulator = 0;
768
812
  for (const node of nodesToBeArranged) {
@@ -1325,6 +1369,17 @@ class ActionQueue {
1325
1369
  }
1326
1370
  }
1327
1371
  }
1372
+ var DiagramActions;
1373
+ (function (DiagramActions) {
1374
+ DiagramActions["AddConnectionAction"] = "add-connection";
1375
+ DiagramActions["AddNodeAction"] = "add-node";
1376
+ DiagramActions["EditFieldAction"] = "edit-field";
1377
+ DiagramActions["MoveNodeAction"] = "move-node";
1378
+ DiagramActions["RemoveAction"] = "remove";
1379
+ DiagramActions["StretchNodeAction"] = "stretch-node";
1380
+ DiagramActions["StretchSectionAction"] = "stretch-section";
1381
+ DiagramActions["UpdateValuesAction"] = "update-values";
1382
+ })(DiagramActions || (DiagramActions = {}));
1328
1383
  class AddNodeAction {
1329
1384
  constructor(canvas, type, coords, label, values, id) {
1330
1385
  this.canvas = canvas;
@@ -1336,14 +1391,11 @@ class AddNodeAction {
1336
1391
  }
1337
1392
  undo() {
1338
1393
  if (this.id) {
1339
- const node = this.canvas.model.getNode(this.id);
1340
- if (node) {
1341
- this.canvas.model.deleteNode(node);
1342
- }
1394
+ this.canvas.model.nodes.remove(this.id);
1343
1395
  }
1344
1396
  }
1345
1397
  redo() {
1346
- const node = this.canvas.model.addNode(this.type, this.coords, this.id, this.sectionIds, this.sectionPortIds, this.sectionPortLabelIds, this.portIds, this.portLabelIds, this.labelId);
1398
+ const node = this.canvas.model.nodes.new(this.type, this.coords, this.id, this.sectionIds, this.sectionPortIds, this.sectionPortLabelIds, this.portIds, this.portLabelIds, this.labelId);
1347
1399
  if (this.values !== undefined) {
1348
1400
  node.valueSet.setValues(structuredClone({
1349
1401
  ...node.valueSet.getValues(),
@@ -1372,16 +1424,10 @@ class MoveNodeAction {
1372
1424
  this.to = to;
1373
1425
  }
1374
1426
  undo() {
1375
- const node = this.canvas.model.getNode(this.nodeId);
1376
- if (node) {
1377
- node.move(this.from);
1378
- }
1427
+ this.canvas.model.nodes.get(this.nodeId)?.move(this.from);
1379
1428
  }
1380
1429
  redo() {
1381
- const node = this.canvas.model.getNode(this.nodeId);
1382
- if (node) {
1383
- node.move(this.to);
1384
- }
1430
+ this.canvas.model.nodes.get(this.nodeId)?.move(this.to);
1385
1431
  }
1386
1432
  }
1387
1433
  class StretchNodeAction {
@@ -1393,16 +1439,14 @@ class StretchNodeAction {
1393
1439
  this.to = to;
1394
1440
  }
1395
1441
  undo() {
1396
- const node = this.canvas.model.getNode(this.nodeId);
1397
- if (node) {
1398
- node.stretch(this.direction, this.from - this.to);
1399
- }
1442
+ this.canvas.model.nodes
1443
+ .get(this.nodeId)
1444
+ ?.stretch(this.direction, this.from - this.to);
1400
1445
  }
1401
1446
  redo() {
1402
- const node = this.canvas.model.getNode(this.nodeId);
1403
- if (node) {
1404
- node.stretch(this.direction, this.to - this.from);
1405
- }
1447
+ this.canvas.model.nodes
1448
+ .get(this.nodeId)
1449
+ ?.stretch(this.direction, this.to - this.from);
1406
1450
  }
1407
1451
  }
1408
1452
  class StretchSectionAction {
@@ -1414,14 +1458,14 @@ class StretchSectionAction {
1414
1458
  this.to = to;
1415
1459
  }
1416
1460
  undo() {
1417
- const section = this.canvas.model.getSection(this.sectionId);
1461
+ const section = this.canvas.model.sections.get(this.sectionId);
1418
1462
  const node = section?.node;
1419
1463
  if (node) {
1420
1464
  node.stretchSections(this.direction, this.from - this.to, section.coords);
1421
1465
  }
1422
1466
  }
1423
1467
  redo() {
1424
- const section = this.canvas.model.getSection(this.sectionId);
1468
+ const section = this.canvas.model.sections.get(this.sectionId);
1425
1469
  const node = section?.node;
1426
1470
  if (node) {
1427
1471
  node.stretchSections(this.direction, this.to - this.from, section.coords);
@@ -1438,17 +1482,14 @@ class AddConnectionAction {
1438
1482
  }
1439
1483
  undo() {
1440
1484
  if (this.id) {
1441
- const connection = this.canvas.model.getConnection(this.id);
1442
- if (connection) {
1443
- this.canvas.model.deleteConnection(connection);
1444
- }
1485
+ this.canvas.model.connections.remove(this.id);
1445
1486
  }
1446
1487
  }
1447
1488
  redo() {
1448
- const start = this.canvas.model.getPort(this.startId);
1449
- const end = this.canvas.model.getPort(this.endId);
1489
+ const start = this.canvas.model.ports.get(this.startId);
1490
+ const end = this.canvas.model.ports.get(this.endId);
1450
1491
  if (start && end) {
1451
- const connection = this.canvas.model.addConnection(this.type, start, end, this.id);
1492
+ const connection = this.canvas.model.connections.new(this.type, start, end, this.id);
1452
1493
  // reset our id in case it was automatically generated
1453
1494
  this.id = connection.id;
1454
1495
  }
@@ -1462,14 +1503,14 @@ class EditFieldAction {
1462
1503
  this.to = to;
1463
1504
  }
1464
1505
  undo() {
1465
- const field = this.canvas.model.getField(this.fieldId);
1506
+ const field = this.canvas.model.fields.get(this.fieldId);
1466
1507
  if (field) {
1467
1508
  field.text = this.from;
1468
1509
  this.canvas.updateFieldsInView(this.fieldId);
1469
1510
  }
1470
1511
  }
1471
1512
  redo() {
1472
- const field = this.canvas.model.getField(this.fieldId);
1513
+ const field = this.canvas.model.fields.get(this.fieldId);
1473
1514
  if (field) {
1474
1515
  field.text = this.to;
1475
1516
  this.canvas.updateFieldsInView(this.fieldId);
@@ -1488,7 +1529,7 @@ class UpdateValuesAction {
1488
1529
  return this.model.valueSet;
1489
1530
  }
1490
1531
  else {
1491
- return this.model.getElement(this.id)?.valueSet;
1532
+ return (this.model.nodes.get(this.id) || this.model.connections.get(this.id))?.valueSet;
1492
1533
  }
1493
1534
  }
1494
1535
  undo() {
@@ -1557,30 +1598,30 @@ class RemoveAction {
1557
1598
  }
1558
1599
  undo() {
1559
1600
  for (const node of this.nodes) {
1560
- this.model.nodes.push(node);
1601
+ this.model.nodes.add(node);
1561
1602
  }
1562
1603
  for (const section of this.sections) {
1563
- this.model.sections.push(section);
1604
+ this.model.sections.add(section);
1564
1605
  }
1565
1606
  for (const port of this.ports) {
1566
- this.model.ports.push(port);
1607
+ this.model.ports.add(port);
1567
1608
  }
1568
1609
  for (const connection of this.connections) {
1569
- this.model.connections.push(connection);
1610
+ this.model.connections.add(connection);
1570
1611
  }
1571
1612
  for (const field of this.fields) {
1572
- this.model.fields.push(field);
1613
+ this.model.fields.add(field);
1573
1614
  }
1574
1615
  for (const node of this.nodes) {
1575
1616
  if (node.label) {
1576
- const label = this.model.getField(node.label._id);
1617
+ const label = this.model.fields.get(node.label._id);
1577
1618
  if (label) {
1578
1619
  node.label = label;
1579
1620
  }
1580
1621
  }
1581
1622
  const ports = [];
1582
1623
  for (const nodePort of node.ports) {
1583
- const port = this.model.getPort(nodePort._id);
1624
+ const port = this.model.ports.get(nodePort._id);
1584
1625
  if (port) {
1585
1626
  ports.push(port);
1586
1627
  }
@@ -1588,7 +1629,7 @@ class RemoveAction {
1588
1629
  node.ports = ports;
1589
1630
  const sections = [];
1590
1631
  for (const nodeSection of node.sections) {
1591
- const section = this.model.getSection(nodeSection._id);
1632
+ const section = this.model.sections.get(nodeSection._id);
1592
1633
  if (section) {
1593
1634
  sections.push(section);
1594
1635
  }
@@ -1597,20 +1638,20 @@ class RemoveAction {
1597
1638
  }
1598
1639
  for (const section of this.sections) {
1599
1640
  if (section.node) {
1600
- const node = this.model.getNode(section.node._id);
1641
+ const node = this.model.nodes.get(section.node._id);
1601
1642
  if (node) {
1602
1643
  section.node = node;
1603
1644
  }
1604
1645
  }
1605
1646
  if (section.label) {
1606
- const label = this.model.getField(section.label._id);
1647
+ const label = this.model.fields.get(section.label._id);
1607
1648
  if (label) {
1608
1649
  section.label = label;
1609
1650
  }
1610
1651
  }
1611
1652
  const ports = [];
1612
1653
  for (const sectionPort of section.ports) {
1613
- const port = this.model.getPort(sectionPort._id);
1654
+ const port = this.model.ports.get(sectionPort._id);
1614
1655
  if (port) {
1615
1656
  ports.push(port);
1616
1657
  }
@@ -1619,20 +1660,21 @@ class RemoveAction {
1619
1660
  }
1620
1661
  for (const port of this.ports) {
1621
1662
  if (port.rootElement) {
1622
- const rootElement = this.model.getElement(port.rootElement._id);
1663
+ const rootElement = this.model.nodes.get(port.rootElement._id) ||
1664
+ this.model.sections.get(port.rootElement._id);
1623
1665
  if (rootElement) {
1624
1666
  port.rootElement = rootElement;
1625
1667
  }
1626
1668
  }
1627
1669
  if (port.label) {
1628
- const label = this.model.getField(port.label._id);
1670
+ const label = this.model.fields.get(port.label._id);
1629
1671
  if (label) {
1630
1672
  port.label = label;
1631
1673
  }
1632
1674
  }
1633
1675
  const outgoingConnections = [];
1634
1676
  for (const portOutgoingConnection of port.outgoingConnections) {
1635
- const connection = this.model.getConnection(portOutgoingConnection._id);
1677
+ const connection = this.model.connections.get(portOutgoingConnection._id);
1636
1678
  if (connection) {
1637
1679
  outgoingConnections.push(connection);
1638
1680
  }
@@ -1640,7 +1682,7 @@ class RemoveAction {
1640
1682
  port.outgoingConnections = outgoingConnections;
1641
1683
  const incomingConnections = [];
1642
1684
  for (const portIncomingConnection of port.incomingConnections) {
1643
- const connection = this.model.getConnection(portIncomingConnection._id);
1685
+ const connection = this.model.connections.get(portIncomingConnection._id);
1644
1686
  if (connection) {
1645
1687
  incomingConnections.push(connection);
1646
1688
  }
@@ -1649,13 +1691,13 @@ class RemoveAction {
1649
1691
  }
1650
1692
  for (const connection of this.connections) {
1651
1693
  if (connection.start) {
1652
- const start = this.model.getPort(connection.start._id);
1694
+ const start = this.model.ports.get(connection.start._id);
1653
1695
  if (start) {
1654
1696
  connection.setStart(start);
1655
1697
  }
1656
1698
  }
1657
1699
  if (connection.end) {
1658
- const end = this.model.getPort(connection.end._id);
1700
+ const end = this.model.ports.get(connection.end._id);
1659
1701
  if (end) {
1660
1702
  connection.setEnd(end);
1661
1703
  }
@@ -1663,7 +1705,9 @@ class RemoveAction {
1663
1705
  }
1664
1706
  for (const field of this.fields) {
1665
1707
  if (field.rootElement) {
1666
- const rootElement = this.model.getElement(field.rootElement._id);
1708
+ const rootElement = this.model.nodes.get(field.rootElement._id) ||
1709
+ this.model.sections.get(field.rootElement._id) ||
1710
+ this.model.ports.get(field.rootElement._id);
1667
1711
  if (rootElement) {
1668
1712
  field.rootElement = rootElement;
1669
1713
  }
@@ -1680,7 +1724,7 @@ class RemoveAction {
1680
1724
  this.fields = [];
1681
1725
  // make shallow copies of the elements with their relationships
1682
1726
  for (const nodeId of this.nodeIds) {
1683
- const node = this.model.getNode(nodeId);
1727
+ const node = this.model.nodes.get(nodeId);
1684
1728
  if (node) {
1685
1729
  const nodeCopy = clone(node);
1686
1730
  if (nodeCopy.label) {
@@ -1692,7 +1736,7 @@ class RemoveAction {
1692
1736
  }
1693
1737
  }
1694
1738
  for (const sectionId of this.sectionIds) {
1695
- const section = this.model.getSection(sectionId);
1739
+ const section = this.model.sections.get(sectionId);
1696
1740
  if (section) {
1697
1741
  const sectionCopy = clone(section);
1698
1742
  if (sectionCopy.label) {
@@ -1703,7 +1747,7 @@ class RemoveAction {
1703
1747
  }
1704
1748
  }
1705
1749
  for (const portId of this.portIds) {
1706
- const port = this.model.getPort(portId);
1750
+ const port = this.model.ports.get(portId);
1707
1751
  if (port) {
1708
1752
  const portCopy = clone(port);
1709
1753
  if (portCopy.rootElement) {
@@ -1718,7 +1762,7 @@ class RemoveAction {
1718
1762
  }
1719
1763
  }
1720
1764
  for (const connectionId of this.connectionIds) {
1721
- const connection = this.model.getConnection(connectionId);
1765
+ const connection = this.model.connections.get(connectionId);
1722
1766
  if (connection) {
1723
1767
  const connectionCopy = clone(connection);
1724
1768
  if (connectionCopy.start) {
@@ -1731,7 +1775,7 @@ class RemoveAction {
1731
1775
  }
1732
1776
  }
1733
1777
  for (const fieldId of this.fieldIds) {
1734
- const field = this.model.getField(fieldId);
1778
+ const field = this.model.fields.get(fieldId);
1735
1779
  if (field) {
1736
1780
  const fieldCopy = clone(field);
1737
1781
  if (fieldCopy.rootElement) {
@@ -1742,34 +1786,19 @@ class RemoveAction {
1742
1786
  }
1743
1787
  // delete the elements
1744
1788
  for (const nodeId of this.nodeIds) {
1745
- const node = this.model.getNode(nodeId);
1746
- if (node) {
1747
- this.model.deleteNode(node);
1748
- }
1789
+ this.model.nodes.remove(nodeId);
1749
1790
  }
1750
1791
  for (const sectionId of this.sectionIds) {
1751
- const section = this.model.getSection(sectionId);
1752
- if (section) {
1753
- this.model.deleteSection(section);
1754
- }
1792
+ this.model.sections.remove(sectionId);
1755
1793
  }
1756
1794
  for (const portId of this.portIds) {
1757
- const port = this.model.getPort(portId);
1758
- if (port) {
1759
- this.model.deletePort(port);
1760
- }
1795
+ this.model.ports.remove(portId);
1761
1796
  }
1762
1797
  for (const connectionId of this.connectionIds) {
1763
- const connection = this.model.getConnection(connectionId);
1764
- if (connection) {
1765
- this.model.deleteConnection(connection);
1766
- }
1798
+ this.model.connections.remove(connectionId);
1767
1799
  }
1768
1800
  for (const fieldId of this.fieldIds) {
1769
- const field = this.model.getField(fieldId);
1770
- if (field) {
1771
- this.model.deleteField(field);
1772
- }
1801
+ this.model.fields.remove(fieldId);
1773
1802
  }
1774
1803
  }
1775
1804
  }
@@ -1781,7 +1810,7 @@ const clone = (obj) => {
1781
1810
  };
1782
1811
 
1783
1812
  /**
1784
- * Represents an object which exists as part of a particular diagram model and has a visual representation in a diagram canvas.
1813
+ * Represents an object which exists as part of a specific diagram model and has a visual representation in a diagram canvas.
1785
1814
  * @see DiagramModel
1786
1815
  * @see DiagramCanvas
1787
1816
  */
@@ -1806,6 +1835,104 @@ class DiagramElement {
1806
1835
  return this.model.canvas?.selectCanvasView()?.select(`g#${this.id}`);
1807
1836
  }
1808
1837
  }
1838
+ /**
1839
+ * Represents a collection of diagram entities of a type that exists as part of a diagram model.
1840
+ * @see DiagramEntity
1841
+ * @see DiagramModel
1842
+ */
1843
+ class DiagramEntitySet {
1844
+ constructor() {
1845
+ /**
1846
+ * The list of entities contained in this set.
1847
+ */
1848
+ this.entities = [];
1849
+ /**
1850
+ * A mapping of entity ids to their corresponding entity in this set for quickly fetching entities based on their id.
1851
+ */
1852
+ this.entityMap = {};
1853
+ }
1854
+ /**
1855
+ * The number of entities of this set.
1856
+ */
1857
+ get length() {
1858
+ return this.entities.length;
1859
+ }
1860
+ /**
1861
+ * Gets all of the entities of this set.
1862
+ * @returns An array containing all of the entities of this set.
1863
+ */
1864
+ all() {
1865
+ return [...this.entities];
1866
+ }
1867
+ /**
1868
+ * Adds an entity to this set if there are no entities with the same id. Has no effect if there already exists an entity with the same id as the given entity.
1869
+ * For creating entities with relationships with other entities, the new() method should be used instead. The add() method adds an entity but doesn't take care of setting that entity's relationships with other entities.
1870
+ * @param entity An entity to be added to this set.
1871
+ */
1872
+ add(entity) {
1873
+ if (this.entityMap[entity.id] === undefined) {
1874
+ this.entityMap[entity.id] = entity;
1875
+ this.entities.push(entity);
1876
+ }
1877
+ }
1878
+ /**
1879
+ * Removes all the entities in this set.
1880
+ */
1881
+ clear() {
1882
+ // remove each entity individually in case classes that extend this implement their own specific cleanup
1883
+ while (this.entities.length > 0) {
1884
+ this.remove(this.entities[0].id);
1885
+ }
1886
+ }
1887
+ /**
1888
+ * Checks if this set contains an entity with the given id.
1889
+ * @param id An id.
1890
+ * @returns `true` if this set contains an entity with the given id, `false` otherwise.
1891
+ */
1892
+ contains(id) {
1893
+ return this.entityMap[id] !== undefined;
1894
+ }
1895
+ /**
1896
+ * Gets all of the entities of this set filtered following given criteria.
1897
+ * @returns An array containing the entities of this set that meet the given criteria.
1898
+ */
1899
+ filter() {
1900
+ return this.all();
1901
+ }
1902
+ /**
1903
+ * Gets an entity of this set matching specific criteria.
1904
+ * @returns An entity of this set.
1905
+ */
1906
+ find() {
1907
+ return this.entities.length > 0 ? this.entities[0] : undefined;
1908
+ }
1909
+ /**
1910
+ * Gets an entity from this set.
1911
+ * @param id An id.
1912
+ * @returns An entity with the given id, or `undefined` if there are no entities with the given id.
1913
+ */
1914
+ get(id) {
1915
+ return this.entityMap[id];
1916
+ }
1917
+ /**
1918
+ * Attempts to find and remove an entity with the given id. Has no effect if there are no entities with the given id.
1919
+ * @param id An id.
1920
+ */
1921
+ remove(id) {
1922
+ const entity = this.get(id);
1923
+ if (entity !== undefined) {
1924
+ delete this.entityMap[id];
1925
+ removeIfExists(this.entities, entity);
1926
+ }
1927
+ }
1928
+ *[Symbol.iterator]() {
1929
+ let counter = 0;
1930
+ while (counter < this.entities.length) {
1931
+ yield this.entities[counter];
1932
+ ++counter;
1933
+ }
1934
+ }
1935
+ }
1809
1936
 
1810
1937
  class Property {
1811
1938
  constructor(name, type, defaultValue, basic, editable, rootAttribute) {
@@ -2130,13 +2257,13 @@ class DiagramConnection extends DiagramElement {
2130
2257
  }
2131
2258
  constructor(model, type, start, end, id) {
2132
2259
  let uniqueId;
2133
- if (id !== undefined && model.getConnection(id) === undefined) {
2260
+ if (id !== undefined && model.connections.get(id) === undefined) {
2134
2261
  uniqueId = id;
2135
2262
  }
2136
2263
  else {
2137
2264
  do {
2138
2265
  uniqueId = `diagram-connection-${++idTicker$4}`;
2139
- } while (model.getConnection(uniqueId) !== undefined);
2266
+ } while (model.connections.get(uniqueId) !== undefined);
2140
2267
  }
2141
2268
  super(model, uniqueId);
2142
2269
  this.startCoords = [0, 0];
@@ -2200,9 +2327,52 @@ class DiagramConnection extends DiagramElement {
2200
2327
  }
2201
2328
  }
2202
2329
  }
2330
+ class DiagramConnectionSet extends DiagramEntitySet {
2331
+ constructor(model) {
2332
+ super();
2333
+ this.types = new DiagramEntitySet();
2334
+ this.model = model;
2335
+ }
2336
+ new(type, start, end, id) {
2337
+ const connection = new DiagramConnection(this.model, type, start, end, id);
2338
+ super.add(connection);
2339
+ connection.updateInView();
2340
+ return connection;
2341
+ }
2342
+ remove(id) {
2343
+ const connection = this.get(id);
2344
+ if (connection) {
2345
+ // remove from ports
2346
+ removeIfExists(connection.start?.outgoingConnections || [], connection);
2347
+ removeIfExists(connection.end?.incomingConnections || [], connection);
2348
+ // remove from set of connections
2349
+ super.remove(id);
2350
+ // remove from canvas
2351
+ connection.updateInView();
2352
+ }
2353
+ }
2354
+ filter(type, threshold) {
2355
+ return this.entities.filter((e) => (type ? e.type.id === type : true) &&
2356
+ (threshold
2357
+ ? (e.start?.getNode()?.type?.priority || Number.NEGATIVE_INFINITY) >=
2358
+ threshold &&
2359
+ (e.end?.getNode()?.type?.priority || Number.NEGATIVE_INFINITY) >=
2360
+ threshold
2361
+ : true));
2362
+ }
2363
+ find(type, threshold) {
2364
+ return this.entities.find((e) => (type ? e.type.id === type : true) &&
2365
+ (threshold
2366
+ ? (e.start?.getNode()?.type?.priority || Number.NEGATIVE_INFINITY) >=
2367
+ threshold &&
2368
+ (e.end?.getNode()?.type?.priority || Number.NEGATIVE_INFINITY) >=
2369
+ threshold
2370
+ : true));
2371
+ }
2372
+ }
2203
2373
 
2204
2374
  let idTicker$3 = 0;
2205
- const DIAGRAM_LOOK_DEFAULTS = {
2375
+ const DIAGRAM_SECTION_LOOK_DEFAULTS = {
2206
2376
  lookType: 'shaped-look',
2207
2377
  shape: ClosedShape.Rectangle,
2208
2378
  color: '#FFFFFF',
@@ -2210,46 +2380,17 @@ const DIAGRAM_LOOK_DEFAULTS = {
2210
2380
  selectedColor: '#FFFFFF',
2211
2381
  selectedBorderColor: '#000000'
2212
2382
  };
2213
- const DIAGRAM_NODE_TYPE_DEFAULTS = {
2214
- name: '',
2215
- defaultWidth: 0,
2216
- defaultHeight: 0,
2383
+ const DIAGRAM_SECTION_DEFAULTS = {
2384
+ sectionsX: 1,
2385
+ sectionsY: 1,
2217
2386
  minWidth: 0,
2218
2387
  minHeight: 0,
2219
- resizableX: false,
2220
- resizableY: false,
2388
+ margin: 0,
2221
2389
  label: null,
2222
2390
  ports: [],
2223
- sections: null,
2224
- look: DIAGRAM_LOOK_DEFAULTS,
2225
- isUnique: false,
2226
- priority: 0,
2227
- properties: []
2391
+ look: DIAGRAM_SECTION_LOOK_DEFAULTS
2228
2392
  };
2229
- class DiagramNodeType {
2230
- constructor(options) {
2231
- const values = {
2232
- ...DIAGRAM_NODE_TYPE_DEFAULTS,
2233
- ...options
2234
- };
2235
- this.id = values.id;
2236
- this.name = values.name;
2237
- this.defaultWidth = values.defaultWidth;
2238
- this.defaultHeight = values.defaultHeight;
2239
- this.minWidth = values.minWidth;
2240
- this.minHeight = values.minHeight;
2241
- this.resizableX = values.resizableX;
2242
- this.resizableY = values.resizableY;
2243
- this.label = values.label;
2244
- this.ports = values.ports;
2245
- this.sections = values.sections;
2246
- this.look = values.look;
2247
- this.isUnique = values.isUnique;
2248
- this.priority = values.priority;
2249
- this.propertySet = new PropertySet(options?.properties || []);
2250
- }
2251
- }
2252
- class DiagramNode extends DiagramElement {
2393
+ class DiagramSection extends DiagramElement {
2253
2394
  get name() {
2254
2395
  return this.label?.text || '';
2255
2396
  }
@@ -2259,29 +2400,26 @@ class DiagramNode extends DiagramElement {
2259
2400
  this.label.updateInView();
2260
2401
  }
2261
2402
  }
2262
- constructor(model, type, coords = [0, 0], id) {
2403
+ constructor(model, node, coords, width, height, id) {
2263
2404
  let uniqueId;
2264
- if (id !== undefined && model.getNode(id) === undefined) {
2405
+ if (id !== undefined && model.sections.get(id) === undefined) {
2265
2406
  uniqueId = id;
2266
2407
  }
2267
2408
  else {
2268
2409
  do {
2269
- uniqueId = `diagram-node-${++idTicker$3}`;
2270
- } while (model.getNode(uniqueId) !== undefined);
2410
+ uniqueId = `diagram-section-${++idTicker$3}`;
2411
+ } while (model.sections.get(uniqueId) !== undefined);
2271
2412
  }
2272
2413
  super(model, uniqueId);
2273
- this.sections = [];
2274
2414
  this.ports = [];
2275
- this.type = type;
2276
- this.valueSet = new ValueSet(type.propertySet, this);
2277
- this.originalData = {};
2415
+ this.node = node;
2278
2416
  this.coords = coords;
2279
- this.width = type.defaultWidth;
2280
- this.height = type.defaultHeight;
2417
+ this.width = width;
2418
+ this.height = height;
2281
2419
  }
2282
2420
  updateInView() {
2283
2421
  if (this.model.canvas && this.model.renderToCanvas) {
2284
- this.model.canvas.updateNodesInView(this.id);
2422
+ this.model.canvas.updateSectionsInView(this.id);
2285
2423
  }
2286
2424
  }
2287
2425
  getClosestPortToPoint(coords) {
@@ -2328,36 +2466,12 @@ class DiagramNode extends DiagramElement {
2328
2466
  }
2329
2467
  return result;
2330
2468
  }
2331
- getAdjacentNodes() {
2332
- const result = [];
2333
- for (const port of this.ports) {
2334
- for (const incomingConnection of port.incomingConnections) {
2335
- const otherNode = incomingConnection.start?.getNode();
2336
- if (otherNode) {
2337
- result.push(otherNode);
2338
- }
2339
- }
2340
- for (const outgoingConnection of port.outgoingConnections) {
2341
- const otherNode = outgoingConnection.end?.getNode();
2342
- if (otherNode) {
2343
- result.push(otherNode);
2344
- }
2345
- }
2346
- }
2347
- return result;
2348
- }
2349
2469
  move(coords) {
2350
2470
  const coordDifferences = [
2351
2471
  coords[0] - this.coords[0],
2352
2472
  coords[1] - this.coords[1]
2353
2473
  ];
2354
2474
  this.coords = coords;
2355
- for (const section of this.sections) {
2356
- section.move([
2357
- section.coords[0] + coordDifferences[0],
2358
- section.coords[1] + coordDifferences[1]
2359
- ]);
2360
- }
2361
2475
  for (const port of this.ports) {
2362
2476
  port.move([
2363
2477
  port.coords[0] + coordDifferences[0],
@@ -2382,29 +2496,49 @@ class DiagramNode extends DiagramElement {
2382
2496
  case Side.Left:
2383
2497
  newCoordsX = [oldCoordsX[0] - distance, oldCoordsX[1]];
2384
2498
  newCoordsY = [oldCoordsY[0], oldCoordsY[1]];
2385
- if (newCoordsX[1] - newCoordsX[0] < this.type.minWidth) {
2386
- newCoordsX[0] = newCoordsX[1] - this.type.minWidth;
2499
+ if (newCoordsX[1] - newCoordsX[0] <
2500
+ (this.node?.type?.sections?.minWidth ||
2501
+ DIAGRAM_SECTION_DEFAULTS.minWidth)) {
2502
+ newCoordsX[0] =
2503
+ newCoordsX[1] -
2504
+ (this.node?.type?.sections?.minWidth ||
2505
+ DIAGRAM_SECTION_DEFAULTS.minWidth);
2387
2506
  }
2388
2507
  break;
2389
2508
  case Side.Top:
2390
2509
  newCoordsX = [oldCoordsX[0], oldCoordsX[1]];
2391
2510
  newCoordsY = [oldCoordsY[0] - distance, oldCoordsY[1]];
2392
- if (newCoordsY[1] - newCoordsY[0] < this.type.minHeight) {
2393
- newCoordsY[0] = newCoordsY[1] - this.type.minHeight;
2511
+ if (newCoordsY[1] - newCoordsY[0] <
2512
+ (this.node?.type?.sections?.minHeight ||
2513
+ DIAGRAM_SECTION_DEFAULTS.minHeight)) {
2514
+ newCoordsY[0] =
2515
+ newCoordsY[1] -
2516
+ (this.node?.type?.sections?.minHeight ||
2517
+ DIAGRAM_SECTION_DEFAULTS.minHeight);
2394
2518
  }
2395
2519
  break;
2396
2520
  case Side.Right:
2397
2521
  newCoordsX = [oldCoordsX[0], oldCoordsX[1] + distance];
2398
2522
  newCoordsY = [oldCoordsY[0], oldCoordsY[1]];
2399
- if (newCoordsX[1] - newCoordsX[0] < this.type.minWidth) {
2400
- newCoordsX[1] = newCoordsX[0] + this.type.minWidth;
2523
+ if (newCoordsX[1] - newCoordsX[0] <
2524
+ (this.node?.type?.sections?.minWidth ||
2525
+ DIAGRAM_SECTION_DEFAULTS.minWidth)) {
2526
+ newCoordsX[1] =
2527
+ newCoordsX[0] +
2528
+ (this.node?.type?.sections?.minWidth ||
2529
+ DIAGRAM_SECTION_DEFAULTS.minWidth);
2401
2530
  }
2402
2531
  break;
2403
2532
  case Side.Bottom:
2404
2533
  newCoordsX = [oldCoordsX[0], oldCoordsX[1]];
2405
2534
  newCoordsY = [oldCoordsY[0], oldCoordsY[1] + distance];
2406
- if (newCoordsY[1] - newCoordsY[0] < this.type.minHeight) {
2407
- newCoordsY[1] = newCoordsY[0] + this.type.minHeight;
2535
+ if (newCoordsY[1] - newCoordsY[0] <
2536
+ (this.node?.type?.sections?.minHeight ||
2537
+ DIAGRAM_SECTION_DEFAULTS.minHeight)) {
2538
+ newCoordsY[1] =
2539
+ newCoordsY[0] +
2540
+ (this.node?.type?.sections?.minHeight ||
2541
+ DIAGRAM_SECTION_DEFAULTS.minHeight);
2408
2542
  }
2409
2543
  break;
2410
2544
  }
@@ -2416,74 +2550,181 @@ class DiagramNode extends DiagramElement {
2416
2550
  }
2417
2551
  if (this.label) {
2418
2552
  this.label.coords = [
2419
- this.coords[0] + (this.type.label?.margin || 0),
2420
- this.coords[1] + (this.type.label?.margin || 0)
2553
+ this.coords[0] + (this.node?.type?.sections?.label?.margin || 0),
2554
+ this.coords[1] + (this.node?.type?.sections?.label?.margin || 0)
2421
2555
  ];
2422
- (this.label.width = this.width - (this.type.label?.margin || 0) * 2),
2423
- (this.label.height = this.height - (this.type.label?.margin || 0) * 2);
2556
+ (this.label.width =
2557
+ this.width - (this.node?.type?.sections?.label?.margin || 0) * 2),
2558
+ (this.label.height =
2559
+ this.height - (this.node?.type?.sections?.label?.margin || 0) * 2);
2424
2560
  }
2425
- // we ignore this.sections, the stretching of a node with sections is handled in the stretchSections method
2426
2561
  this.updateInView();
2427
2562
  }
2428
- stretchSections(direction, distance, point) {
2429
- switch (direction) {
2430
- case Side.Bottom:
2431
- for (const section of this.sections) {
2432
- if (section.coords[1] === point[1]) {
2433
- section.stretch(direction, distance);
2434
- }
2435
- else if (section.coords[1] > point[1]) {
2436
- section.move([section.coords[0], section.coords[1] + distance]);
2563
+ }
2564
+ class DiagramSectionSet extends DiagramEntitySet {
2565
+ constructor(model) {
2566
+ super();
2567
+ this.model = model;
2568
+ }
2569
+ new(node, coords, width, height, id, portIds, portLabelIds) {
2570
+ const section = new DiagramSection(this.model, node, coords, width, height, id);
2571
+ super.add(section);
2572
+ section.updateInView();
2573
+ // add this section to its node
2574
+ node.sections.push(section);
2575
+ node.updateInView();
2576
+ // add section ports
2577
+ if (node.type.sections?.ports && node.type.sections.ports.length > 0) {
2578
+ for (let i = 0; i < node.type.sections.ports.length; ++i) {
2579
+ const portConfig = node.type.sections.ports[i];
2580
+ const port = this.model.ports.new(section, [
2581
+ section.coords[0] + portConfig.coords[0],
2582
+ section.coords[1] + portConfig.coords[1]
2583
+ ], portConfig.direction, portIds && portIds.length > i ? portIds[i] : undefined);
2584
+ if (portConfig.label) {
2585
+ const labelConfiguration = {
2586
+ ...DIAGRAM_FIELD_DEFAULTS,
2587
+ ...portConfig.label
2588
+ };
2589
+ let labelCoords;
2590
+ switch (port.direction) {
2591
+ case Side.Top:
2592
+ case Side.Left:
2593
+ labelCoords = [
2594
+ port.coords[0] - labelConfiguration.fontSize,
2595
+ port.coords[1] - labelConfiguration.fontSize
2596
+ ];
2597
+ break;
2598
+ case Side.Bottom:
2599
+ labelCoords = [
2600
+ port.coords[0] - labelConfiguration.fontSize,
2601
+ port.coords[1] + labelConfiguration.fontSize
2602
+ ];
2603
+ break;
2604
+ case Side.Right:
2605
+ labelCoords = [
2606
+ port.coords[0] + labelConfiguration.fontSize,
2607
+ port.coords[1] - labelConfiguration.fontSize
2608
+ ];
2609
+ break;
2610
+ default:
2611
+ labelCoords = port.coords;
2437
2612
  }
2613
+ this.model.fields.new(port, labelCoords, labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, labelConfiguration.fontSize, labelConfiguration.fontSize, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, '', labelConfiguration.editable, portLabelIds && portLabelIds.length > i
2614
+ ? portLabelIds[i]
2615
+ : undefined);
2438
2616
  }
2439
- break;
2440
- case Side.Right:
2441
- for (const section of this.sections) {
2442
- if (section.coords[0] === point[0]) {
2443
- section.stretch(direction, distance);
2444
- }
2445
- else if (section.coords[0] > point[0]) {
2446
- section.move([section.coords[0] + distance, section.coords[1]]);
2447
- }
2448
- }
2449
- break;
2450
- case Side.Top:
2451
- for (const section of this.sections) {
2452
- if (section.coords[1] === point[1]) {
2453
- section.stretch(direction, distance);
2454
- }
2455
- else if (section.coords[1] < point[1]) {
2456
- section.move([section.coords[0], section.coords[1] - distance]);
2457
- }
2617
+ }
2618
+ }
2619
+ // add section label
2620
+ if (node.type.sections?.label) {
2621
+ const labelConfiguration = {
2622
+ ...DIAGRAM_FIELD_DEFAULTS,
2623
+ ...node.type.sections.label
2624
+ };
2625
+ this.model.fields.new(section, [
2626
+ section.coords[0] + labelConfiguration.margin,
2627
+ section.coords[1] + labelConfiguration.margin
2628
+ ], labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, section.width - labelConfiguration.margin * 2, section.height - labelConfiguration.margin * 2, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, '', labelConfiguration.editable, id);
2629
+ }
2630
+ return section;
2631
+ }
2632
+ remove(id) {
2633
+ const section = this.get(id);
2634
+ if (section) {
2635
+ // remove all ports
2636
+ while (section.ports.length > 0) {
2637
+ this.model.ports.remove(section.ports[0].id);
2638
+ }
2639
+ // remove label
2640
+ if (section.label) {
2641
+ this.model.fields.remove(section.label.id);
2642
+ }
2643
+ // remove from root element
2644
+ if (section.node) {
2645
+ removeIfExists(section.node.sections, section);
2646
+ }
2647
+ // remove from set of sections
2648
+ super.remove(id);
2649
+ // remove from canvas
2650
+ section.updateInView();
2651
+ }
2652
+ }
2653
+ filter(threshold) {
2654
+ return this.entities.filter((e) => {
2655
+ if (threshold) {
2656
+ const node = e.node;
2657
+ if (node) {
2658
+ return node.type.priority >= threshold;
2458
2659
  }
2459
- break;
2460
- case Side.Left:
2461
- for (const section of this.sections) {
2462
- if (section.coords[0] === point[0]) {
2463
- section.stretch(direction, distance);
2464
- }
2465
- else if (section.coords[0] < point[0]) {
2466
- section.move([section.coords[0] - distance, section.coords[1]]);
2467
- }
2660
+ return false;
2661
+ }
2662
+ return true;
2663
+ });
2664
+ }
2665
+ find(threshold) {
2666
+ return this.entities.find((e) => {
2667
+ if (threshold) {
2668
+ const node = e.node;
2669
+ if (node) {
2670
+ return node.type.priority >= threshold;
2468
2671
  }
2469
- break;
2470
- }
2471
- this.stretch(direction, distance);
2672
+ return false;
2673
+ }
2674
+ return true;
2675
+ });
2472
2676
  }
2473
2677
  }
2474
2678
 
2475
2679
  let idTicker$2 = 0;
2476
- const DIAGRAM_SECTION_DEFAULTS = {
2477
- sectionsX: 1,
2478
- sectionsY: 1,
2680
+ const DIAGRAM_NODE_LOOK_DEFAULTS = {
2681
+ lookType: 'shaped-look',
2682
+ shape: ClosedShape.Rectangle,
2683
+ color: '#FFFFFF',
2684
+ borderColor: '#000000',
2685
+ selectedColor: '#FFFFFF',
2686
+ selectedBorderColor: '#000000'
2687
+ };
2688
+ const DIAGRAM_NODE_TYPE_DEFAULTS = {
2689
+ name: '',
2690
+ defaultWidth: 0,
2691
+ defaultHeight: 0,
2479
2692
  minWidth: 0,
2480
2693
  minHeight: 0,
2481
- margin: 0,
2694
+ resizableX: false,
2695
+ resizableY: false,
2482
2696
  label: null,
2483
2697
  ports: [],
2484
- look: DIAGRAM_LOOK_DEFAULTS
2698
+ sections: null,
2699
+ look: DIAGRAM_NODE_LOOK_DEFAULTS,
2700
+ isUnique: false,
2701
+ priority: 0,
2702
+ properties: []
2485
2703
  };
2486
- class DiagramSection extends DiagramElement {
2704
+ class DiagramNodeType {
2705
+ constructor(options) {
2706
+ const values = {
2707
+ ...DIAGRAM_NODE_TYPE_DEFAULTS,
2708
+ ...options
2709
+ };
2710
+ this.id = values.id;
2711
+ this.name = values.name;
2712
+ this.defaultWidth = values.defaultWidth;
2713
+ this.defaultHeight = values.defaultHeight;
2714
+ this.minWidth = values.minWidth;
2715
+ this.minHeight = values.minHeight;
2716
+ this.resizableX = values.resizableX;
2717
+ this.resizableY = values.resizableY;
2718
+ this.label = values.label;
2719
+ this.ports = values.ports;
2720
+ this.sections = values.sections;
2721
+ this.look = values.look;
2722
+ this.isUnique = values.isUnique;
2723
+ this.priority = values.priority;
2724
+ this.propertySet = new PropertySet(options?.properties || []);
2725
+ }
2726
+ }
2727
+ class DiagramNode extends DiagramElement {
2487
2728
  get name() {
2488
2729
  return this.label?.text || '';
2489
2730
  }
@@ -2493,26 +2734,29 @@ class DiagramSection extends DiagramElement {
2493
2734
  this.label.updateInView();
2494
2735
  }
2495
2736
  }
2496
- constructor(model, node, coords, width, height, id) {
2737
+ constructor(model, type, coords = [0, 0], id) {
2497
2738
  let uniqueId;
2498
- if (id !== undefined && model.getNode(id) === undefined) {
2739
+ if (id !== undefined && model.nodes.get(id) === undefined) {
2499
2740
  uniqueId = id;
2500
2741
  }
2501
2742
  else {
2502
2743
  do {
2503
- uniqueId = `diagram-section-${++idTicker$2}`;
2504
- } while (model.getNode(uniqueId) !== undefined);
2744
+ uniqueId = `diagram-node-${++idTicker$2}`;
2745
+ } while (model.nodes.get(uniqueId) !== undefined);
2505
2746
  }
2506
2747
  super(model, uniqueId);
2748
+ this.sections = [];
2507
2749
  this.ports = [];
2508
- this.node = node;
2750
+ this.type = type;
2751
+ this.valueSet = new ValueSet(type.propertySet, this);
2752
+ this.originalData = {};
2509
2753
  this.coords = coords;
2510
- this.width = width;
2511
- this.height = height;
2754
+ this.width = type.defaultWidth;
2755
+ this.height = type.defaultHeight;
2512
2756
  }
2513
2757
  updateInView() {
2514
2758
  if (this.model.canvas && this.model.renderToCanvas) {
2515
- this.model.canvas.updateSectionsInView(this.id);
2759
+ this.model.canvas.updateNodesInView(this.id);
2516
2760
  }
2517
2761
  }
2518
2762
  getClosestPortToPoint(coords) {
@@ -2559,12 +2803,36 @@ class DiagramSection extends DiagramElement {
2559
2803
  }
2560
2804
  return result;
2561
2805
  }
2806
+ getAdjacentNodes() {
2807
+ const result = [];
2808
+ for (const port of this.ports) {
2809
+ for (const incomingConnection of port.incomingConnections) {
2810
+ const otherNode = incomingConnection.start?.getNode();
2811
+ if (otherNode) {
2812
+ result.push(otherNode);
2813
+ }
2814
+ }
2815
+ for (const outgoingConnection of port.outgoingConnections) {
2816
+ const otherNode = outgoingConnection.end?.getNode();
2817
+ if (otherNode) {
2818
+ result.push(otherNode);
2819
+ }
2820
+ }
2821
+ }
2822
+ return result;
2823
+ }
2562
2824
  move(coords) {
2563
2825
  const coordDifferences = [
2564
2826
  coords[0] - this.coords[0],
2565
2827
  coords[1] - this.coords[1]
2566
2828
  ];
2567
2829
  this.coords = coords;
2830
+ for (const section of this.sections) {
2831
+ section.move([
2832
+ section.coords[0] + coordDifferences[0],
2833
+ section.coords[1] + coordDifferences[1]
2834
+ ]);
2835
+ }
2568
2836
  for (const port of this.ports) {
2569
2837
  port.move([
2570
2838
  port.coords[0] + coordDifferences[0],
@@ -2589,49 +2857,29 @@ class DiagramSection extends DiagramElement {
2589
2857
  case Side.Left:
2590
2858
  newCoordsX = [oldCoordsX[0] - distance, oldCoordsX[1]];
2591
2859
  newCoordsY = [oldCoordsY[0], oldCoordsY[1]];
2592
- if (newCoordsX[1] - newCoordsX[0] <
2593
- (this.node?.type?.sections?.minWidth ||
2594
- DIAGRAM_SECTION_DEFAULTS.minWidth)) {
2595
- newCoordsX[0] =
2596
- newCoordsX[1] -
2597
- (this.node?.type?.sections?.minWidth ||
2598
- DIAGRAM_SECTION_DEFAULTS.minWidth);
2860
+ if (newCoordsX[1] - newCoordsX[0] < this.type.minWidth) {
2861
+ newCoordsX[0] = newCoordsX[1] - this.type.minWidth;
2599
2862
  }
2600
2863
  break;
2601
2864
  case Side.Top:
2602
2865
  newCoordsX = [oldCoordsX[0], oldCoordsX[1]];
2603
2866
  newCoordsY = [oldCoordsY[0] - distance, oldCoordsY[1]];
2604
- if (newCoordsY[1] - newCoordsY[0] <
2605
- (this.node?.type?.sections?.minHeight ||
2606
- DIAGRAM_SECTION_DEFAULTS.minHeight)) {
2607
- newCoordsY[0] =
2608
- newCoordsY[1] -
2609
- (this.node?.type?.sections?.minHeight ||
2610
- DIAGRAM_SECTION_DEFAULTS.minHeight);
2867
+ if (newCoordsY[1] - newCoordsY[0] < this.type.minHeight) {
2868
+ newCoordsY[0] = newCoordsY[1] - this.type.minHeight;
2611
2869
  }
2612
2870
  break;
2613
2871
  case Side.Right:
2614
2872
  newCoordsX = [oldCoordsX[0], oldCoordsX[1] + distance];
2615
2873
  newCoordsY = [oldCoordsY[0], oldCoordsY[1]];
2616
- if (newCoordsX[1] - newCoordsX[0] <
2617
- (this.node?.type?.sections?.minWidth ||
2618
- DIAGRAM_SECTION_DEFAULTS.minWidth)) {
2619
- newCoordsX[1] =
2620
- newCoordsX[0] +
2621
- (this.node?.type?.sections?.minWidth ||
2622
- DIAGRAM_SECTION_DEFAULTS.minWidth);
2874
+ if (newCoordsX[1] - newCoordsX[0] < this.type.minWidth) {
2875
+ newCoordsX[1] = newCoordsX[0] + this.type.minWidth;
2623
2876
  }
2624
2877
  break;
2625
2878
  case Side.Bottom:
2626
2879
  newCoordsX = [oldCoordsX[0], oldCoordsX[1]];
2627
2880
  newCoordsY = [oldCoordsY[0], oldCoordsY[1] + distance];
2628
- if (newCoordsY[1] - newCoordsY[0] <
2629
- (this.node?.type?.sections?.minHeight ||
2630
- DIAGRAM_SECTION_DEFAULTS.minHeight)) {
2631
- newCoordsY[1] =
2632
- newCoordsY[0] +
2633
- (this.node?.type?.sections?.minHeight ||
2634
- DIAGRAM_SECTION_DEFAULTS.minHeight);
2881
+ if (newCoordsY[1] - newCoordsY[0] < this.type.minHeight) {
2882
+ newCoordsY[1] = newCoordsY[0] + this.type.minHeight;
2635
2883
  }
2636
2884
  break;
2637
2885
  }
@@ -2643,261 +2891,71 @@ class DiagramSection extends DiagramElement {
2643
2891
  }
2644
2892
  if (this.label) {
2645
2893
  this.label.coords = [
2646
- this.coords[0] + (this.node?.type?.sections?.label?.margin || 0),
2647
- this.coords[1] + (this.node?.type?.sections?.label?.margin || 0)
2894
+ this.coords[0] + (this.type.label?.margin || 0),
2895
+ this.coords[1] + (this.type.label?.margin || 0)
2648
2896
  ];
2649
- (this.label.width =
2650
- this.width - (this.node?.type?.sections?.label?.margin || 0) * 2),
2651
- (this.label.height =
2652
- this.height - (this.node?.type?.sections?.label?.margin || 0) * 2);
2897
+ (this.label.width = this.width - (this.type.label?.margin || 0) * 2),
2898
+ (this.label.height = this.height - (this.type.label?.margin || 0) * 2);
2653
2899
  }
2900
+ // we ignore this.sections, the stretching of a node with sections is handled in the stretchSections method
2654
2901
  this.updateInView();
2655
2902
  }
2656
- }
2657
-
2658
- let idTicker$1 = 0;
2659
- const DIAGRAM_PORT_DEFAULTS = {
2660
- radius: 12,
2661
- highlightedColor: 'cyan',
2662
- selectedColor: 'violet'
2663
- };
2664
- class DiagramPort extends DiagramElement {
2665
- constructor(model, rootElement, coords, direction, id) {
2666
- let uniqueId;
2667
- if (id !== undefined && model.getPort(id) === undefined) {
2668
- uniqueId = id;
2669
- }
2670
- else {
2671
- do {
2672
- uniqueId = `diagram-port-${++idTicker$1}`;
2673
- } while (model.getPort(uniqueId) !== undefined);
2903
+ stretchSections(direction, distance, point) {
2904
+ switch (direction) {
2905
+ case Side.Bottom:
2906
+ for (const section of this.sections) {
2907
+ if (section.coords[1] === point[1]) {
2908
+ section.stretch(direction, distance);
2909
+ }
2910
+ else if (section.coords[1] > point[1]) {
2911
+ section.move([section.coords[0], section.coords[1] + distance]);
2912
+ }
2913
+ }
2914
+ break;
2915
+ case Side.Right:
2916
+ for (const section of this.sections) {
2917
+ if (section.coords[0] === point[0]) {
2918
+ section.stretch(direction, distance);
2919
+ }
2920
+ else if (section.coords[0] > point[0]) {
2921
+ section.move([section.coords[0] + distance, section.coords[1]]);
2922
+ }
2923
+ }
2924
+ break;
2925
+ case Side.Top:
2926
+ for (const section of this.sections) {
2927
+ if (section.coords[1] === point[1]) {
2928
+ section.stretch(direction, distance);
2929
+ }
2930
+ else if (section.coords[1] < point[1]) {
2931
+ section.move([section.coords[0], section.coords[1] - distance]);
2932
+ }
2933
+ }
2934
+ break;
2935
+ case Side.Left:
2936
+ for (const section of this.sections) {
2937
+ if (section.coords[0] === point[0]) {
2938
+ section.stretch(direction, distance);
2939
+ }
2940
+ else if (section.coords[0] < point[0]) {
2941
+ section.move([section.coords[0] - distance, section.coords[1]]);
2942
+ }
2943
+ }
2944
+ break;
2674
2945
  }
2675
- super(model, uniqueId);
2676
- this.outgoingConnections = [];
2677
- this.incomingConnections = [];
2678
- this.rootElement = rootElement;
2679
- this.coords = coords;
2680
- this.direction = direction;
2946
+ this.stretch(direction, distance);
2681
2947
  }
2682
- updateInView() {
2683
- if (this.model.canvas && this.model.renderToCanvas) {
2684
- this.model.canvas.updatePortsInView(this.id);
2685
- }
2948
+ }
2949
+ class DiagramNodeSet extends DiagramEntitySet {
2950
+ constructor(model) {
2951
+ super();
2952
+ this.types = new DiagramEntitySet();
2953
+ this.model = model;
2686
2954
  }
2687
- startConnection(connection) {
2688
- this.outgoingConnections.push(connection);
2689
- }
2690
- finishConnection(connection) {
2691
- this.incomingConnections.push(connection);
2692
- }
2693
- getNode() {
2694
- if (this.rootElement instanceof DiagramNode) {
2695
- return this.rootElement;
2696
- }
2697
- else if (this.rootElement instanceof DiagramSection) {
2698
- return this.rootElement.node;
2699
- }
2700
- return undefined;
2701
- }
2702
- move(coords) {
2703
- const coordDifferences = [
2704
- coords[0] - this.coords[0],
2705
- coords[1] - this.coords[1]
2706
- ];
2707
- this.coords = coords;
2708
- for (const connection of this.outgoingConnections) {
2709
- connection.setStart(this);
2710
- }
2711
- for (const connection of this.incomingConnections) {
2712
- connection.setEnd(this);
2713
- }
2714
- if (this.label) {
2715
- this.label.move([
2716
- this.label.coords[0] + coordDifferences[0],
2717
- this.label.coords[1] + coordDifferences[1]
2718
- ]);
2719
- }
2720
- this.updateInView();
2721
- }
2722
- distanceTo(coords) {
2723
- return distanceBetweenPoints(this.coords, coords);
2724
- }
2725
- }
2726
-
2727
- let idTicker = 0;
2728
- const DIAGRAM_FIELD_DEFAULTS = {
2729
- editable: true,
2730
- fontSize: 0,
2731
- margin: 0,
2732
- padding: 0,
2733
- fontFamily: null,
2734
- color: '#000000',
2735
- selectedColor: '#000000',
2736
- horizontalAlign: HorizontalAlign.Center,
2737
- verticalAlign: VerticalAlign.Center
2738
- };
2739
- class DiagramField extends DiagramElement {
2740
- get text() {
2741
- return this._text;
2742
- }
2743
- set text(value) {
2744
- if (value.trim() === '') {
2745
- value = this.defaultText;
2746
- }
2747
- this._text = value;
2748
- this.select()?.text(value);
2749
- }
2750
- constructor(model, rootElement, coords, width, height, fontSize, fontFamily, color, selectedColor, horizontalAlign, verticalAlign, text, editable, id) {
2751
- let uniqueId;
2752
- if (id !== undefined && model.getField(id) === undefined) {
2753
- uniqueId = id;
2754
- }
2755
- else {
2756
- do {
2757
- uniqueId = `diagram-field-${++idTicker}`;
2758
- } while (model.getField(uniqueId) !== undefined);
2759
- }
2760
- super(model, uniqueId);
2761
- this.rootElement = rootElement;
2762
- this.coords = coords;
2763
- this.width = width;
2764
- this.height = height;
2765
- this.fontSize = fontSize;
2766
- this.fontFamily = fontFamily;
2767
- this.color = color;
2768
- this.selectedColor = selectedColor;
2769
- this.horizontalAlign = horizontalAlign;
2770
- this.verticalAlign = verticalAlign;
2771
- this.defaultText = text;
2772
- this._text = text;
2773
- this.editable = editable;
2774
- }
2775
- updateInView() {
2776
- if (this.model.canvas && this.model.renderToCanvas) {
2777
- this.model.canvas.updateFieldsInView(this.id);
2778
- }
2779
- }
2780
- move(coords) {
2781
- this.coords = coords;
2782
- this.updateInView();
2783
- }
2784
- getClosestNode() {
2785
- if (this.rootElement instanceof DiagramNode) {
2786
- return this.rootElement;
2787
- }
2788
- else if (this.rootElement instanceof DiagramPort) {
2789
- return this.rootElement.getNode();
2790
- }
2791
- else if (this.rootElement instanceof DiagramConnection) {
2792
- return (this.rootElement.start?.getNode() || this.rootElement.end?.getNode());
2793
- }
2794
- return undefined;
2795
- }
2796
- }
2797
-
2798
- class DiagramModel {
2799
- // canvas attribute accesors
2800
- // added so that the valueSet can access canvas attributes and change them
2801
- get layoutFormat() {
2802
- return this.canvas?.layoutFormat;
2803
- }
2804
- set layoutFormat(value) {
2805
- if (this.canvas) {
2806
- this.canvas.layoutFormat = value;
2807
- }
2808
- }
2809
- constructor(canvas, id, name, description, type, properties = []) {
2810
- this.renderToCanvas = true;
2811
- this.nodeTypes = [];
2812
- this.connectionTypes = [];
2813
- this.nodes = [];
2814
- this.sections = [];
2815
- this.ports = [];
2816
- this.connections = [];
2817
- this.fields = [];
2818
- this.canvas = canvas;
2819
- this.id = id;
2820
- this.name = name;
2821
- this.description = description;
2822
- this.type = type;
2823
- this.createdAt = new Date();
2824
- this.updatedAt = new Date();
2825
- this.valueSet = new ValueSet(new PropertySet(properties), this);
2826
- }
2827
- enableRenderToCanvas() {
2828
- this.renderToCanvas = true;
2829
- this.canvas?.updateModelInView();
2830
- }
2831
- disableRenderToCanvas() {
2832
- this.renderToCanvas = false;
2833
- }
2834
- /**
2835
- * Deletes everything in this diagram.
2836
- */
2837
- clear() {
2838
- this.id = undefined;
2839
- this.name = '';
2840
- this.description = undefined;
2841
- this.nodes = [];
2842
- this.ports = [];
2843
- this.connections = [];
2844
- this.fields = [];
2845
- this.createdAt = new Date();
2846
- this.updatedAt = new Date();
2847
- this.valueSet.resetValues();
2848
- if (this.renderToCanvas) {
2849
- this.canvas?.cancelAllUserActions();
2850
- this.canvas?.updateModelInView();
2851
- }
2852
- }
2853
- getElement(id) {
2854
- return (this.getNode(id) ||
2855
- this.getSection(id) ||
2856
- this.getPort(id) ||
2857
- this.getConnection(id) ||
2858
- this.getField(id));
2859
- }
2860
- deleteElement(element) {
2861
- if (element instanceof DiagramNode) {
2862
- this.deleteNode(element);
2863
- }
2864
- else if (element instanceof DiagramSection) {
2865
- this.deleteSection(element);
2866
- }
2867
- else if (element instanceof DiagramPort) {
2868
- this.deletePort(element);
2869
- }
2870
- else if (element instanceof DiagramConnection) {
2871
- this.deleteConnection(element);
2872
- }
2873
- else if (element instanceof DiagramField) {
2874
- this.deleteField(element);
2875
- }
2876
- }
2877
- getNodeType(name) {
2878
- return this.nodeTypes.find((e) => e.id === name);
2879
- }
2880
- getConnectionType(name) {
2881
- return this.connectionTypes.find((e) => e.id === name);
2882
- }
2883
- getNode(id) {
2884
- return this.nodes.find((e) => e.id === id);
2885
- }
2886
- getNodes(threshold) {
2887
- if (threshold === undefined) {
2888
- return this.nodes;
2889
- }
2890
- else {
2891
- return this.nodes.filter((e) => e.type.priority >= threshold);
2892
- }
2893
- }
2894
- getNodesOfType(type) {
2895
- return this.nodes.filter((e) => e.type.id === type);
2896
- }
2897
- addNode(type, coords, id, sectionIds, sectionPortIds, sectionPortLabelIds, portIds, portLabelIds, labelId) {
2898
- const newNode = new DiagramNode(this, type, coords, id);
2899
- this.nodes.push(newNode);
2900
- newNode.updateInView();
2955
+ new(type, coords, id, sectionIds, sectionPortIds, sectionPortLabelIds, portIds, portLabelIds, labelId) {
2956
+ const node = new DiagramNode(this.model, type, coords, id);
2957
+ super.add(node);
2958
+ node.updateInView();
2901
2959
  // add node sections
2902
2960
  if (type.sections !== null &&
2903
2961
  (type.sections.sectionsX || 0) > 0 &&
@@ -2909,16 +2967,16 @@ class DiagramModel {
2909
2967
  const sectionsX = sectionConfiguration.sectionsX;
2910
2968
  const sectionsY = sectionConfiguration.sectionsY;
2911
2969
  const margin = sectionConfiguration.margin;
2912
- const widthPerSection = (newNode.width - margin * (sectionsX + 1)) / sectionsX;
2913
- const heightPerSection = (newNode.height - margin * (sectionsY + 1)) / sectionsY;
2970
+ const widthPerSection = (node.width - margin * (sectionsX + 1)) / sectionsX;
2971
+ const heightPerSection = (node.height - margin * (sectionsY + 1)) / sectionsY;
2914
2972
  let sectionCount = 0;
2915
2973
  for (let j = 0; j < sectionsY; ++j) {
2916
2974
  for (let i = 0; i < sectionsX; ++i) {
2917
2975
  const coords = [
2918
- newNode.coords[0] + margin + i * (widthPerSection + margin),
2919
- newNode.coords[1] + margin + j * (heightPerSection + margin)
2976
+ node.coords[0] + margin + i * (widthPerSection + margin),
2977
+ node.coords[1] + margin + j * (heightPerSection + margin)
2920
2978
  ];
2921
- this.addSection(newNode, coords, widthPerSection, heightPerSection, sectionIds && sectionIds.length > sectionCount
2979
+ this.model.sections.new(node, coords, widthPerSection, heightPerSection, sectionIds && sectionIds.length > sectionCount
2922
2980
  ? sectionIds[sectionCount]
2923
2981
  : undefined, sectionPortIds && sectionPortIds.length > sectionCount
2924
2982
  ? sectionPortIds[sectionCount]
@@ -2933,9 +2991,9 @@ class DiagramModel {
2933
2991
  if (type.ports.length > 0) {
2934
2992
  for (let i = 0; i < type.ports.length; ++i) {
2935
2993
  const portConfig = type.ports[i];
2936
- const newPort = this.addPort(newNode, [
2937
- newNode.coords[0] + portConfig.coords[0],
2938
- newNode.coords[1] + portConfig.coords[1]
2994
+ const port = this.model.ports.new(node, [
2995
+ node.coords[0] + portConfig.coords[0],
2996
+ node.coords[1] + portConfig.coords[1]
2939
2997
  ], portConfig.direction, portIds && portIds.length > i ? portIds[i] : undefined);
2940
2998
  if (portConfig.label) {
2941
2999
  const labelConfiguration = {
@@ -2943,33 +3001,32 @@ class DiagramModel {
2943
3001
  ...portConfig.label
2944
3002
  };
2945
3003
  let labelCoords;
2946
- switch (newPort.direction) {
3004
+ switch (port.direction) {
2947
3005
  case Side.Top:
2948
3006
  case Side.Left:
2949
3007
  labelCoords = [
2950
- newPort.coords[0] - labelConfiguration.fontSize,
2951
- newPort.coords[1] - labelConfiguration.fontSize
3008
+ port.coords[0] - labelConfiguration.fontSize,
3009
+ port.coords[1] - labelConfiguration.fontSize
2952
3010
  ];
2953
3011
  break;
2954
3012
  case Side.Bottom:
2955
3013
  labelCoords = [
2956
- newPort.coords[0] - labelConfiguration.fontSize,
2957
- newPort.coords[1] + labelConfiguration.fontSize
3014
+ port.coords[0] - labelConfiguration.fontSize,
3015
+ port.coords[1] + labelConfiguration.fontSize
2958
3016
  ];
2959
3017
  break;
2960
3018
  case Side.Right:
2961
3019
  labelCoords = [
2962
- newPort.coords[0] + labelConfiguration.fontSize,
2963
- newPort.coords[1] - labelConfiguration.fontSize
3020
+ port.coords[0] + labelConfiguration.fontSize,
3021
+ port.coords[1] - labelConfiguration.fontSize
2964
3022
  ];
2965
3023
  break;
2966
3024
  default:
2967
- labelCoords = newPort.coords;
3025
+ labelCoords = port.coords;
2968
3026
  }
2969
- const newField = this.addField(newPort, labelCoords, labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, labelConfiguration.fontSize, labelConfiguration.fontSize, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, '', labelConfiguration.editable, portLabelIds && portLabelIds.length > i
3027
+ this.model.fields.new(port, labelCoords, labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, labelConfiguration.fontSize, labelConfiguration.fontSize, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, '', labelConfiguration.editable, portLabelIds && portLabelIds.length > i
2970
3028
  ? portLabelIds[i]
2971
3029
  : undefined);
2972
- newPort.label = newField;
2973
3030
  }
2974
3031
  }
2975
3032
  }
@@ -2979,242 +3036,353 @@ class DiagramModel {
2979
3036
  ...DIAGRAM_FIELD_DEFAULTS,
2980
3037
  ...type.label
2981
3038
  };
2982
- const newField = this.addField(newNode, [
2983
- newNode.coords[0] + labelConfiguration.margin,
2984
- newNode.coords[1] + labelConfiguration.margin
2985
- ], labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, newNode.width - labelConfiguration.margin * 2, newNode.height - labelConfiguration.margin * 2, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, '', labelConfiguration.editable, labelId);
2986
- newNode.label = newField;
3039
+ this.model.fields.new(node, [
3040
+ node.coords[0] + labelConfiguration.margin,
3041
+ node.coords[1] + labelConfiguration.margin
3042
+ ], labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, node.width - labelConfiguration.margin * 2, node.height - labelConfiguration.margin * 2, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, '', labelConfiguration.editable, labelId);
2987
3043
  }
2988
- return newNode;
3044
+ return node;
2989
3045
  }
2990
- deleteNode(node) {
2991
- // remove all ports
2992
- while (node.sections.length > 0) {
2993
- this.deleteSection(node.sections[0]);
3046
+ remove(id) {
3047
+ const node = this.get(id);
3048
+ if (node) {
3049
+ // remove all sections
3050
+ while (node.sections.length > 0) {
3051
+ this.model.sections.remove(node.sections[0].id);
3052
+ }
3053
+ // remove all ports
3054
+ while (node.ports.length > 0) {
3055
+ this.model.ports.remove(node.ports[0].id);
3056
+ }
3057
+ // remove label
3058
+ if (node.label) {
3059
+ this.model.fields.remove(node.label.id);
3060
+ }
3061
+ // remove from set of nodes
3062
+ super.remove(id);
3063
+ // remove from canvas
3064
+ node.updateInView();
2994
3065
  }
2995
- while (node.ports.length > 0) {
2996
- this.deletePort(node.ports[0]);
3066
+ }
3067
+ filter(type, threshold) {
3068
+ return this.entities.filter((e) => (type ? e.type.id === type : true) &&
3069
+ (threshold ? e.type.priority >= threshold : true));
3070
+ }
3071
+ find(type, threshold) {
3072
+ return this.entities.find((e) => (type ? e.type.id === type : true) &&
3073
+ (threshold ? e.type.priority >= threshold : true));
3074
+ }
3075
+ }
3076
+
3077
+ let idTicker$1 = 0;
3078
+ const DIAGRAM_PORT_DEFAULTS = {
3079
+ radius: 12,
3080
+ highlightedColor: 'cyan',
3081
+ selectedColor: 'violet'
3082
+ };
3083
+ class DiagramPort extends DiagramElement {
3084
+ constructor(model, rootElement, coords, direction, id) {
3085
+ let uniqueId;
3086
+ if (id !== undefined && model.ports.get(id) === undefined) {
3087
+ uniqueId = id;
2997
3088
  }
2998
- if (node.label) {
2999
- this.deleteField(node.label);
3089
+ else {
3090
+ do {
3091
+ uniqueId = `diagram-port-${++idTicker$1}`;
3092
+ } while (model.ports.get(uniqueId) !== undefined);
3093
+ }
3094
+ super(model, uniqueId);
3095
+ this.outgoingConnections = [];
3096
+ this.incomingConnections = [];
3097
+ this.rootElement = rootElement;
3098
+ this.coords = coords;
3099
+ this.direction = direction;
3100
+ }
3101
+ updateInView() {
3102
+ if (this.model.canvas && this.model.renderToCanvas) {
3103
+ this.model.canvas.updatePortsInView(this.id);
3000
3104
  }
3001
- // remove from list of nodes
3002
- removeIfExists(this.nodes, node);
3003
- node.updateInView();
3004
3105
  }
3005
- hasNodeOfType(type) {
3006
- return this.nodes.find((e) => e.type.id === type) !== undefined;
3106
+ startConnection(connection) {
3107
+ this.outgoingConnections.push(connection);
3007
3108
  }
3008
- getSection(id) {
3009
- return this.sections.find((e) => e.id === id);
3109
+ finishConnection(connection) {
3110
+ this.incomingConnections.push(connection);
3010
3111
  }
3011
- getSections(threshold) {
3012
- if (threshold === undefined) {
3013
- return this.sections;
3112
+ getNode() {
3113
+ if (this.rootElement instanceof DiagramNode) {
3114
+ return this.rootElement;
3014
3115
  }
3015
- else {
3016
- return this.sections.filter((e) => (e.node?.type?.priority || Number.NEGATIVE_INFINITY) >= threshold);
3116
+ else if (this.rootElement instanceof DiagramSection) {
3117
+ return this.rootElement.node;
3017
3118
  }
3119
+ return undefined;
3018
3120
  }
3019
- addSection(node, coords, width, height, id, portIds, portLabelIds) {
3020
- const newSection = new DiagramSection(this, node, coords, width, height, id);
3021
- this.sections.push(newSection);
3022
- newSection.updateInView();
3023
- // add to node
3024
- node.sections.push(newSection);
3025
- node.updateInView();
3026
- // add section ports
3027
- if (node.type.sections?.ports && node.type.sections.ports.length > 0) {
3028
- for (let i = 0; i < node.type.sections.ports.length; ++i) {
3029
- const portConfig = node.type.sections.ports[i];
3030
- const newPort = this.addPort(newSection, [
3031
- newSection.coords[0] + portConfig.coords[0],
3032
- newSection.coords[1] + portConfig.coords[1]
3033
- ], portConfig.direction, portIds && portIds.length > i ? portIds[i] : undefined);
3034
- if (portConfig.label) {
3035
- const labelConfiguration = {
3036
- ...DIAGRAM_FIELD_DEFAULTS,
3037
- ...portConfig.label
3038
- };
3039
- let labelCoords;
3040
- switch (newPort.direction) {
3041
- case Side.Top:
3042
- case Side.Left:
3043
- labelCoords = [
3044
- newPort.coords[0] - labelConfiguration.fontSize,
3045
- newPort.coords[1] - labelConfiguration.fontSize
3046
- ];
3047
- break;
3048
- case Side.Bottom:
3049
- labelCoords = [
3050
- newPort.coords[0] - labelConfiguration.fontSize,
3051
- newPort.coords[1] + labelConfiguration.fontSize
3052
- ];
3053
- break;
3054
- case Side.Right:
3055
- labelCoords = [
3056
- newPort.coords[0] + labelConfiguration.fontSize,
3057
- newPort.coords[1] - labelConfiguration.fontSize
3058
- ];
3059
- break;
3060
- default:
3061
- labelCoords = newPort.coords;
3062
- }
3063
- const newField = this.addField(newPort, labelCoords, labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, labelConfiguration.fontSize, labelConfiguration.fontSize, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, '', labelConfiguration.editable, portLabelIds && portLabelIds.length > i
3064
- ? portLabelIds[i]
3065
- : undefined);
3066
- newPort.label = newField;
3067
- }
3068
- }
3121
+ move(coords) {
3122
+ const coordDifferences = [
3123
+ coords[0] - this.coords[0],
3124
+ coords[1] - this.coords[1]
3125
+ ];
3126
+ this.coords = coords;
3127
+ for (const connection of this.outgoingConnections) {
3128
+ connection.setStart(this);
3069
3129
  }
3070
- // add section label
3071
- if (node.type.sections?.label) {
3072
- const labelConfiguration = {
3073
- ...DIAGRAM_FIELD_DEFAULTS,
3074
- ...node.type.sections.label
3075
- };
3076
- const newField = this.addField(newSection, [
3077
- newSection.coords[0] + labelConfiguration.margin,
3078
- newSection.coords[1] + labelConfiguration.margin
3079
- ], labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, newSection.width - labelConfiguration.margin * 2, newSection.height - labelConfiguration.margin * 2, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, '', labelConfiguration.editable, id);
3080
- newSection.label = newField;
3130
+ for (const connection of this.incomingConnections) {
3131
+ connection.setEnd(this);
3132
+ }
3133
+ if (this.label) {
3134
+ this.label.move([
3135
+ this.label.coords[0] + coordDifferences[0],
3136
+ this.label.coords[1] + coordDifferences[1]
3137
+ ]);
3081
3138
  }
3082
- return newSection;
3139
+ this.updateInView();
3140
+ }
3141
+ distanceTo(coords) {
3142
+ return distanceBetweenPoints(this.coords, coords);
3143
+ }
3144
+ }
3145
+ class DiagramPortSet extends DiagramEntitySet {
3146
+ constructor(model) {
3147
+ super();
3148
+ this.model = model;
3149
+ }
3150
+ new(rootElement, coords, direction, id) {
3151
+ const port = new DiagramPort(this.model, rootElement, coords, direction, id);
3152
+ super.add(port);
3153
+ port.updateInView();
3154
+ // add this port to its root element
3155
+ if (rootElement !== undefined) {
3156
+ rootElement.ports.push(port);
3157
+ }
3158
+ return port;
3159
+ }
3160
+ remove(id) {
3161
+ const port = this.get(id);
3162
+ if (port) {
3163
+ // remove all connections
3164
+ while (port.outgoingConnections.length > 0) {
3165
+ this.model.connections.remove(port.outgoingConnections[0].id);
3166
+ }
3167
+ while (port.incomingConnections.length > 0) {
3168
+ this.model.connections.remove(port.incomingConnections[0].id);
3169
+ }
3170
+ // remove label
3171
+ if (port.label) {
3172
+ this.model.fields.remove(port.label.id);
3173
+ }
3174
+ // remove from root element
3175
+ if (port.rootElement instanceof DiagramNode ||
3176
+ port.rootElement instanceof DiagramSection) {
3177
+ removeIfExists(port.rootElement.ports, port);
3178
+ }
3179
+ // remove from set of ports
3180
+ super.remove(id);
3181
+ // remove from canvas
3182
+ port.updateInView();
3183
+ }
3184
+ }
3185
+ filter(threshold) {
3186
+ return this.entities.filter((e) => {
3187
+ if (threshold) {
3188
+ const node = e.getNode();
3189
+ if (node) {
3190
+ return node !== undefined && node.type.priority >= threshold;
3191
+ }
3192
+ return false;
3193
+ }
3194
+ return true;
3195
+ });
3196
+ }
3197
+ find(threshold) {
3198
+ return this.entities.find((e) => {
3199
+ if (threshold) {
3200
+ const node = e.getNode();
3201
+ if (node) {
3202
+ return node !== undefined && node.type.priority >= threshold;
3203
+ }
3204
+ return false;
3205
+ }
3206
+ return true;
3207
+ });
3208
+ }
3209
+ }
3210
+
3211
+ let idTicker = 0;
3212
+ const DIAGRAM_FIELD_DEFAULTS = {
3213
+ editable: true,
3214
+ fontSize: 0,
3215
+ margin: 0,
3216
+ padding: 0,
3217
+ fontFamily: null,
3218
+ color: '#000000',
3219
+ selectedColor: '#000000',
3220
+ horizontalAlign: HorizontalAlign.Center,
3221
+ verticalAlign: VerticalAlign.Center
3222
+ };
3223
+ class DiagramField extends DiagramElement {
3224
+ get text() {
3225
+ return this._text;
3083
3226
  }
3084
- deleteSection(section) {
3085
- // remove all ports
3086
- while (section.ports.length > 0) {
3087
- this.deletePort(section.ports[0]);
3088
- }
3089
- if (section.label) {
3090
- this.deleteField(section.label);
3091
- }
3092
- // remove from list of sections
3093
- if (section.node) {
3094
- removeIfExists(section.node?.sections, section);
3227
+ set text(value) {
3228
+ if (value.trim() === '') {
3229
+ value = this.defaultText;
3095
3230
  }
3096
- removeIfExists(this.sections, section);
3097
- section.updateInView();
3098
- }
3099
- getPort(id) {
3100
- return this.ports.find((e) => e.id === id);
3231
+ this._text = value;
3232
+ this.select()?.text(value);
3101
3233
  }
3102
- getPorts(threshold) {
3103
- if (threshold === undefined) {
3104
- return this.ports;
3234
+ constructor(model, rootElement, coords, width, height, fontSize, fontFamily, color, selectedColor, horizontalAlign, verticalAlign, text, editable, id) {
3235
+ let uniqueId;
3236
+ if (id !== undefined && model.fields.get(id) === undefined) {
3237
+ uniqueId = id;
3105
3238
  }
3106
3239
  else {
3107
- return this.ports.filter((e) => (e.getNode()?.type?.priority || Number.NEGATIVE_INFINITY) >= threshold);
3240
+ do {
3241
+ uniqueId = `diagram-field-${++idTicker}`;
3242
+ } while (model.fields.get(uniqueId) !== undefined);
3108
3243
  }
3244
+ super(model, uniqueId);
3245
+ this.rootElement = rootElement;
3246
+ this.coords = coords;
3247
+ this.width = width;
3248
+ this.height = height;
3249
+ this.fontSize = fontSize;
3250
+ this.fontFamily = fontFamily;
3251
+ this.color = color;
3252
+ this.selectedColor = selectedColor;
3253
+ this.horizontalAlign = horizontalAlign;
3254
+ this.verticalAlign = verticalAlign;
3255
+ this.defaultText = text;
3256
+ this._text = text;
3257
+ this.editable = editable;
3109
3258
  }
3110
- addPort(rootElement, coords, direction, id) {
3111
- const newPort = new DiagramPort(this, rootElement, coords, direction, id);
3112
- this.ports.push(newPort);
3113
- if (rootElement instanceof DiagramNode) {
3114
- rootElement.ports.push(newPort);
3115
- }
3116
- else if (rootElement instanceof DiagramSection) {
3117
- rootElement.ports.push(newPort);
3259
+ updateInView() {
3260
+ if (this.model.canvas && this.model.renderToCanvas) {
3261
+ this.model.canvas.updateFieldsInView(this.id);
3118
3262
  }
3119
- newPort.updateInView();
3120
- return newPort;
3121
3263
  }
3122
- deletePort(port) {
3123
- // remove all connections
3124
- while (port.outgoingConnections.length > 0) {
3125
- this.deleteConnection(port.outgoingConnections[0]);
3126
- }
3127
- while (port.incomingConnections.length > 0) {
3128
- this.deleteConnection(port.incomingConnections[0]);
3129
- }
3130
- // remove label
3131
- if (port.label) {
3132
- this.deleteField(port.label);
3264
+ move(coords) {
3265
+ this.coords = coords;
3266
+ this.updateInView();
3267
+ }
3268
+ getClosestNode() {
3269
+ if (this.rootElement instanceof DiagramNode) {
3270
+ return this.rootElement;
3133
3271
  }
3134
- // remove from lists of ports
3135
- if (port.rootElement instanceof DiagramNode) {
3136
- removeIfExists(port.rootElement.ports, port);
3272
+ else if (this.rootElement instanceof DiagramPort) {
3273
+ return this.rootElement.getNode();
3137
3274
  }
3138
- else if (port.rootElement instanceof DiagramSection) {
3139
- removeIfExists(port.rootElement.ports, port);
3275
+ else if (this.rootElement instanceof DiagramConnection) {
3276
+ return (this.rootElement.start?.getNode() || this.rootElement.end?.getNode());
3140
3277
  }
3141
- removeIfExists(this.ports, port);
3142
- // remove from canvas
3143
- port.updateInView();
3278
+ return undefined;
3144
3279
  }
3145
- getConnection(id) {
3146
- return this.connections.find((e) => e.id === id);
3280
+ }
3281
+ class DiagramFieldSet extends DiagramEntitySet {
3282
+ constructor(model) {
3283
+ super();
3284
+ this.model = model;
3147
3285
  }
3148
- getConnections(threshold) {
3149
- if (threshold === undefined) {
3150
- return this.connections;
3286
+ new(rootElement, coords, fontSize, fontFamily, color, selectedColor, width, height, horizontalAlign, verticalAlign, text, editable, id) {
3287
+ const field = new DiagramField(this.model, rootElement, coords, width, height, fontSize, fontFamily, color, selectedColor, horizontalAlign, verticalAlign, text, editable, id);
3288
+ super.add(field);
3289
+ field.updateInView();
3290
+ // add this field to its root element
3291
+ if (rootElement !== undefined) {
3292
+ rootElement.label = field;
3151
3293
  }
3152
- else {
3153
- return this.connections.filter((e) => (e.start?.getNode()?.type?.priority || Number.NEGATIVE_INFINITY) >=
3154
- threshold &&
3155
- (e.end?.getNode()?.type?.priority || Number.NEGATIVE_INFINITY) >=
3156
- threshold);
3157
- }
3158
- }
3159
- getConnectionsOfType(type) {
3160
- return this.connections.filter((e) => e.type.id === type);
3161
- }
3162
- addConnection(type, start, end, id) {
3163
- const newConnection = new DiagramConnection(this, type, start, end, id);
3164
- this.connections.push(newConnection);
3165
- newConnection.updateInView();
3166
- return newConnection;
3167
- }
3168
- deleteConnection(connection) {
3169
- // remove port labels
3170
- if (connection.start?.label) {
3171
- this.deleteField(connection.start.label);
3172
- }
3173
- if (connection.end?.label) {
3174
- this.deleteField(connection.end.label);
3175
- }
3176
- // remove from lists of connections
3177
- removeIfExists(connection.start?.outgoingConnections || [], connection);
3178
- removeIfExists(connection.end?.incomingConnections || [], connection);
3179
- removeIfExists(this.connections, connection);
3180
- // remove from canvas
3181
- connection.updateInView();
3294
+ return field;
3182
3295
  }
3183
- getField(id) {
3184
- return this.fields.find((e) => e.id === id);
3185
- }
3186
- getFields(threshold) {
3187
- if (threshold === undefined) {
3188
- return this.fields;
3296
+ remove(id) {
3297
+ const field = this.get(id);
3298
+ if (field) {
3299
+ // remove from root element
3300
+ if (field.rootElement instanceof DiagramNode ||
3301
+ field.rootElement instanceof DiagramSection ||
3302
+ field.rootElement instanceof DiagramPort) {
3303
+ if (field.rootElement.label === field) {
3304
+ field.rootElement.label = undefined;
3305
+ }
3306
+ }
3307
+ // remove from set of fields
3308
+ super.remove(id);
3309
+ // remove from canvas
3310
+ field.updateInView();
3189
3311
  }
3190
- else {
3191
- return this.fields.filter((e) => {
3312
+ }
3313
+ filter(threshold) {
3314
+ return this.entities.filter((e) => {
3315
+ if (threshold) {
3192
3316
  const node = e.getClosestNode();
3193
3317
  return node !== undefined && node.type.priority >= threshold;
3194
- });
3195
- }
3196
- }
3197
- addField(rootElement, coords, fontSize, fontFamily, color, selectedColor, width, height, horizontalAlign, verticalAlign, text, editable, id) {
3198
- const newField = new DiagramField(this, rootElement, coords, width, height, fontSize, fontFamily, color, selectedColor, horizontalAlign, verticalAlign, text, editable, id);
3199
- this.fields.push(newField);
3200
- newField.updateInView();
3201
- return newField;
3318
+ }
3319
+ return true;
3320
+ });
3202
3321
  }
3203
- deleteField(field) {
3204
- // remove from lists of fields
3205
- removeIfExists(this.fields, field);
3206
- if (field.rootElement instanceof DiagramNode) {
3207
- if (field.rootElement.label === field) {
3208
- field.rootElement.label = undefined;
3322
+ find(threshold) {
3323
+ return this.entities.find((e) => {
3324
+ if (threshold) {
3325
+ const node = e.getClosestNode();
3326
+ return node !== undefined && node.type.priority >= threshold;
3209
3327
  }
3328
+ return true;
3329
+ });
3330
+ }
3331
+ }
3332
+
3333
+ class DiagramModel {
3334
+ // canvas attribute accesors
3335
+ // added so that the valueSet can access canvas attributes and change them
3336
+ get layoutFormat() {
3337
+ return this.canvas?.layoutFormat;
3338
+ }
3339
+ set layoutFormat(value) {
3340
+ if (this.canvas) {
3341
+ this.canvas.layoutFormat = value;
3210
3342
  }
3211
- else if (field.rootElement instanceof DiagramPort) {
3212
- if (field.rootElement.label === field) {
3213
- field.rootElement.label = undefined;
3214
- }
3343
+ }
3344
+ constructor(canvas, id, name, description, type, properties = []) {
3345
+ this.renderToCanvas = true;
3346
+ this.nodes = new DiagramNodeSet(this);
3347
+ this.sections = new DiagramSectionSet(this);
3348
+ this.ports = new DiagramPortSet(this);
3349
+ this.connections = new DiagramConnectionSet(this);
3350
+ this.fields = new DiagramFieldSet(this);
3351
+ this.canvas = canvas;
3352
+ this.id = id;
3353
+ this.name = name;
3354
+ this.description = description;
3355
+ this.type = type;
3356
+ this.createdAt = new Date();
3357
+ this.updatedAt = new Date();
3358
+ this.valueSet = new ValueSet(new PropertySet(properties), this);
3359
+ }
3360
+ enableRenderToCanvas() {
3361
+ this.renderToCanvas = true;
3362
+ this.canvas?.updateModelInView();
3363
+ }
3364
+ disableRenderToCanvas() {
3365
+ this.renderToCanvas = false;
3366
+ }
3367
+ /**
3368
+ * Deletes everything in this diagram.
3369
+ */
3370
+ clear() {
3371
+ this.id = undefined;
3372
+ this.name = '';
3373
+ this.description = undefined;
3374
+ this.createdAt = new Date();
3375
+ this.updatedAt = new Date();
3376
+ this.nodes.clear();
3377
+ this.sections.clear();
3378
+ this.ports.clear();
3379
+ this.connections.clear();
3380
+ this.fields.clear();
3381
+ this.valueSet.resetValues();
3382
+ if (this.renderToCanvas) {
3383
+ this.canvas?.cancelAllUserActions();
3384
+ this.canvas?.updateModelInView();
3215
3385
  }
3216
- // remove from canvas
3217
- field.updateInView();
3218
3386
  }
3219
3387
  }
3220
3388
 
@@ -3222,6 +3390,10 @@ class DiagramModel {
3222
3390
  * Thickness of the invisible path around a connection used to make it easier to click on, in pixels.
3223
3391
  */
3224
3392
  const CONNECTION_PATH_BOX_THICKNESS = 12;
3393
+ /**
3394
+ * Thickness of the resizer line used to resize nodes and sections on drag, in pixels.
3395
+ */
3396
+ const RESIZER_THICKNESS = 6;
3225
3397
  /**
3226
3398
  * Text to display as the title of the property editor when editing this diagram's properties.
3227
3399
  * @see PropertyEditorComponent
@@ -3255,6 +3427,7 @@ class DiagramCanvas {
3255
3427
  this.priorityThreshold = config.defaultPriorityThreshold;
3256
3428
  this.priorityThresholds = config.priorityThresholds || [];
3257
3429
  this.layoutFormat = config.layoutFormat;
3430
+ this.userActions = config.userActions || {};
3258
3431
  this.validators = [];
3259
3432
  this.actionQueue = new ActionQueue(ACTION_QUEUE_SIZE);
3260
3433
  // load node types
@@ -3264,7 +3437,7 @@ class DiagramCanvas {
3264
3437
  ...config.nodeTypeDefaults,
3265
3438
  ...nodeTypeConfig
3266
3439
  });
3267
- this.model.nodeTypes.push(nodeType);
3440
+ this.model.nodes.types.add(nodeType);
3268
3441
  }
3269
3442
  }
3270
3443
  // load connection types
@@ -3274,11 +3447,11 @@ class DiagramCanvas {
3274
3447
  ...config.connectionTypeDefaults,
3275
3448
  ...connectionTypeConfig
3276
3449
  });
3277
- this.model.connectionTypes.push(connectionType);
3450
+ this.model.connections.types.add(connectionType);
3278
3451
  }
3279
3452
  this.connectionType =
3280
3453
  config.defaultConnection !== undefined
3281
- ? this.model.getConnectionType(config.defaultConnection)
3454
+ ? this.model.connections.types.get(config.defaultConnection)
3282
3455
  : undefined;
3283
3456
  }
3284
3457
  }
@@ -3295,11 +3468,9 @@ class DiagramCanvas {
3295
3468
  this.diagramRoot = d3.select(appendTo).append('div').node();
3296
3469
  d3.select(this.diagramRoot)
3297
3470
  .attr('tabindex', 0) // make element focusable
3298
- .style('position', 'absolute')
3299
3471
  .style('width', '100%')
3300
3472
  .style('height', '100%')
3301
3473
  .append('svg')
3302
- .style('position', 'absolute')
3303
3474
  .style('width', '100%')
3304
3475
  .style('height', '100%');
3305
3476
  d3.select(this.diagramRoot)
@@ -3309,7 +3480,9 @@ class DiagramCanvas {
3309
3480
  d3.select(this.diagramRoot).node()?.focus();
3310
3481
  })
3311
3482
  .on(Events.KeyUp, (event) => {
3312
- if (!event.ctrlKey && event.key === Keys.Delete) {
3483
+ if (!event.ctrlKey &&
3484
+ event.key === Keys.Delete &&
3485
+ this.userActions[DiagramActions.RemoveAction] !== false) {
3313
3486
  // delete selection
3314
3487
  if (this.userSelection.length > 0) {
3315
3488
  const nodesToBeDeleted = [];
@@ -3456,13 +3629,13 @@ class DiagramCanvas {
3456
3629
  // if there are no nodes, we have nothing to do here
3457
3630
  if (this.model.nodes.length > 0) {
3458
3631
  const canvasViewBoundingBox = this.selectCanvasView().select('rect').node().getBBox();
3459
- const minimumX = Math.min(...this.model.nodes.map((n) => n.coords[0]));
3460
- const maximumX = Math.max(...this.model.nodes.map((n) => n.coords[0] + n.width));
3632
+ const minimumX = Math.min(...this.model.nodes.all().map((n) => n.coords[0]));
3633
+ const maximumX = Math.max(...this.model.nodes.all().map((n) => n.coords[0] + n.width));
3461
3634
  const averageX = (minimumX + maximumX) / 2;
3462
3635
  const rangeX = maximumX - minimumX;
3463
3636
  const windowRangeX = canvasViewBoundingBox.width;
3464
- const minimumY = Math.min(...this.model.nodes.map((n) => n.coords[1]));
3465
- const maximumY = Math.max(...this.model.nodes.map((n) => n.coords[1] + n.height));
3637
+ const minimumY = Math.min(...this.model.nodes.all().map((n) => n.coords[1]));
3638
+ const maximumY = Math.max(...this.model.nodes.all().map((n) => n.coords[1] + n.height));
3466
3639
  const averageY = (minimumY + maximumY) / 2;
3467
3640
  const rangeY = maximumY - minimumY;
3468
3641
  const windowRangeY = canvasViewBoundingBox.height;
@@ -3524,7 +3697,7 @@ class DiagramCanvas {
3524
3697
  updateNodesInView(...ids) {
3525
3698
  let updateSelection = this.selectCanvas()
3526
3699
  .selectAll('g.diagram-node')
3527
- .data(this.model.getNodes(this.priorityThreshold), (d) => d.id);
3700
+ .data(this.model.nodes.filter(undefined, this.priorityThreshold), (d) => d.id);
3528
3701
  const exitSelection = updateSelection.exit();
3529
3702
  const enterSelection = updateSelection
3530
3703
  .enter()
@@ -3556,37 +3729,43 @@ class DiagramCanvas {
3556
3729
  .call(d3
3557
3730
  .drag()
3558
3731
  .on(DragEvents.Start, (event, d) => {
3559
- d3.select('body').style('cursor', 'grabbing');
3560
- this.draggingFrom = [event.x, event.y];
3561
- this.currentAction = new MoveNodeAction(this, d.id, d.coords, [0, 0]);
3732
+ if (this.userActions[DiagramActions.MoveNodeAction] !== false) {
3733
+ d3.select('body').style('cursor', 'grabbing');
3734
+ this.draggingFrom = [event.x, event.y];
3735
+ this.currentAction = new MoveNodeAction(this, d.id, d.coords, [0, 0]);
3736
+ }
3562
3737
  })
3563
3738
  .on(DragEvents.Drag, (event, d) => {
3564
- const newNodeCoords = [
3565
- event.x - d.width / 2,
3566
- event.y - d.height / 2
3567
- ];
3568
- d.move(newNodeCoords);
3569
- })
3570
- .on(DragEvents.End, (event, d) => {
3571
- // prevent drag behavior if mouse hasn't moved
3572
- if ((this.draggingFrom[0] !== event.x ||
3573
- this.draggingFrom[1] !== event.y) &&
3574
- this.currentAction instanceof MoveNodeAction) {
3575
- let newNodeCoords = [
3739
+ if (this.userActions[DiagramActions.MoveNodeAction] !== false) {
3740
+ const newNodeCoords = [
3576
3741
  event.x - d.width / 2,
3577
3742
  event.y - d.height / 2
3578
3743
  ];
3579
- if (this.snapToGrid) {
3580
- newNodeCoords = this.getClosestGridPoint(newNodeCoords);
3581
- }
3582
3744
  d.move(newNodeCoords);
3583
- this.currentAction.to = newNodeCoords;
3584
- this.actionQueue.add(this.currentAction);
3585
3745
  }
3586
- else {
3587
- this.currentAction = undefined;
3746
+ })
3747
+ .on(DragEvents.End, (event, d) => {
3748
+ if (this.userActions[DiagramActions.MoveNodeAction] !== false) {
3749
+ // prevent drag behavior if mouse hasn't moved
3750
+ if ((this.draggingFrom[0] !== event.x ||
3751
+ this.draggingFrom[1] !== event.y) &&
3752
+ this.currentAction instanceof MoveNodeAction) {
3753
+ let newNodeCoords = [
3754
+ event.x - d.width / 2,
3755
+ event.y - d.height / 2
3756
+ ];
3757
+ if (this.snapToGrid) {
3758
+ newNodeCoords = this.getClosestGridPoint(newNodeCoords);
3759
+ }
3760
+ d.move(newNodeCoords);
3761
+ this.currentAction.to = newNodeCoords;
3762
+ this.actionQueue.add(this.currentAction);
3763
+ }
3764
+ else {
3765
+ this.currentAction = undefined;
3766
+ }
3767
+ d3.select('body').style('cursor', 'auto');
3588
3768
  }
3589
- d3.select('body').style('cursor', 'auto');
3590
3769
  }));
3591
3770
  enterSelection.filter('.shaped-look').append('path');
3592
3771
  enterSelection
@@ -3643,33 +3822,38 @@ class DiagramCanvas {
3643
3822
  .append('line')
3644
3823
  .attr('class', 'left-resizer')
3645
3824
  .attr('stroke', 'transparent')
3646
- .attr('stroke-width', '5px')
3825
+ .attr('stroke-width', `${RESIZER_THICKNESS}px`)
3647
3826
  .on(Events.MouseOver, (event, d) => {
3648
- if (d.type.resizableX) {
3827
+ if (this.userActions[DiagramActions.StretchNodeAction] !== false &&
3828
+ d.type.resizableX) {
3649
3829
  d3.select('body').style('cursor', 'ew-resize');
3650
3830
  }
3651
3831
  })
3652
3832
  .on(Events.MouseOut, (event, d) => {
3653
- if (d.type.resizableX) {
3833
+ if (this.userActions[DiagramActions.StretchNodeAction] !== false &&
3834
+ d.type.resizableX) {
3654
3835
  d3.select('body').style('cursor', 'auto');
3655
3836
  }
3656
3837
  })
3657
3838
  .call(d3
3658
3839
  .drag()
3659
3840
  .on(DragEvents.Start, (event, d) => {
3660
- if (d.type.resizableX) {
3841
+ if (this.userActions[DiagramActions.StretchNodeAction] !== false &&
3842
+ d.type.resizableX) {
3661
3843
  d3.select('body').style('cursor', 'ew-resize');
3662
3844
  this.currentAction = new StretchNodeAction(this, d.id, Side.Left, d.width, d.width);
3663
3845
  }
3664
3846
  })
3665
3847
  .on(DragEvents.Drag, (event, d) => {
3666
- if (d.type.resizableX) {
3848
+ if (this.userActions[DiagramActions.StretchNodeAction] !== false &&
3849
+ d.type.resizableX) {
3667
3850
  const pointerCoords = this.getPointerLocationRelativeToCanvas(event);
3668
3851
  d.stretch(Side.Left, d.coords[0] - pointerCoords[0]);
3669
3852
  }
3670
3853
  })
3671
3854
  .on(DragEvents.End, (event, d) => {
3672
- if (d.type.resizableX) {
3855
+ if (this.userActions[DiagramActions.StretchNodeAction] !== false &&
3856
+ d.type.resizableX) {
3673
3857
  let pointerCoords = this.getPointerLocationRelativeToCanvas(event);
3674
3858
  if (this.snapToGrid) {
3675
3859
  pointerCoords = this.getClosestGridPoint(pointerCoords);
@@ -3686,33 +3870,38 @@ class DiagramCanvas {
3686
3870
  .append('line')
3687
3871
  .attr('class', 'top-resizer')
3688
3872
  .attr('stroke', 'transparent')
3689
- .attr('stroke-width', '5px')
3873
+ .attr('stroke-width', `${RESIZER_THICKNESS}px`)
3690
3874
  .on(Events.MouseOver, (event, d) => {
3691
- if (d.type.resizableY) {
3875
+ if (this.userActions[DiagramActions.StretchNodeAction] !== false &&
3876
+ d.type.resizableY) {
3692
3877
  d3.select('body').style('cursor', 'ns-resize');
3693
3878
  }
3694
3879
  })
3695
3880
  .on(Events.MouseOut, (event, d) => {
3696
- if (d.type.resizableY) {
3881
+ if (this.userActions[DiagramActions.StretchNodeAction] !== false &&
3882
+ d.type.resizableY) {
3697
3883
  d3.select('body').style('cursor', 'auto');
3698
3884
  }
3699
3885
  })
3700
3886
  .call(d3
3701
3887
  .drag()
3702
3888
  .on(DragEvents.Start, (event, d) => {
3703
- if (d.type.resizableY) {
3889
+ if (this.userActions[DiagramActions.StretchNodeAction] !== false &&
3890
+ d.type.resizableY) {
3704
3891
  d3.select('body').style('cursor', 'ns-resize');
3705
3892
  this.currentAction = new StretchNodeAction(this, d.id, Side.Top, d.height, d.height);
3706
3893
  }
3707
3894
  })
3708
3895
  .on(DragEvents.Drag, (event, d) => {
3709
- if (d.type.resizableY) {
3896
+ if (this.userActions[DiagramActions.StretchNodeAction] !== false &&
3897
+ d.type.resizableY) {
3710
3898
  const pointerCoords = this.getPointerLocationRelativeToCanvas(event);
3711
3899
  d.stretch(Side.Top, d.coords[1] - pointerCoords[1]);
3712
3900
  }
3713
3901
  })
3714
3902
  .on(DragEvents.End, (event, d) => {
3715
- if (d.type.resizableY) {
3903
+ if (this.userActions[DiagramActions.StretchNodeAction] !== false &&
3904
+ d.type.resizableY) {
3716
3905
  let pointerCoords = this.getPointerLocationRelativeToCanvas(event);
3717
3906
  if (this.snapToGrid) {
3718
3907
  pointerCoords = this.getClosestGridPoint(pointerCoords);
@@ -3729,33 +3918,38 @@ class DiagramCanvas {
3729
3918
  .append('line')
3730
3919
  .attr('class', 'right-resizer')
3731
3920
  .attr('stroke', 'transparent')
3732
- .attr('stroke-width', '5px')
3921
+ .attr('stroke-width', `${RESIZER_THICKNESS}px`)
3733
3922
  .on(Events.MouseOver, (event, d) => {
3734
- if (d.type.resizableX) {
3923
+ if (this.userActions[DiagramActions.StretchNodeAction] !== false &&
3924
+ d.type.resizableX) {
3735
3925
  d3.select('body').style('cursor', 'ew-resize');
3736
3926
  }
3737
3927
  })
3738
3928
  .on(Events.MouseOut, (event, d) => {
3739
- if (d.type.resizableX) {
3929
+ if (this.userActions[DiagramActions.StretchNodeAction] !== false &&
3930
+ d.type.resizableX) {
3740
3931
  d3.select('body').style('cursor', 'auto');
3741
3932
  }
3742
3933
  })
3743
3934
  .call(d3
3744
3935
  .drag()
3745
3936
  .on(DragEvents.Start, (event, d) => {
3746
- if (d.type.resizableX) {
3937
+ if (this.userActions[DiagramActions.StretchNodeAction] !== false &&
3938
+ d.type.resizableX) {
3747
3939
  d3.select('body').style('cursor', 'ew-resize');
3748
3940
  this.currentAction = new StretchNodeAction(this, d.id, Side.Right, d.width, d.width);
3749
3941
  }
3750
3942
  })
3751
3943
  .on(DragEvents.Drag, (event, d) => {
3752
- if (d.type.resizableX) {
3944
+ if (this.userActions[DiagramActions.StretchNodeAction] !== false &&
3945
+ d.type.resizableX) {
3753
3946
  const pointerCoords = this.getPointerLocationRelativeToCanvas(event);
3754
3947
  d.stretch(Side.Right, pointerCoords[0] - (d.coords[0] + d.width));
3755
3948
  }
3756
3949
  })
3757
3950
  .on(DragEvents.End, (event, d) => {
3758
- if (d.type.resizableX) {
3951
+ if (this.userActions[DiagramActions.StretchNodeAction] !== false &&
3952
+ d.type.resizableX) {
3759
3953
  let pointerCoords = this.getPointerLocationRelativeToCanvas(event);
3760
3954
  if (this.snapToGrid) {
3761
3955
  pointerCoords = this.getClosestGridPoint(pointerCoords);
@@ -3772,33 +3966,38 @@ class DiagramCanvas {
3772
3966
  .append('line')
3773
3967
  .attr('class', 'bottom-resizer')
3774
3968
  .attr('stroke', 'transparent')
3775
- .attr('stroke-width', '5px')
3969
+ .attr('stroke-width', `${RESIZER_THICKNESS}px`)
3776
3970
  .on(Events.MouseOver, (event, d) => {
3777
- if (d.type.resizableY) {
3971
+ if (this.userActions[DiagramActions.StretchNodeAction] !== false &&
3972
+ d.type.resizableY) {
3778
3973
  d3.select('body').style('cursor', 'ns-resize');
3779
3974
  }
3780
3975
  })
3781
3976
  .on(Events.MouseOut, (event, d) => {
3782
- if (d.type.resizableY) {
3977
+ if (this.userActions[DiagramActions.StretchNodeAction] !== false &&
3978
+ d.type.resizableY) {
3783
3979
  d3.select('body').style('cursor', 'auto');
3784
3980
  }
3785
3981
  })
3786
3982
  .call(d3
3787
3983
  .drag()
3788
3984
  .on(DragEvents.Start, (event, d) => {
3789
- if (d.type.resizableY) {
3985
+ if (this.userActions[DiagramActions.StretchNodeAction] !== false &&
3986
+ d.type.resizableY) {
3790
3987
  d3.select('body').style('cursor', 'ns-resize');
3791
3988
  this.currentAction = new StretchNodeAction(this, d.id, Side.Bottom, d.height, d.height);
3792
3989
  }
3793
3990
  })
3794
3991
  .on(DragEvents.Drag, (event, d) => {
3795
- if (d.type.resizableY) {
3992
+ if (this.userActions[DiagramActions.StretchNodeAction] !== false &&
3993
+ d.type.resizableY) {
3796
3994
  const pointerCoords = this.getPointerLocationRelativeToCanvas(event);
3797
3995
  d.stretch(Side.Bottom, pointerCoords[1] - (d.coords[1] + d.height));
3798
3996
  }
3799
3997
  })
3800
3998
  .on(DragEvents.End, (event, d) => {
3801
- if (d.type.resizableY) {
3999
+ if (this.userActions[DiagramActions.StretchNodeAction] !== false &&
4000
+ d.type.resizableY) {
3802
4001
  let pointerCoords = this.getPointerLocationRelativeToCanvas(event);
3803
4002
  if (this.snapToGrid) {
3804
4003
  pointerCoords = this.getClosestGridPoint(pointerCoords);
@@ -3945,8 +4144,8 @@ class DiagramCanvas {
3945
4144
  mergeSelection
3946
4145
  .filter('.resizable-x')
3947
4146
  .select('line.left-resizer')
3948
- .attr('x1', 0)
3949
- .attr('x2', 0)
4147
+ .attr('x1', RESIZER_THICKNESS / 2)
4148
+ .attr('x2', RESIZER_THICKNESS / 2)
3950
4149
  .attr('y1', 0)
3951
4150
  .attr('y2', (d) => d.height);
3952
4151
  mergeSelection
@@ -3954,13 +4153,13 @@ class DiagramCanvas {
3954
4153
  .select('line.top-resizer')
3955
4154
  .attr('x1', 0)
3956
4155
  .attr('x2', (d) => d.width)
3957
- .attr('y1', 0)
3958
- .attr('y2', 0);
4156
+ .attr('y1', RESIZER_THICKNESS / 2)
4157
+ .attr('y2', RESIZER_THICKNESS / 2);
3959
4158
  mergeSelection
3960
4159
  .filter('.resizable-x')
3961
4160
  .select('line.right-resizer')
3962
- .attr('x1', (d) => d.width)
3963
- .attr('x2', (d) => d.width)
4161
+ .attr('x1', (d) => d.width - RESIZER_THICKNESS / 2)
4162
+ .attr('x2', (d) => d.width - RESIZER_THICKNESS / 2)
3964
4163
  .attr('y1', 0)
3965
4164
  .attr('y2', (d) => d.height);
3966
4165
  mergeSelection
@@ -3968,13 +4167,13 @@ class DiagramCanvas {
3968
4167
  .select('line.bottom-resizer')
3969
4168
  .attr('x1', 0)
3970
4169
  .attr('x2', (d) => d.width)
3971
- .attr('y1', (d) => d.height)
3972
- .attr('y2', (d) => d.height);
4170
+ .attr('y1', (d) => d.height - RESIZER_THICKNESS / 2)
4171
+ .attr('y2', (d) => d.height - RESIZER_THICKNESS / 2);
3973
4172
  }
3974
4173
  updateSectionsInView(...ids) {
3975
4174
  let updateSelection = this.selectCanvas()
3976
4175
  .selectAll('g.diagram-section')
3977
- .data(this.model.getSections(this.priorityThreshold), (d) => d.id);
4176
+ .data(this.model.sections.filter(this.priorityThreshold), (d) => d.id);
3978
4177
  const exitSelection = updateSelection.exit();
3979
4178
  const enterSelection = updateSelection
3980
4179
  .enter()
@@ -4006,40 +4205,46 @@ class DiagramCanvas {
4006
4205
  .call(d3
4007
4206
  .drag()
4008
4207
  .on(DragEvents.Start, (event, d) => {
4009
- const node = d.node;
4010
- d3.select('body').style('cursor', 'grabbing');
4011
- this.draggingFrom = [event.x, event.y];
4012
- this.currentAction = new MoveNodeAction(this, node.id, node.coords, [0, 0]);
4208
+ if (this.userActions[DiagramActions.MoveNodeAction] !== false) {
4209
+ const node = d.node;
4210
+ d3.select('body').style('cursor', 'grabbing');
4211
+ this.draggingFrom = [event.x, event.y];
4212
+ this.currentAction = new MoveNodeAction(this, node.id, node.coords, [0, 0]);
4213
+ }
4013
4214
  })
4014
4215
  .on(DragEvents.Drag, (event, d) => {
4015
- const node = d.node;
4016
- const newNodeCoords = [
4017
- event.x - node.width / 2,
4018
- event.y - node.height / 2
4019
- ];
4020
- node.move(newNodeCoords);
4021
- })
4022
- .on(DragEvents.End, (event, d) => {
4023
- const node = d.node;
4024
- // prevent drag behavior if mouse hasn't moved
4025
- if ((this.draggingFrom[0] !== event.x ||
4026
- this.draggingFrom[1] !== event.y) &&
4027
- this.currentAction instanceof MoveNodeAction) {
4028
- let newNodeCoords = [
4216
+ if (this.userActions[DiagramActions.MoveNodeAction] !== false) {
4217
+ const node = d.node;
4218
+ const newNodeCoords = [
4029
4219
  event.x - node.width / 2,
4030
4220
  event.y - node.height / 2
4031
4221
  ];
4032
- if (this.snapToGrid) {
4033
- newNodeCoords = this.getClosestGridPoint(newNodeCoords);
4034
- }
4035
- d.node?.move(newNodeCoords);
4036
- this.currentAction.to = newNodeCoords;
4037
- this.actionQueue.add(this.currentAction);
4222
+ node.move(newNodeCoords);
4038
4223
  }
4039
- else {
4040
- this.currentAction = undefined;
4224
+ })
4225
+ .on(DragEvents.End, (event, d) => {
4226
+ if (this.userActions[DiagramActions.MoveNodeAction] !== false) {
4227
+ const node = d.node;
4228
+ // prevent drag behavior if mouse hasn't moved
4229
+ if ((this.draggingFrom[0] !== event.x ||
4230
+ this.draggingFrom[1] !== event.y) &&
4231
+ this.currentAction instanceof MoveNodeAction) {
4232
+ let newNodeCoords = [
4233
+ event.x - node.width / 2,
4234
+ event.y - node.height / 2
4235
+ ];
4236
+ if (this.snapToGrid) {
4237
+ newNodeCoords = this.getClosestGridPoint(newNodeCoords);
4238
+ }
4239
+ d.node?.move(newNodeCoords);
4240
+ this.currentAction.to = newNodeCoords;
4241
+ this.actionQueue.add(this.currentAction);
4242
+ }
4243
+ else {
4244
+ this.currentAction = undefined;
4245
+ }
4246
+ d3.select('body').style('cursor', 'auto');
4041
4247
  }
4042
- d3.select('body').style('cursor', 'auto');
4043
4248
  }));
4044
4249
  enterSelection.filter('.shaped-look').append('path');
4045
4250
  enterSelection
@@ -4096,33 +4301,38 @@ class DiagramCanvas {
4096
4301
  .append('line')
4097
4302
  .attr('class', 'left-resizer')
4098
4303
  .attr('stroke', 'transparent')
4099
- .attr('stroke-width', '5px')
4304
+ .attr('stroke-width', `${RESIZER_THICKNESS}px`)
4100
4305
  .on(Events.MouseOver, (event, d) => {
4101
- if (d.node?.type?.resizableX) {
4306
+ if (this.userActions[DiagramActions.StretchSectionAction] !== false &&
4307
+ d.node?.type?.resizableX) {
4102
4308
  d3.select('body').style('cursor', 'ew-resize');
4103
4309
  }
4104
4310
  })
4105
4311
  .on(Events.MouseOut, (event, d) => {
4106
- if (d.node?.type?.resizableX) {
4312
+ if (this.userActions[DiagramActions.StretchSectionAction] !== false &&
4313
+ d.node?.type?.resizableX) {
4107
4314
  d3.select('body').style('cursor', 'auto');
4108
4315
  }
4109
4316
  })
4110
4317
  .call(d3
4111
4318
  .drag()
4112
4319
  .on(DragEvents.Start, (event, d) => {
4113
- if (d.node?.type?.resizableX) {
4320
+ if (this.userActions[DiagramActions.StretchSectionAction] !== false &&
4321
+ d.node?.type?.resizableX) {
4114
4322
  d3.select('body').style('cursor', 'ew-resize');
4115
4323
  this.currentAction = new StretchSectionAction(this, d.id, Side.Left, d.width, d.width);
4116
4324
  }
4117
4325
  })
4118
4326
  .on(DragEvents.Drag, (event, d) => {
4119
- if (d.node?.type?.resizableX) {
4327
+ if (this.userActions[DiagramActions.StretchSectionAction] !== false &&
4328
+ d.node?.type?.resizableX) {
4120
4329
  const pointerCoords = this.getPointerLocationRelativeToCanvas(event);
4121
4330
  d.node.stretchSections(Side.Left, d.coords[0] - pointerCoords[0], d.coords);
4122
4331
  }
4123
4332
  })
4124
4333
  .on(DragEvents.End, (event, d) => {
4125
- if (d.node?.type?.resizableX) {
4334
+ if (this.userActions[DiagramActions.StretchSectionAction] !== false &&
4335
+ d.node?.type?.resizableX) {
4126
4336
  let pointerCoords = this.getPointerLocationRelativeToCanvas(event);
4127
4337
  if (this.snapToGrid) {
4128
4338
  pointerCoords = this.getClosestGridPoint(pointerCoords);
@@ -4139,33 +4349,38 @@ class DiagramCanvas {
4139
4349
  .append('line')
4140
4350
  .attr('class', 'top-resizer')
4141
4351
  .attr('stroke', 'transparent')
4142
- .attr('stroke-width', '5px')
4352
+ .attr('stroke-width', `${RESIZER_THICKNESS}px`)
4143
4353
  .on(Events.MouseOver, (event, d) => {
4144
- if (d.node?.type?.resizableY) {
4354
+ if (this.userActions[DiagramActions.StretchSectionAction] !== false &&
4355
+ d.node?.type?.resizableY) {
4145
4356
  d3.select('body').style('cursor', 'ns-resize');
4146
4357
  }
4147
4358
  })
4148
4359
  .on(Events.MouseOut, (event, d) => {
4149
- if (d.node?.type?.resizableY) {
4360
+ if (this.userActions[DiagramActions.StretchSectionAction] !== false &&
4361
+ d.node?.type?.resizableY) {
4150
4362
  d3.select('body').style('cursor', 'auto');
4151
4363
  }
4152
4364
  })
4153
4365
  .call(d3
4154
4366
  .drag()
4155
4367
  .on(DragEvents.Start, (event, d) => {
4156
- if (d.node?.type?.resizableY) {
4368
+ if (this.userActions[DiagramActions.StretchSectionAction] !== false &&
4369
+ d.node?.type?.resizableY) {
4157
4370
  d3.select('body').style('cursor', 'ns-resize');
4158
4371
  this.currentAction = new StretchSectionAction(this, d.id, Side.Top, d.height, d.height);
4159
4372
  }
4160
4373
  })
4161
4374
  .on(DragEvents.Drag, (event, d) => {
4162
- if (d.node?.type?.resizableY) {
4375
+ if (this.userActions[DiagramActions.StretchSectionAction] !== false &&
4376
+ d.node?.type?.resizableY) {
4163
4377
  const pointerCoords = this.getPointerLocationRelativeToCanvas(event);
4164
4378
  d.node.stretchSections(Side.Top, d.coords[1] - pointerCoords[1], d.coords);
4165
4379
  }
4166
4380
  })
4167
4381
  .on(DragEvents.End, (event, d) => {
4168
- if (d.node?.type?.resizableY) {
4382
+ if (this.userActions[DiagramActions.StretchSectionAction] !== false &&
4383
+ d.node?.type?.resizableY) {
4169
4384
  let pointerCoords = this.getPointerLocationRelativeToCanvas(event);
4170
4385
  if (this.snapToGrid) {
4171
4386
  pointerCoords = this.getClosestGridPoint(pointerCoords);
@@ -4182,33 +4397,38 @@ class DiagramCanvas {
4182
4397
  .append('line')
4183
4398
  .attr('class', 'right-resizer')
4184
4399
  .attr('stroke', 'transparent')
4185
- .attr('stroke-width', '5px')
4400
+ .attr('stroke-width', `${RESIZER_THICKNESS}px`)
4186
4401
  .on(Events.MouseOver, (event, d) => {
4187
- if (d.node?.type?.resizableX) {
4402
+ if (this.userActions[DiagramActions.StretchSectionAction] !== false &&
4403
+ d.node?.type?.resizableX) {
4188
4404
  d3.select('body').style('cursor', 'ew-resize');
4189
4405
  }
4190
4406
  })
4191
4407
  .on(Events.MouseOut, (event, d) => {
4192
- if (d.node?.type?.resizableX) {
4408
+ if (this.userActions[DiagramActions.StretchSectionAction] !== false &&
4409
+ d.node?.type?.resizableX) {
4193
4410
  d3.select('body').style('cursor', 'auto');
4194
4411
  }
4195
4412
  })
4196
4413
  .call(d3
4197
4414
  .drag()
4198
4415
  .on(DragEvents.Start, (event, d) => {
4199
- if (d.node?.type?.resizableX) {
4416
+ if (this.userActions[DiagramActions.StretchSectionAction] !== false &&
4417
+ d.node?.type?.resizableX) {
4200
4418
  d3.select('body').style('cursor', 'ew-resize');
4201
4419
  this.currentAction = new StretchSectionAction(this, d.id, Side.Right, d.width, d.width);
4202
4420
  }
4203
4421
  })
4204
4422
  .on(DragEvents.Drag, (event, d) => {
4205
- if (d.node?.type?.resizableX) {
4423
+ if (this.userActions[DiagramActions.StretchSectionAction] !== false &&
4424
+ d.node?.type?.resizableX) {
4206
4425
  const pointerCoords = this.getPointerLocationRelativeToCanvas(event);
4207
4426
  d.node.stretchSections(Side.Right, pointerCoords[0] - (d.coords[0] + d.width), d.coords);
4208
4427
  }
4209
4428
  })
4210
4429
  .on(DragEvents.End, (event, d) => {
4211
- if (d.node?.type?.resizableX) {
4430
+ if (this.userActions[DiagramActions.StretchSectionAction] !== false &&
4431
+ d.node?.type?.resizableX) {
4212
4432
  let pointerCoords = this.getPointerLocationRelativeToCanvas(event);
4213
4433
  if (this.snapToGrid) {
4214
4434
  pointerCoords = this.getClosestGridPoint(pointerCoords);
@@ -4225,33 +4445,38 @@ class DiagramCanvas {
4225
4445
  .append('line')
4226
4446
  .attr('class', 'bottom-resizer')
4227
4447
  .attr('stroke', 'transparent')
4228
- .attr('stroke-width', '5px')
4448
+ .attr('stroke-width', `${RESIZER_THICKNESS}px`)
4229
4449
  .on(Events.MouseOver, (event, d) => {
4230
- if (d.node?.type?.resizableY) {
4450
+ if (this.userActions[DiagramActions.StretchSectionAction] !== false &&
4451
+ d.node?.type?.resizableY) {
4231
4452
  d3.select('body').style('cursor', 'ns-resize');
4232
4453
  }
4233
4454
  })
4234
4455
  .on(Events.MouseOut, (event, d) => {
4235
- if (d.node?.type?.resizableY) {
4456
+ if (this.userActions[DiagramActions.StretchSectionAction] !== false &&
4457
+ d.node?.type?.resizableY) {
4236
4458
  d3.select('body').style('cursor', 'auto');
4237
4459
  }
4238
4460
  })
4239
4461
  .call(d3
4240
4462
  .drag()
4241
4463
  .on(DragEvents.Start, (event, d) => {
4242
- if (d.node?.type?.resizableY) {
4464
+ if (this.userActions[DiagramActions.StretchSectionAction] !== false &&
4465
+ d.node?.type?.resizableY) {
4243
4466
  d3.select('body').style('cursor', 'ns-resize');
4244
4467
  this.currentAction = new StretchSectionAction(this, d.id, Side.Bottom, d.height, d.height);
4245
4468
  }
4246
4469
  })
4247
4470
  .on(DragEvents.Drag, (event, d) => {
4248
- if (d.node?.type?.resizableY) {
4471
+ if (this.userActions[DiagramActions.StretchSectionAction] !== false &&
4472
+ d.node?.type?.resizableY) {
4249
4473
  const pointerCoords = this.getPointerLocationRelativeToCanvas(event);
4250
4474
  d.node.stretchSections(Side.Bottom, pointerCoords[1] - (d.coords[1] + d.height), d.coords);
4251
4475
  }
4252
4476
  })
4253
4477
  .on(DragEvents.End, (event, d) => {
4254
- if (d.node?.type?.resizableY) {
4478
+ if (this.userActions[DiagramActions.StretchSectionAction] !== false &&
4479
+ d.node?.type?.resizableY) {
4255
4480
  let pointerCoords = this.getPointerLocationRelativeToCanvas(event);
4256
4481
  if (this.snapToGrid) {
4257
4482
  pointerCoords = this.getClosestGridPoint(pointerCoords);
@@ -4427,8 +4652,8 @@ class DiagramCanvas {
4427
4652
  mergeSelection
4428
4653
  .filter('.resizable-x')
4429
4654
  .select('line.left-resizer')
4430
- .attr('x1', 0)
4431
- .attr('x2', 0)
4655
+ .attr('x1', RESIZER_THICKNESS / 2)
4656
+ .attr('x2', RESIZER_THICKNESS / 2)
4432
4657
  .attr('y1', 0)
4433
4658
  .attr('y2', (d) => d.height);
4434
4659
  mergeSelection
@@ -4436,13 +4661,13 @@ class DiagramCanvas {
4436
4661
  .select('line.top-resizer')
4437
4662
  .attr('x1', 0)
4438
4663
  .attr('x2', (d) => d.width)
4439
- .attr('y1', 0)
4440
- .attr('y2', 0);
4664
+ .attr('y1', RESIZER_THICKNESS / 2)
4665
+ .attr('y2', RESIZER_THICKNESS / 2);
4441
4666
  mergeSelection
4442
4667
  .filter('.resizable-x')
4443
4668
  .select('line.right-resizer')
4444
- .attr('x1', (d) => d.width)
4445
- .attr('x2', (d) => d.width)
4669
+ .attr('x1', (d) => d.width - RESIZER_THICKNESS / 2)
4670
+ .attr('x2', (d) => d.width - RESIZER_THICKNESS / 2)
4446
4671
  .attr('y1', 0)
4447
4672
  .attr('y2', (d) => d.height);
4448
4673
  mergeSelection
@@ -4450,13 +4675,13 @@ class DiagramCanvas {
4450
4675
  .select('line.bottom-resizer')
4451
4676
  .attr('x1', 0)
4452
4677
  .attr('x2', (d) => d.width)
4453
- .attr('y1', (d) => d.height)
4454
- .attr('y2', (d) => d.height);
4678
+ .attr('y1', (d) => d.height - RESIZER_THICKNESS / 2)
4679
+ .attr('y2', (d) => d.height - RESIZER_THICKNESS / 2);
4455
4680
  }
4456
4681
  updatePortsInView(...ids) {
4457
4682
  let updateSelection = this.selectCanvas()
4458
4683
  .selectAll('g.diagram-port')
4459
- .data(this.model.getPorts(this.priorityThreshold), (d) => d.id);
4684
+ .data(this.model.ports.filter(this.priorityThreshold), (d) => d.id);
4460
4685
  const exitSelection = updateSelection.exit();
4461
4686
  const enterSelection = updateSelection
4462
4687
  .enter()
@@ -4488,50 +4713,56 @@ class DiagramCanvas {
4488
4713
  .call(d3
4489
4714
  .drag()
4490
4715
  .on(DragEvents.Start, (event, d) => {
4491
- d3.select('body').style('cursor', 'grabbing');
4492
- this.startConnection(d);
4716
+ if (this.userActions[DiagramActions.AddConnectionAction] !== false) {
4717
+ d3.select('body').style('cursor', 'grabbing');
4718
+ this.startConnection(d);
4719
+ }
4493
4720
  })
4494
4721
  .on(DragEvents.Drag, (event) => {
4495
- if (this.unfinishedConnection !== undefined) {
4496
- this.unfinishedConnection.endCoords = [event.x, event.y];
4497
- this.updateConnectionsInView();
4722
+ if (this.userActions[DiagramActions.AddConnectionAction] !== false) {
4723
+ if (this.unfinishedConnection !== undefined) {
4724
+ this.unfinishedConnection.endCoords = [event.x, event.y];
4725
+ this.updateConnectionsInView();
4726
+ }
4498
4727
  }
4499
4728
  })
4500
4729
  .on(DragEvents.End, (event) => {
4501
- d3.select('body').style('cursor', 'auto');
4502
- if (this.mainUserHighlight instanceof DiagramPort) {
4503
- this.finishConnection(this.mainUserHighlight);
4504
- }
4505
- else if (this.mainUserHighlight instanceof DiagramNode ||
4506
- this.mainUserHighlight instanceof DiagramSection ||
4507
- this.mainUserHighlight instanceof DiagramField) {
4508
- let targetRootElement;
4509
- if (this.mainUserHighlight instanceof DiagramNode ||
4510
- this.mainUserHighlight instanceof DiagramSection) {
4511
- targetRootElement = this.mainUserHighlight;
4512
- }
4513
- else if (this.mainUserHighlight.rootElement instanceof DiagramNode ||
4514
- this.mainUserHighlight.rootElement instanceof DiagramSection) {
4515
- targetRootElement = this.mainUserHighlight.rootElement;
4516
- }
4517
- else {
4518
- this.dropConnection();
4519
- return;
4730
+ if (this.userActions[DiagramActions.AddConnectionAction] !== false) {
4731
+ d3.select('body').style('cursor', 'auto');
4732
+ if (this.mainUserHighlight instanceof DiagramPort) {
4733
+ this.finishConnection(this.mainUserHighlight);
4520
4734
  }
4521
- const closestPort = targetRootElement.getClosestPortToPoint([
4522
- event.x,
4523
- event.y
4524
- ]);
4525
- if (closestPort !== undefined) {
4526
- this.finishConnection(closestPort);
4735
+ else if (this.mainUserHighlight instanceof DiagramNode ||
4736
+ this.mainUserHighlight instanceof DiagramSection ||
4737
+ this.mainUserHighlight instanceof DiagramField) {
4738
+ let targetRootElement;
4739
+ if (this.mainUserHighlight instanceof DiagramNode ||
4740
+ this.mainUserHighlight instanceof DiagramSection) {
4741
+ targetRootElement = this.mainUserHighlight;
4742
+ }
4743
+ else if (this.mainUserHighlight.rootElement instanceof DiagramNode ||
4744
+ this.mainUserHighlight.rootElement instanceof DiagramSection) {
4745
+ targetRootElement = this.mainUserHighlight.rootElement;
4746
+ }
4747
+ else {
4748
+ this.dropConnection();
4749
+ return;
4750
+ }
4751
+ const closestPort = targetRootElement.getClosestPortToPoint([
4752
+ event.x,
4753
+ event.y
4754
+ ]);
4755
+ if (closestPort !== undefined) {
4756
+ this.finishConnection(closestPort);
4757
+ }
4758
+ else {
4759
+ this.dropConnection();
4760
+ }
4527
4761
  }
4528
4762
  else {
4529
4763
  this.dropConnection();
4530
4764
  }
4531
4765
  }
4532
- else {
4533
- this.dropConnection();
4534
- }
4535
4766
  }));
4536
4767
  enterSelection.append('circle');
4537
4768
  mergeSelection.attr('transform', (d) => `translate(${d.coords[0]},${d.coords[1]})`);
@@ -4547,7 +4778,7 @@ class DiagramCanvas {
4547
4778
  }
4548
4779
  updateConnectionsInView(...ids) {
4549
4780
  const connectionList = [
4550
- ...this.model.getConnections(this.priorityThreshold)
4781
+ ...this.model.connections.filter(undefined, this.priorityThreshold)
4551
4782
  ];
4552
4783
  if (this.unfinishedConnection) {
4553
4784
  connectionList.push(this.unfinishedConnection);
@@ -4643,7 +4874,7 @@ class DiagramCanvas {
4643
4874
  updateFieldsInView(...ids) {
4644
4875
  let updateSelection = this.selectCanvas()
4645
4876
  .selectAll('foreignObject.diagram-field')
4646
- .data(this.model.getFields(this.priorityThreshold), (d) => d.id);
4877
+ .data(this.model.fields.filter(this.priorityThreshold), (d) => d.id);
4647
4878
  const exitSelection = updateSelection.exit();
4648
4879
  const enterSelection = updateSelection
4649
4880
  .enter()
@@ -4676,7 +4907,8 @@ class DiagramCanvas {
4676
4907
  }
4677
4908
  })
4678
4909
  .on(Events.DoubleClick, (event, d) => {
4679
- if (d.editable) {
4910
+ if (this.userActions[DiagramActions.EditFieldAction] !== false &&
4911
+ d.editable) {
4680
4912
  this.currentAction = new EditFieldAction(this, d.id, d.text, '');
4681
4913
  this.createInputField(d.text, d.coords, d.width, d.height, d.fontSize, d.fontFamily, (text) => {
4682
4914
  d.text = text;
@@ -4694,54 +4926,60 @@ class DiagramCanvas {
4694
4926
  .call(d3
4695
4927
  .drag()
4696
4928
  .on(DragEvents.Start, (event, d) => {
4697
- if (d.rootElement instanceof DiagramNode ||
4698
- d.rootElement instanceof DiagramSection) {
4699
- const node = d.rootElement instanceof DiagramNode
4700
- ? d.rootElement
4701
- : d.rootElement.node;
4702
- d3.select('body').style('cursor', 'grabbing');
4703
- this.draggingFrom = [event.x, event.y];
4704
- this.currentAction = new MoveNodeAction(this, node.id, node.coords, [0, 0]);
4929
+ if (this.userActions[DiagramActions.MoveNodeAction] !== false) {
4930
+ if (d.rootElement instanceof DiagramNode ||
4931
+ d.rootElement instanceof DiagramSection) {
4932
+ const node = d.rootElement instanceof DiagramNode
4933
+ ? d.rootElement
4934
+ : d.rootElement.node;
4935
+ d3.select('body').style('cursor', 'grabbing');
4936
+ this.draggingFrom = [event.x, event.y];
4937
+ this.currentAction = new MoveNodeAction(this, node.id, node.coords, [0, 0]);
4938
+ }
4705
4939
  }
4706
4940
  })
4707
4941
  .on(DragEvents.Drag, (event, d) => {
4708
- if (d.rootElement instanceof DiagramNode ||
4709
- d.rootElement instanceof DiagramSection) {
4710
- const node = d.rootElement instanceof DiagramNode
4711
- ? d.rootElement
4712
- : d.rootElement.node;
4713
- const newNodeCoords = [
4714
- event.x - node.width / 2,
4715
- event.y - node.height / 2
4716
- ];
4717
- node.move(newNodeCoords);
4718
- }
4719
- })
4720
- .on(DragEvents.End, (event, d) => {
4721
- if (d.rootElement instanceof DiagramNode ||
4722
- d.rootElement instanceof DiagramSection) {
4723
- const node = d.rootElement instanceof DiagramNode
4724
- ? d.rootElement
4725
- : d.rootElement.node;
4726
- // prevent drag behavior if mouse hasn't moved
4727
- if ((this.draggingFrom[0] !== event.x ||
4728
- this.draggingFrom[1] !== event.y) &&
4729
- this.currentAction instanceof MoveNodeAction) {
4730
- let newNodeCoords = [
4942
+ if (this.userActions[DiagramActions.MoveNodeAction] !== false) {
4943
+ if (d.rootElement instanceof DiagramNode ||
4944
+ d.rootElement instanceof DiagramSection) {
4945
+ const node = d.rootElement instanceof DiagramNode
4946
+ ? d.rootElement
4947
+ : d.rootElement.node;
4948
+ const newNodeCoords = [
4731
4949
  event.x - node.width / 2,
4732
4950
  event.y - node.height / 2
4733
4951
  ];
4734
- if (this.snapToGrid) {
4735
- newNodeCoords = this.getClosestGridPoint(newNodeCoords);
4736
- }
4737
4952
  node.move(newNodeCoords);
4738
- this.currentAction.to = newNodeCoords;
4739
- this.actionQueue.add(this.currentAction);
4740
4953
  }
4741
- else {
4742
- this.currentAction = undefined;
4954
+ }
4955
+ })
4956
+ .on(DragEvents.End, (event, d) => {
4957
+ if (this.userActions[DiagramActions.MoveNodeAction] !== false) {
4958
+ if (d.rootElement instanceof DiagramNode ||
4959
+ d.rootElement instanceof DiagramSection) {
4960
+ const node = d.rootElement instanceof DiagramNode
4961
+ ? d.rootElement
4962
+ : d.rootElement.node;
4963
+ // prevent drag behavior if mouse hasn't moved
4964
+ if ((this.draggingFrom[0] !== event.x ||
4965
+ this.draggingFrom[1] !== event.y) &&
4966
+ this.currentAction instanceof MoveNodeAction) {
4967
+ let newNodeCoords = [
4968
+ event.x - node.width / 2,
4969
+ event.y - node.height / 2
4970
+ ];
4971
+ if (this.snapToGrid) {
4972
+ newNodeCoords = this.getClosestGridPoint(newNodeCoords);
4973
+ }
4974
+ node.move(newNodeCoords);
4975
+ this.currentAction.to = newNodeCoords;
4976
+ this.actionQueue.add(this.currentAction);
4977
+ }
4978
+ else {
4979
+ this.currentAction = undefined;
4980
+ }
4981
+ d3.select('body').style('cursor', 'auto');
4743
4982
  }
4744
- d3.select('body').style('cursor', 'auto');
4745
4983
  }
4746
4984
  }))
4747
4985
  .append('xhtml:div')
@@ -4979,9 +5217,13 @@ class DiagramCanvas {
4979
5217
  }
4980
5218
  else {
4981
5219
  if (this.guessConnectionType) {
4982
- let differentConnectionType = this.model.connectionTypes.find((t) => t.canStartFromType(port.getNode()?.type?.id || ''));
5220
+ let differentConnectionType = this.model.connections.types
5221
+ .all()
5222
+ .find((t) => t.canStartFromType(port.getNode()?.type?.id || ''));
4983
5223
  if (differentConnectionType === undefined) {
4984
- differentConnectionType = this.model.connectionTypes.find((t) => t.canFinishOnType(port.getNode()?.type?.id || ''));
5224
+ differentConnectionType = this.model.connections.types
5225
+ .all()
5226
+ .find((t) => t.canFinishOnType(port.getNode()?.type?.id || ''));
4985
5227
  }
4986
5228
  if (differentConnectionType !== undefined) {
4987
5229
  this.unfinishedConnection = new DiagramConnection(this.model, differentConnectionType, port, undefined, 'diagram-connection-unfinished');
@@ -5018,10 +5260,15 @@ class DiagramCanvas {
5018
5260
  }
5019
5261
  else {
5020
5262
  if (this.guessConnectionType) {
5021
- let differentConnectionType = this.model.connectionTypes.find((t) => t.canStartFromType(this.unfinishedConnection?.start?.getNode()?.type?.id || '') && t.canFinishOnType(port.getNode()?.type?.id || ''));
5263
+ let differentConnectionType = this.model.connections.types
5264
+ .all()
5265
+ .find((t) => t.canStartFromType(this.unfinishedConnection?.start?.getNode()?.type?.id || '') && t.canFinishOnType(port.getNode()?.type?.id || ''));
5022
5266
  let invertConnection = false;
5023
5267
  if (differentConnectionType === undefined) {
5024
- differentConnectionType = this.model.connectionTypes.find((t) => t.canFinishOnType(this.unfinishedConnection?.start?.getNode()?.type?.id || '') && t.canStartFromType(port.getNode()?.type?.id || ''));
5268
+ differentConnectionType = this.model.connections.types
5269
+ .all()
5270
+ .find((t) => t.canFinishOnType(this.unfinishedConnection?.start?.getNode()?.type?.id ||
5271
+ '') && t.canStartFromType(port.getNode()?.type?.id || ''));
5025
5272
  invertConnection = true;
5026
5273
  }
5027
5274
  if (differentConnectionType !== undefined) {
@@ -5279,10 +5526,10 @@ class CanvasProviderService {
5279
5526
  getCanvas() {
5280
5527
  return this._canvas;
5281
5528
  }
5282
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: CanvasProviderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
5283
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: CanvasProviderService }); }
5529
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: CanvasProviderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
5530
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: CanvasProviderService }); }
5284
5531
  }
5285
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: CanvasProviderService, decorators: [{
5532
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: CanvasProviderService, decorators: [{
5286
5533
  type: Injectable
5287
5534
  }] });
5288
5535
 
@@ -5366,12 +5613,12 @@ class DiagramButtonsComponent {
5366
5613
  redo() {
5367
5614
  this.canvas.actionQueue.redo();
5368
5615
  }
5369
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: DiagramButtonsComponent, deps: [{ token: CanvasProviderService }], target: i0.ɵɵFactoryTarget.Component }); }
5370
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.6", type: DiagramButtonsComponent, isStandalone: true, selector: "daga-diagram-buttons", inputs: { enableFilter: "enableFilter", enableLayout: "enableLayout", enableUndoRedo: "enableUndoRedo", enableZoom: "enableZoom", zoomRate: "zoomRate" }, viewQueries: [{ propertyName: "collapsableButtons", first: true, predicate: ["collapsableButtons"], descendants: true }], ngImport: i0, template: "<div class=\"diagram-buttons\">\n <button *ngIf=\"enableZoom\" class=\"zoom-in\" (click)=\"zoomIn()\">\n <span class=\"tooltip\">Zoom in</span>\n </button>\n <button *ngIf=\"enableZoom\" class=\"zoom-out\" (click)=\"zoomOut()\">\n <span class=\"tooltip\">Zoom out</span>\n </button>\n <div #collapsableButtons class=\"collapsable-buttons collapsed\">\n <button *ngIf=\"enableZoom\" class=\"center\" (click)=\"center()\">\n <span class=\"tooltip\">Fit diagram to screen</span>\n </button>\n <button *ngIf=\"enableUndoRedo\" class=\"undo\" (click)=\"undo()\">\n <span class=\"tooltip\">Undo</span>\n </button>\n <button *ngIf=\"enableUndoRedo\" class=\"redo\" (click)=\"redo()\">\n <span class=\"tooltip\">Redo</span>\n </button>\n <button\n *ngIf=\"enableLayout && canvas.layoutFormat\"\n class=\"layout\"\n (click)=\"layout()\"\n >\n <span class=\"tooltip\">Apply layout</span>\n </button>\n <button\n *ngIf=\"enableFilter && canvas.priorityThresholds.length >= 2\"\n class=\"filter\"\n [class]=\"filterOn ? 'on' : 'off'\"\n (click)=\"filter()\"\n >\n <span class=\"tooltip\">Apply filter</span>\n </button>\n </div>\n <button class=\"more-options\" (click)=\"toggleCollapse()\">\n <span *ngIf=\"!collapsed\" class=\"tooltip\">Less options</span>\n <span *ngIf=\"collapsed\" class=\"tooltip\">More options</span>\n </button>\n</div>\n", styles: [":host{position:absolute;right:1rem;bottom:1rem}.diagram-buttons button{position:relative;display:block;height:3rem;width:3rem;padding:0;border:0;margin-bottom:1rem;background-color:transparent}.diagram-buttons button .tooltip{visibility:hidden;z-index:1;position:absolute;top:.5rem;right:3.5rem;height:2rem;padding:.6rem;border-radius:.25rem;font-size:.8rem;font-weight:500;box-sizing:border-box;white-space:nowrap;color:#fff;background-color:#0009}.diagram-buttons button:hover .tooltip{visibility:visible}.diagram-buttons button.filter.on{background-image:url(/assets/daga/icon/buttons/filter-on.svg)}.diagram-buttons button.filter.on:hover{background-image:url(/assets/daga/icon/buttons/filter-on-hover.svg)}.diagram-buttons button.filter.off{background-image:url(/assets/daga/icon/buttons/filter-off.svg)}.diagram-buttons button.filter.off:hover{background-image:url(/assets/daga/icon/buttons/filter-off-hover.svg)}.diagram-buttons button.layout{background-image:url(/assets/daga/icon/buttons/layout.svg)}.diagram-buttons button.layout:hover{background-image:url(/assets/daga/icon/buttons/layout-hover.svg)}.diagram-buttons button.zoom-in{background-image:url(/assets/daga/icon/buttons/zoom-in.svg)}.diagram-buttons button.zoom-in:hover{background-image:url(/assets/daga/icon/buttons/zoom-in-hover.svg)}.diagram-buttons button.zoom-out{background-image:url(/assets/daga/icon/buttons/zoom-out.svg)}.diagram-buttons button.zoom-out:hover{background-image:url(/assets/daga/icon/buttons/zoom-out-hover.svg)}.diagram-buttons button.center{background-image:url(/assets/daga/icon/buttons/center.svg)}.diagram-buttons button.center:hover{background-image:url(/assets/daga/icon/buttons/center-hover.svg)}.diagram-buttons button.undo{background-image:url(/assets/daga/icon/buttons/undo.svg)}.diagram-buttons button.undo:hover{background-image:url(/assets/daga/icon/buttons/undo-hover.svg)}.diagram-buttons button.redo{background-image:url(/assets/daga/icon/buttons/redo.svg)}.diagram-buttons button.redo:hover{background-image:url(/assets/daga/icon/buttons/redo-hover.svg)}.diagram-buttons button.more-options{background-image:url(/assets/daga/icon/buttons/ellipsis.svg)}.diagram-buttons button.more-options:hover{background-image:url(/assets/daga/icon/buttons/ellipsis-hover.svg)}.diagram-buttons .collapsable-buttons.collapsing{animation-name:collapse-animation;animation-duration:1s;animation-fill-mode:forwards}.diagram-buttons .collapsable-buttons.expanding{animation-name:expand-animation;animation-duration:1s;animation-fill-mode:forwards}.diagram-buttons .collapsable-buttons.collapsed{transform:scaleY(0);height:0}@keyframes collapse-animation{0%{transform:scale(1);transform-origin:0% 0%;height:12rem}to{transform:scaleY(0);transform-origin:0% 0%;height:0}}@keyframes expand-animation{0%{transform:scaleY(0);transform-origin:0% 0%;height:0}to{transform:scale(1);transform-origin:0% 0%;height:12rem}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
5616
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: DiagramButtonsComponent, deps: [{ token: CanvasProviderService }], target: i0.ɵɵFactoryTarget.Component }); }
5617
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.1.2", type: DiagramButtonsComponent, isStandalone: true, selector: "daga-diagram-buttons", inputs: { enableFilter: "enableFilter", enableLayout: "enableLayout", enableUndoRedo: "enableUndoRedo", enableZoom: "enableZoom", zoomRate: "zoomRate" }, viewQueries: [{ propertyName: "collapsableButtons", first: true, predicate: ["collapsableButtons"], descendants: true }], ngImport: i0, template: "<div class=\"diagram-buttons\">\n <button *ngIf=\"enableZoom\" class=\"zoom-in\" (click)=\"zoomIn()\">\n <span class=\"tooltip\">Zoom in</span>\n </button>\n <button *ngIf=\"enableZoom\" class=\"zoom-out\" (click)=\"zoomOut()\">\n <span class=\"tooltip\">Zoom out</span>\n </button>\n <div #collapsableButtons class=\"collapsable-buttons collapsed\">\n <button *ngIf=\"enableZoom\" class=\"center\" (click)=\"center()\">\n <span class=\"tooltip\">Fit diagram to screen</span>\n </button>\n <button *ngIf=\"enableUndoRedo\" class=\"undo\" (click)=\"undo()\">\n <span class=\"tooltip\">Undo</span>\n </button>\n <button *ngIf=\"enableUndoRedo\" class=\"redo\" (click)=\"redo()\">\n <span class=\"tooltip\">Redo</span>\n </button>\n <button\n *ngIf=\"enableLayout && canvas.layoutFormat\"\n class=\"layout\"\n (click)=\"layout()\"\n >\n <span class=\"tooltip\">Apply layout</span>\n </button>\n <button\n *ngIf=\"enableFilter && canvas.priorityThresholds.length >= 2\"\n class=\"filter\"\n [class]=\"filterOn ? 'on' : 'off'\"\n (click)=\"filter()\"\n >\n <span class=\"tooltip\">Apply filter</span>\n </button>\n </div>\n <button class=\"more-options\" (click)=\"toggleCollapse()\">\n <span *ngIf=\"!collapsed\" class=\"tooltip\">Less options</span>\n <span *ngIf=\"collapsed\" class=\"tooltip\">More options</span>\n </button>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
5371
5618
  }
5372
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: DiagramButtonsComponent, decorators: [{
5619
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: DiagramButtonsComponent, decorators: [{
5373
5620
  type: Component,
5374
- args: [{ standalone: true, selector: 'daga-diagram-buttons', imports: [CommonModule], template: "<div class=\"diagram-buttons\">\n <button *ngIf=\"enableZoom\" class=\"zoom-in\" (click)=\"zoomIn()\">\n <span class=\"tooltip\">Zoom in</span>\n </button>\n <button *ngIf=\"enableZoom\" class=\"zoom-out\" (click)=\"zoomOut()\">\n <span class=\"tooltip\">Zoom out</span>\n </button>\n <div #collapsableButtons class=\"collapsable-buttons collapsed\">\n <button *ngIf=\"enableZoom\" class=\"center\" (click)=\"center()\">\n <span class=\"tooltip\">Fit diagram to screen</span>\n </button>\n <button *ngIf=\"enableUndoRedo\" class=\"undo\" (click)=\"undo()\">\n <span class=\"tooltip\">Undo</span>\n </button>\n <button *ngIf=\"enableUndoRedo\" class=\"redo\" (click)=\"redo()\">\n <span class=\"tooltip\">Redo</span>\n </button>\n <button\n *ngIf=\"enableLayout && canvas.layoutFormat\"\n class=\"layout\"\n (click)=\"layout()\"\n >\n <span class=\"tooltip\">Apply layout</span>\n </button>\n <button\n *ngIf=\"enableFilter && canvas.priorityThresholds.length >= 2\"\n class=\"filter\"\n [class]=\"filterOn ? 'on' : 'off'\"\n (click)=\"filter()\"\n >\n <span class=\"tooltip\">Apply filter</span>\n </button>\n </div>\n <button class=\"more-options\" (click)=\"toggleCollapse()\">\n <span *ngIf=\"!collapsed\" class=\"tooltip\">Less options</span>\n <span *ngIf=\"collapsed\" class=\"tooltip\">More options</span>\n </button>\n</div>\n", styles: [":host{position:absolute;right:1rem;bottom:1rem}.diagram-buttons button{position:relative;display:block;height:3rem;width:3rem;padding:0;border:0;margin-bottom:1rem;background-color:transparent}.diagram-buttons button .tooltip{visibility:hidden;z-index:1;position:absolute;top:.5rem;right:3.5rem;height:2rem;padding:.6rem;border-radius:.25rem;font-size:.8rem;font-weight:500;box-sizing:border-box;white-space:nowrap;color:#fff;background-color:#0009}.diagram-buttons button:hover .tooltip{visibility:visible}.diagram-buttons button.filter.on{background-image:url(/assets/daga/icon/buttons/filter-on.svg)}.diagram-buttons button.filter.on:hover{background-image:url(/assets/daga/icon/buttons/filter-on-hover.svg)}.diagram-buttons button.filter.off{background-image:url(/assets/daga/icon/buttons/filter-off.svg)}.diagram-buttons button.filter.off:hover{background-image:url(/assets/daga/icon/buttons/filter-off-hover.svg)}.diagram-buttons button.layout{background-image:url(/assets/daga/icon/buttons/layout.svg)}.diagram-buttons button.layout:hover{background-image:url(/assets/daga/icon/buttons/layout-hover.svg)}.diagram-buttons button.zoom-in{background-image:url(/assets/daga/icon/buttons/zoom-in.svg)}.diagram-buttons button.zoom-in:hover{background-image:url(/assets/daga/icon/buttons/zoom-in-hover.svg)}.diagram-buttons button.zoom-out{background-image:url(/assets/daga/icon/buttons/zoom-out.svg)}.diagram-buttons button.zoom-out:hover{background-image:url(/assets/daga/icon/buttons/zoom-out-hover.svg)}.diagram-buttons button.center{background-image:url(/assets/daga/icon/buttons/center.svg)}.diagram-buttons button.center:hover{background-image:url(/assets/daga/icon/buttons/center-hover.svg)}.diagram-buttons button.undo{background-image:url(/assets/daga/icon/buttons/undo.svg)}.diagram-buttons button.undo:hover{background-image:url(/assets/daga/icon/buttons/undo-hover.svg)}.diagram-buttons button.redo{background-image:url(/assets/daga/icon/buttons/redo.svg)}.diagram-buttons button.redo:hover{background-image:url(/assets/daga/icon/buttons/redo-hover.svg)}.diagram-buttons button.more-options{background-image:url(/assets/daga/icon/buttons/ellipsis.svg)}.diagram-buttons button.more-options:hover{background-image:url(/assets/daga/icon/buttons/ellipsis-hover.svg)}.diagram-buttons .collapsable-buttons.collapsing{animation-name:collapse-animation;animation-duration:1s;animation-fill-mode:forwards}.diagram-buttons .collapsable-buttons.expanding{animation-name:expand-animation;animation-duration:1s;animation-fill-mode:forwards}.diagram-buttons .collapsable-buttons.collapsed{transform:scaleY(0);height:0}@keyframes collapse-animation{0%{transform:scale(1);transform-origin:0% 0%;height:12rem}to{transform:scaleY(0);transform-origin:0% 0%;height:0}}@keyframes expand-animation{0%{transform:scaleY(0);transform-origin:0% 0%;height:0}to{transform:scale(1);transform-origin:0% 0%;height:12rem}}\n"] }]
5621
+ args: [{ standalone: true, selector: 'daga-diagram-buttons', imports: [CommonModule], template: "<div class=\"diagram-buttons\">\n <button *ngIf=\"enableZoom\" class=\"zoom-in\" (click)=\"zoomIn()\">\n <span class=\"tooltip\">Zoom in</span>\n </button>\n <button *ngIf=\"enableZoom\" class=\"zoom-out\" (click)=\"zoomOut()\">\n <span class=\"tooltip\">Zoom out</span>\n </button>\n <div #collapsableButtons class=\"collapsable-buttons collapsed\">\n <button *ngIf=\"enableZoom\" class=\"center\" (click)=\"center()\">\n <span class=\"tooltip\">Fit diagram to screen</span>\n </button>\n <button *ngIf=\"enableUndoRedo\" class=\"undo\" (click)=\"undo()\">\n <span class=\"tooltip\">Undo</span>\n </button>\n <button *ngIf=\"enableUndoRedo\" class=\"redo\" (click)=\"redo()\">\n <span class=\"tooltip\">Redo</span>\n </button>\n <button\n *ngIf=\"enableLayout && canvas.layoutFormat\"\n class=\"layout\"\n (click)=\"layout()\"\n >\n <span class=\"tooltip\">Apply layout</span>\n </button>\n <button\n *ngIf=\"enableFilter && canvas.priorityThresholds.length >= 2\"\n class=\"filter\"\n [class]=\"filterOn ? 'on' : 'off'\"\n (click)=\"filter()\"\n >\n <span class=\"tooltip\">Apply filter</span>\n </button>\n </div>\n <button class=\"more-options\" (click)=\"toggleCollapse()\">\n <span *ngIf=\"!collapsed\" class=\"tooltip\">Less options</span>\n <span *ngIf=\"collapsed\" class=\"tooltip\">More options</span>\n </button>\n</div>\n" }]
5375
5622
  }], ctorParameters: () => [{ type: CanvasProviderService }], propDecorators: { collapsableButtons: [{
5376
5623
  type: ViewChild,
5377
5624
  args: ['collapsableButtons']
@@ -5415,7 +5662,8 @@ class ErrorsComponent {
5415
5662
  }
5416
5663
  showError(error) {
5417
5664
  if (error.elementId && error.propertyNames) {
5418
- this.canvas.setPropertyEditorSelection(this.canvas.model.getElement(error.elementId));
5665
+ this.canvas.setPropertyEditorSelection(this.canvas.model.nodes.get(error.elementId) ||
5666
+ this.canvas.model.connections.get(error.elementId));
5419
5667
  this.canvas.parentComponent.propertyEditor?.highlightProperty(...error.propertyNames);
5420
5668
  }
5421
5669
  else if (!error.elementId && error.propertyNames) {
@@ -5424,12 +5672,12 @@ class ErrorsComponent {
5424
5672
  }
5425
5673
  // TODO: IF ERROR IS IN AN ELEMENT BUT NOT IN A SPECIFIC PROPERTY, WE COULD HIGHLIGHT THE ELEMENT
5426
5674
  }
5427
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: ErrorsComponent, deps: [{ token: CanvasProviderService }], target: i0.ɵɵFactoryTarget.Component }); }
5428
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.6", type: ErrorsComponent, isStandalone: true, selector: "daga-errors", viewQueries: [{ propertyName: "errorsContainer", first: true, predicate: ["errors"], descendants: true }], ngImport: i0, template: "<div #errorsContainer class=\"errors\">\n <div\n *ngIf=\"errors.length === 0\"\n class=\"errors-summary no-errors prevent-user-select\"\n >\n <span>No errors found</span>\n </div>\n <div\n *ngIf=\"errors.length > 0\"\n class=\"errors-summary with-errors prevent-user-select\"\n >\n <span>{{ errors.length }} errors found</span>\n <div class=\"collapse-button-container\">\n <daga-collapse-button\n [collapsableSelector]=\"errorsContainer\"\n [collapsableAdditionalSelector]=\"'.error-panel'\"\n [direction]=\"Side.Top\"\n [rule]=\"'display'\"\n [collapsedValue]=\"'none'\"\n [visibleValue]=\"'block'\"\n />\n </div>\n </div>\n <div *ngIf=\"errors.length > 0\" class=\"error-panel\">\n <ol>\n <li\n *ngFor=\"let error of errors; index as i\"\n (click)=\"showError(error)\"\n [innerHTML]=\"error.message\"\n ></li>\n </ol>\n </div>\n</div>\n", styles: [":host{left:2rem;bottom:0;position:absolute;width:calc(100% - 8rem)}.errors-summary{position:absolute;right:2rem;top:-2rem;height:2rem;border-top-left-radius:.5rem;border-top-right-radius:.5rem;display:flex;flex-direction:row;align-items:center}.errors-summary.no-errors{background-color:var(--panel-secondary-color);color:var(--font-color)}.errors-summary.with-errors{background-color:#e64545;color:#fff}.errors-summary span{flex:1 0 auto;padding:.5rem}.errors-summary .collapse-button-container{flex:0 0 auto;padding-left:.5rem;padding-right:.5rem;border-top-left-radius:.5rem;border-top-right-radius:.5rem;background-color:var(--error-color)}.errors-summary .collapse-button-container daga-collapse-button{filter:brightness(10)}.error-panel{width:100%;max-height:12rem;border-top-left-radius:.5rem;border-top-right-radius:.5rem;padding:.5rem;background-color:var(--font-color);color:#fff;overflow:auto}.error-panel ol{counter-reset:count;list-style:decimal;padding:0;padding-left:5rem;margin:0;font-size:.95rem}.error-panel ol li{counter-increment:count;cursor:pointer;padding-bottom:.25rem}.error-panel ol li:hover{text-decoration:underline}.error-panel ol li::marker{content:\"ERROR \" counters(count,\".\",decimal-leading-zero) \" \";font-family:var(--monospace-font-family);font-size:.9rem;font-weight:400;color:#ffffffbf}.error-panel ol li b{font-weight:700}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: CollapseButtonComponent, selector: "daga-collapse-button", inputs: ["collapsableSelector", "collapsableAdditionalSelector", "collapsed", "disabled", "direction", "rule", "collapsedValue", "visibleValue"] }] }); }
5675
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: ErrorsComponent, deps: [{ token: CanvasProviderService }], target: i0.ɵɵFactoryTarget.Component }); }
5676
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.1.2", type: ErrorsComponent, isStandalone: true, selector: "daga-errors", viewQueries: [{ propertyName: "errorsContainer", first: true, predicate: ["errors"], descendants: true }], ngImport: i0, template: "<div #errorsContainer class=\"errors\">\n <div\n *ngIf=\"errors.length === 0\"\n class=\"errors-summary no-errors prevent-user-select\"\n >\n <span>No errors found</span>\n </div>\n <div\n *ngIf=\"errors.length > 0\"\n class=\"errors-summary with-errors prevent-user-select\"\n >\n <span>{{ errors.length }} errors found</span>\n <div class=\"collapse-button-container\">\n <daga-collapse-button\n [collapsableSelector]=\"errorsContainer\"\n [collapsableAdditionalSelector]=\"'.error-panel'\"\n [direction]=\"Side.Top\"\n [rule]=\"'display'\"\n [collapsedValue]=\"'none'\"\n [visibleValue]=\"'block'\"\n />\n </div>\n </div>\n <div *ngIf=\"errors.length > 0\" class=\"error-panel\">\n <ol>\n <li\n *ngFor=\"let error of errors; index as i\"\n (click)=\"showError(error)\"\n [innerHTML]=\"error.message\"\n ></li>\n </ol>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: CollapseButtonComponent, selector: "daga-collapse-button", inputs: ["collapsableSelector", "collapsableAdditionalSelector", "collapsed", "disabled", "direction", "rule", "collapsedValue", "visibleValue"] }] }); }
5429
5677
  }
5430
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: ErrorsComponent, decorators: [{
5678
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: ErrorsComponent, decorators: [{
5431
5679
  type: Component,
5432
- args: [{ standalone: true, selector: 'daga-errors', imports: [CommonModule, CollapseButtonComponent], template: "<div #errorsContainer class=\"errors\">\n <div\n *ngIf=\"errors.length === 0\"\n class=\"errors-summary no-errors prevent-user-select\"\n >\n <span>No errors found</span>\n </div>\n <div\n *ngIf=\"errors.length > 0\"\n class=\"errors-summary with-errors prevent-user-select\"\n >\n <span>{{ errors.length }} errors found</span>\n <div class=\"collapse-button-container\">\n <daga-collapse-button\n [collapsableSelector]=\"errorsContainer\"\n [collapsableAdditionalSelector]=\"'.error-panel'\"\n [direction]=\"Side.Top\"\n [rule]=\"'display'\"\n [collapsedValue]=\"'none'\"\n [visibleValue]=\"'block'\"\n />\n </div>\n </div>\n <div *ngIf=\"errors.length > 0\" class=\"error-panel\">\n <ol>\n <li\n *ngFor=\"let error of errors; index as i\"\n (click)=\"showError(error)\"\n [innerHTML]=\"error.message\"\n ></li>\n </ol>\n </div>\n</div>\n", styles: [":host{left:2rem;bottom:0;position:absolute;width:calc(100% - 8rem)}.errors-summary{position:absolute;right:2rem;top:-2rem;height:2rem;border-top-left-radius:.5rem;border-top-right-radius:.5rem;display:flex;flex-direction:row;align-items:center}.errors-summary.no-errors{background-color:var(--panel-secondary-color);color:var(--font-color)}.errors-summary.with-errors{background-color:#e64545;color:#fff}.errors-summary span{flex:1 0 auto;padding:.5rem}.errors-summary .collapse-button-container{flex:0 0 auto;padding-left:.5rem;padding-right:.5rem;border-top-left-radius:.5rem;border-top-right-radius:.5rem;background-color:var(--error-color)}.errors-summary .collapse-button-container daga-collapse-button{filter:brightness(10)}.error-panel{width:100%;max-height:12rem;border-top-left-radius:.5rem;border-top-right-radius:.5rem;padding:.5rem;background-color:var(--font-color);color:#fff;overflow:auto}.error-panel ol{counter-reset:count;list-style:decimal;padding:0;padding-left:5rem;margin:0;font-size:.95rem}.error-panel ol li{counter-increment:count;cursor:pointer;padding-bottom:.25rem}.error-panel ol li:hover{text-decoration:underline}.error-panel ol li::marker{content:\"ERROR \" counters(count,\".\",decimal-leading-zero) \" \";font-family:var(--monospace-font-family);font-size:.9rem;font-weight:400;color:#ffffffbf}.error-panel ol li b{font-weight:700}\n"] }]
5680
+ args: [{ standalone: true, selector: 'daga-errors', imports: [CommonModule, CollapseButtonComponent], template: "<div #errorsContainer class=\"errors\">\n <div\n *ngIf=\"errors.length === 0\"\n class=\"errors-summary no-errors prevent-user-select\"\n >\n <span>No errors found</span>\n </div>\n <div\n *ngIf=\"errors.length > 0\"\n class=\"errors-summary with-errors prevent-user-select\"\n >\n <span>{{ errors.length }} errors found</span>\n <div class=\"collapse-button-container\">\n <daga-collapse-button\n [collapsableSelector]=\"errorsContainer\"\n [collapsableAdditionalSelector]=\"'.error-panel'\"\n [direction]=\"Side.Top\"\n [rule]=\"'display'\"\n [collapsedValue]=\"'none'\"\n [visibleValue]=\"'block'\"\n />\n </div>\n </div>\n <div *ngIf=\"errors.length > 0\" class=\"error-panel\">\n <ol>\n <li\n *ngFor=\"let error of errors; index as i\"\n (click)=\"showError(error)\"\n [innerHTML]=\"error.message\"\n ></li>\n </ol>\n </div>\n</div>\n" }]
5433
5681
  }], ctorParameters: () => [{ type: CanvasProviderService }], propDecorators: { errorsContainer: [{
5434
5682
  type: ViewChild,
5435
5683
  args: ['errors']
@@ -5510,7 +5758,7 @@ class PaletteComponent {
5510
5758
  }
5511
5759
  appendTemplate(template, classes) {
5512
5760
  if (template.templateType === 'node') {
5513
- const nodeType = this.canvas.model.getNodeType(template.type);
5761
+ const nodeType = this.canvas.model.nodes.types.get(template.type);
5514
5762
  if (nodeType) {
5515
5763
  this.appendNodeTemplate(nodeType, template, classes);
5516
5764
  }
@@ -5520,7 +5768,7 @@ class PaletteComponent {
5520
5768
  }
5521
5769
  else if (template.templateType === 'connection') {
5522
5770
  {
5523
- const connectionType = this.canvas.model.getConnectionType(template.type);
5771
+ const connectionType = this.canvas.model.connections.types.get(template.type);
5524
5772
  if (connectionType) {
5525
5773
  this.appendConnectionTemplate(connectionType, template, classes);
5526
5774
  }
@@ -5578,7 +5826,12 @@ class PaletteComponent {
5578
5826
  .style('top', 0)
5579
5827
  .style('z-index', 'auto');
5580
5828
  // try to place node
5581
- if (type.isUnique && this.canvas.model.hasNodeOfType(type.id)) {
5829
+ if (this.canvas.userActions[DiagramActions.AddNodeAction] === false) {
5830
+ // can't place, the user isn't allowed to place nodes
5831
+ return;
5832
+ }
5833
+ if (type.isUnique &&
5834
+ this.canvas.model.nodes.find(type.id) !== undefined) {
5582
5835
  // can't place, it's unique and that node is already in the model
5583
5836
  return;
5584
5837
  }
@@ -5778,12 +6031,12 @@ class PaletteComponent {
5778
6031
  .text(templateConfig.label);
5779
6032
  }
5780
6033
  }
5781
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: PaletteComponent, deps: [{ token: CanvasProviderService }], target: i0.ɵɵFactoryTarget.Component }); }
5782
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.6", type: PaletteComponent, isStandalone: true, selector: "daga-palette", inputs: { palettes: "palettes", currentPalette: "currentPalette", currentCategory: "currentCategory", location: "location" }, viewQueries: [{ propertyName: "panel", first: true, predicate: ["panel"], descendants: true }], ngImport: i0, template: "<div #panel class=\"panel {{ location }}\">\n <daga-collapse-button\n #collapseButton\n [collapsableSelector]=\"panel\"\n [collapsableAdditionalSelector]=\"'.panel-content'\"\n [rule]=\"'display'\"\n [collapsedValue]=\"'none'\"\n [visibleValue]=\"'block'\"\n />\n <div class=\"panel-content\">\n <div *ngIf=\"palettes.length > 1\" class=\"panel-tabs\">\n <div\n *ngFor=\"let palette of palettes\"\n class=\"panel-tab\"\n [class]=\"palette === currentPalette ? 'current-tab' : ''\"\n (click)=\"switchPalette(palette)\"\n >\n {{ palette.name }}\n </div>\n </div>\n <div class=\"palette-view\"></div>\n </div>\n</div>\n", styles: [".panel{width:12rem}.palette-view{display:flex;flex-direction:column;align-items:center;gap:1rem;padding:1rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: CollapseButtonComponent, selector: "daga-collapse-button", inputs: ["collapsableSelector", "collapsableAdditionalSelector", "collapsed", "disabled", "direction", "rule", "collapsedValue", "visibleValue"] }] }); }
6034
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: PaletteComponent, deps: [{ token: CanvasProviderService }], target: i0.ɵɵFactoryTarget.Component }); }
6035
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.1.2", type: PaletteComponent, isStandalone: true, selector: "daga-palette", inputs: { palettes: "palettes", currentPalette: "currentPalette", currentCategory: "currentCategory", location: "location" }, viewQueries: [{ propertyName: "panel", first: true, predicate: ["panel"], descendants: true }], ngImport: i0, template: "<div #panel class=\"panel {{ location }}\">\n <daga-collapse-button\n #collapseButton\n [collapsableSelector]=\"panel\"\n [collapsableAdditionalSelector]=\"'.panel-content'\"\n [rule]=\"'display'\"\n [collapsedValue]=\"'none'\"\n [visibleValue]=\"'block'\"\n />\n <div class=\"panel-content\">\n <div *ngIf=\"palettes.length > 1\" class=\"panel-tabs\">\n <div\n *ngFor=\"let palette of palettes\"\n class=\"panel-tab\"\n [class]=\"palette === currentPalette ? 'current-tab' : ''\"\n (click)=\"switchPalette(palette)\"\n >\n {{ palette.name }}\n </div>\n </div>\n <div class=\"palette-view\"></div>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: CollapseButtonComponent, selector: "daga-collapse-button", inputs: ["collapsableSelector", "collapsableAdditionalSelector", "collapsed", "disabled", "direction", "rule", "collapsedValue", "visibleValue"] }] }); }
5783
6036
  }
5784
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: PaletteComponent, decorators: [{
6037
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: PaletteComponent, decorators: [{
5785
6038
  type: Component,
5786
- args: [{ standalone: true, selector: 'daga-palette', imports: [CommonModule, CollapseButtonComponent], template: "<div #panel class=\"panel {{ location }}\">\n <daga-collapse-button\n #collapseButton\n [collapsableSelector]=\"panel\"\n [collapsableAdditionalSelector]=\"'.panel-content'\"\n [rule]=\"'display'\"\n [collapsedValue]=\"'none'\"\n [visibleValue]=\"'block'\"\n />\n <div class=\"panel-content\">\n <div *ngIf=\"palettes.length > 1\" class=\"panel-tabs\">\n <div\n *ngFor=\"let palette of palettes\"\n class=\"panel-tab\"\n [class]=\"palette === currentPalette ? 'current-tab' : ''\"\n (click)=\"switchPalette(palette)\"\n >\n {{ palette.name }}\n </div>\n </div>\n <div class=\"palette-view\"></div>\n </div>\n</div>\n", styles: [".panel{width:12rem}.palette-view{display:flex;flex-direction:column;align-items:center;gap:1rem;padding:1rem}\n"] }]
6039
+ args: [{ standalone: true, selector: 'daga-palette', imports: [CommonModule, CollapseButtonComponent], template: "<div #panel class=\"panel {{ location }}\">\n <daga-collapse-button\n #collapseButton\n [collapsableSelector]=\"panel\"\n [collapsableAdditionalSelector]=\"'.panel-content'\"\n [rule]=\"'display'\"\n [collapsedValue]=\"'none'\"\n [visibleValue]=\"'block'\"\n />\n <div class=\"panel-content\">\n <div *ngIf=\"palettes.length > 1\" class=\"panel-tabs\">\n <div\n *ngFor=\"let palette of palettes\"\n class=\"panel-tab\"\n [class]=\"palette === currentPalette ? 'current-tab' : ''\"\n (click)=\"switchPalette(palette)\"\n >\n {{ palette.name }}\n </div>\n </div>\n <div class=\"palette-view\"></div>\n </div>\n</div>\n" }]
5787
6040
  }], ctorParameters: () => [{ type: CanvasProviderService }], propDecorators: { panel: [{
5788
6041
  type: ViewChild,
5789
6042
  args: ['panel']
@@ -5851,12 +6104,12 @@ class TextListEditorComponent {
5851
6104
  this.addToValue();
5852
6105
  }
5853
6106
  }
5854
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: TextListEditorComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
5855
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.6", type: TextListEditorComponent, isStandalone: true, selector: "daga-text-list-editor", inputs: { value: "value", valueInput: "valueInput", disabled: "disabled" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div *ngFor=\"let item of value; let index = index\" class=\"value-item-element\">\n <lux-input\n type=\"text\"\n [disabled]=\"disabled\"\n [value]=\"item\"\n (focusout)=\"editFromValue(getValueFromEvent($event), index)\"\n ></lux-input>\n <button\n *ngIf=\"!disabled\"\n class=\"property-button\"\n (click)=\"removeFromValue(index)\"\n >\n <img src=\"/assets/daga/icon/property/close.svg\" />\n </button>\n</div>\n<div *ngIf=\"!disabled\" class=\"value-item-input\">\n <div class=\"relatively-positioned\">\n <lux-input\n type=\"text\"\n (keyup)=\"onKeyUp($event)\"\n [(ngModel)]=\"valueInput\"\n ></lux-input>\n <button\n *ngIf=\"valueInput !== ''\"\n class=\"clear\"\n (click)=\"clearInput()\"\n ></button>\n </div>\n <button class=\"property-button\" (click)=\"addToValue()\">\n <img src=\"/assets/daga/icon/property/add.svg\" />\n </button>\n</div>\n", styles: [".property{padding-top:.5rem;padding-bottom:.5rem}.property .property-name{display:flex;justify-content:space-between;align-items:center;height:1.5rem;padding-bottom:.5rem;margin:0;width:100%;font-size:.75rem;font-weight:500;text-transform:uppercase}.value-item-input,.value-item-element{display:flex;align-items:stretch;flex-direction:row;height:1.5rem;gap:.5rem}.value-item-element{margin-bottom:.5rem}.left-bar{padding-left:1rem;border-left:.25rem solid var(--property-background-color)}lux-input,.relatively-positioned,p.value-item{height:1.5rem;flex-grow:1;flex-basis:0}p.value-item{margin:0;overflow:hidden;text-overflow:ellipsis}.relatively-positioned{position:relative}button.property-button{min-width:1.5rem;min-height:1.5rem;width:1.5rem;height:1.5rem;padding:0;border-radius:.25rem;border:none;background-color:transparent;font-size:1rem}button.property-button img{padding:.25rem;width:1rem;height:1rem}button.property-button:hover{background-color:var(--property-background-color)}button.clear{position:absolute;top:0;right:0;min-width:1.5rem;min-height:1.5rem;width:1.5rem;height:1.5rem;padding:0;border-radius:.25rem;border:none;background-color:transparent;background:var(--lux-autocomplete-icon-clear);background-size:.5rem .5rem;z-index:1}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: LuxModule }, { kind: "component", type: i3.InputComponent, selector: "lux-input", inputs: ["rows", "cols", "step", "min", "max", "lang", "inlineErrors", "inputId", "aria-label", "readonly", "disabled", "pattern", "currency", "placeholder", "required", "type", "value"], outputs: ["valueChange", "keyPress"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] }); }
6107
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: TextListEditorComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
6108
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.1.2", type: TextListEditorComponent, isStandalone: true, selector: "daga-text-list-editor", inputs: { value: "value", valueInput: "valueInput", disabled: "disabled" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div *ngFor=\"let item of value; let index = index\" class=\"value-item-element\">\n <lux-input\n type=\"text\"\n [disabled]=\"disabled\"\n [value]=\"item\"\n (focusout)=\"editFromValue(getValueFromEvent($event), index)\"\n ></lux-input>\n <button\n *ngIf=\"!disabled\"\n class=\"property-button\"\n (click)=\"removeFromValue(index)\"\n >\n <div class=\"icon close-icon\"></div>\n </button>\n</div>\n<div *ngIf=\"!disabled\" class=\"value-item-input\">\n <div class=\"relatively-positioned\">\n <lux-input\n type=\"text\"\n (keyup)=\"onKeyUp($event)\"\n [(ngModel)]=\"valueInput\"\n ></lux-input>\n <button\n *ngIf=\"valueInput !== ''\"\n class=\"clear\"\n (click)=\"clearInput()\"\n ></button>\n </div>\n <button class=\"property-button\" (click)=\"addToValue()\">\n <div class=\"icon add-icon\"></div>\n </button>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: LuxModule }, { kind: "component", type: i3.InputComponent, selector: "lux-input", inputs: ["rows", "cols", "step", "min", "max", "lang", "inlineErrors", "inputId", "aria-label", "readonly", "disabled", "pattern", "currency", "placeholder", "required", "type", "value"], outputs: ["valueChange", "keyPress"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] }); }
5856
6109
  }
5857
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: TextListEditorComponent, decorators: [{
6110
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: TextListEditorComponent, decorators: [{
5858
6111
  type: Component,
5859
- args: [{ standalone: true, selector: 'daga-text-list-editor', imports: [CommonModule, LuxModule, FormsModule], template: "<div *ngFor=\"let item of value; let index = index\" class=\"value-item-element\">\n <lux-input\n type=\"text\"\n [disabled]=\"disabled\"\n [value]=\"item\"\n (focusout)=\"editFromValue(getValueFromEvent($event), index)\"\n ></lux-input>\n <button\n *ngIf=\"!disabled\"\n class=\"property-button\"\n (click)=\"removeFromValue(index)\"\n >\n <img src=\"/assets/daga/icon/property/close.svg\" />\n </button>\n</div>\n<div *ngIf=\"!disabled\" class=\"value-item-input\">\n <div class=\"relatively-positioned\">\n <lux-input\n type=\"text\"\n (keyup)=\"onKeyUp($event)\"\n [(ngModel)]=\"valueInput\"\n ></lux-input>\n <button\n *ngIf=\"valueInput !== ''\"\n class=\"clear\"\n (click)=\"clearInput()\"\n ></button>\n </div>\n <button class=\"property-button\" (click)=\"addToValue()\">\n <img src=\"/assets/daga/icon/property/add.svg\" />\n </button>\n</div>\n", styles: [".property{padding-top:.5rem;padding-bottom:.5rem}.property .property-name{display:flex;justify-content:space-between;align-items:center;height:1.5rem;padding-bottom:.5rem;margin:0;width:100%;font-size:.75rem;font-weight:500;text-transform:uppercase}.value-item-input,.value-item-element{display:flex;align-items:stretch;flex-direction:row;height:1.5rem;gap:.5rem}.value-item-element{margin-bottom:.5rem}.left-bar{padding-left:1rem;border-left:.25rem solid var(--property-background-color)}lux-input,.relatively-positioned,p.value-item{height:1.5rem;flex-grow:1;flex-basis:0}p.value-item{margin:0;overflow:hidden;text-overflow:ellipsis}.relatively-positioned{position:relative}button.property-button{min-width:1.5rem;min-height:1.5rem;width:1.5rem;height:1.5rem;padding:0;border-radius:.25rem;border:none;background-color:transparent;font-size:1rem}button.property-button img{padding:.25rem;width:1rem;height:1rem}button.property-button:hover{background-color:var(--property-background-color)}button.clear{position:absolute;top:0;right:0;min-width:1.5rem;min-height:1.5rem;width:1.5rem;height:1.5rem;padding:0;border-radius:.25rem;border:none;background-color:transparent;background:var(--lux-autocomplete-icon-clear);background-size:.5rem .5rem;z-index:1}\n"] }]
6112
+ args: [{ standalone: true, selector: 'daga-text-list-editor', imports: [CommonModule, LuxModule, FormsModule], template: "<div *ngFor=\"let item of value; let index = index\" class=\"value-item-element\">\n <lux-input\n type=\"text\"\n [disabled]=\"disabled\"\n [value]=\"item\"\n (focusout)=\"editFromValue(getValueFromEvent($event), index)\"\n ></lux-input>\n <button\n *ngIf=\"!disabled\"\n class=\"property-button\"\n (click)=\"removeFromValue(index)\"\n >\n <div class=\"icon close-icon\"></div>\n </button>\n</div>\n<div *ngIf=\"!disabled\" class=\"value-item-input\">\n <div class=\"relatively-positioned\">\n <lux-input\n type=\"text\"\n (keyup)=\"onKeyUp($event)\"\n [(ngModel)]=\"valueInput\"\n ></lux-input>\n <button\n *ngIf=\"valueInput !== ''\"\n class=\"clear\"\n (click)=\"clearInput()\"\n ></button>\n </div>\n <button class=\"property-button\" (click)=\"addToValue()\">\n <div class=\"icon add-icon\"></div>\n </button>\n</div>\n" }]
5860
6113
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { value: [{
5861
6114
  type: Input
5862
6115
  }], valueInput: [{
@@ -5927,12 +6180,12 @@ class TextMapEditorComponent {
5927
6180
  this.addToValue();
5928
6181
  }
5929
6182
  }
5930
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: TextMapEditorComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
5931
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.6", type: TextMapEditorComponent, isStandalone: true, selector: "daga-text-map-editor", inputs: { value: "value", keyInput: "keyInput", valueInput: "valueInput", disabled: "disabled" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div *ngFor=\"let item of value | keyvalue\" class=\"value-item-element\">\n <lux-input\n type=\"text\"\n [disabled]=\"disabled\"\n [value]=\"item.key\"\n (focusout)=\"editKey(item.key, getValueFromEvent($event))\"\n ></lux-input>\n <lux-input\n type=\"text\"\n [disabled]=\"disabled\"\n [value]=\"item.value\"\n (focusout)=\"editValue(item.key, getValueFromEvent($event))\"\n ></lux-input>\n <button\n *ngIf=\"!disabled\"\n class=\"property-button\"\n (click)=\"removeFromValue(item.key)\"\n >\n <img src=\"/assets/daga/icon/property/close.svg\" />\n </button>\n</div>\n<div *ngIf=\"!disabled\" class=\"value-item-input\">\n <div class=\"relatively-positioned\">\n <lux-input\n type=\"text\"\n (keyup)=\"onKeyUp($event)\"\n [(ngModel)]=\"keyInput\"\n ></lux-input>\n <button\n *ngIf=\"keyInput !== ''\"\n class=\"clear\"\n (click)=\"clearKeyInput()\"\n ></button>\n </div>\n <div class=\"relatively-positioned\">\n <lux-input\n type=\"text\"\n (keyup)=\"onKeyUp($event)\"\n [(ngModel)]=\"valueInput\"\n ></lux-input>\n <button\n *ngIf=\"valueInput !== ''\"\n class=\"clear\"\n (click)=\"clearValueInput()\"\n ></button>\n </div>\n <button class=\"property-button\" (click)=\"addToValue()\">\n <img src=\"/assets/daga/icon/property/add.svg\" />\n </button>\n</div>\n", styles: [".property{padding-top:.5rem;padding-bottom:.5rem}.property .property-name{display:flex;justify-content:space-between;align-items:center;height:1.5rem;padding-bottom:.5rem;margin:0;width:100%;font-size:.75rem;font-weight:500;text-transform:uppercase}.value-item-input,.value-item-element{display:flex;align-items:stretch;flex-direction:row;height:1.5rem;gap:.5rem}.value-item-element{margin-bottom:.5rem}.left-bar{padding-left:1rem;border-left:.25rem solid var(--property-background-color)}lux-input,.relatively-positioned,p.value-item{height:1.5rem;flex-grow:1;flex-basis:0}p.value-item{margin:0;overflow:hidden;text-overflow:ellipsis}.relatively-positioned{position:relative}button.property-button{min-width:1.5rem;min-height:1.5rem;width:1.5rem;height:1.5rem;padding:0;border-radius:.25rem;border:none;background-color:transparent;font-size:1rem}button.property-button img{padding:.25rem;width:1rem;height:1rem}button.property-button:hover{background-color:var(--property-background-color)}button.clear{position:absolute;top:0;right:0;min-width:1.5rem;min-height:1.5rem;width:1.5rem;height:1.5rem;padding:0;border-radius:.25rem;border:none;background-color:transparent;background:var(--lux-autocomplete-icon-clear);background-size:.5rem .5rem;z-index:1}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i2.KeyValuePipe, name: "keyvalue" }, { kind: "ngmodule", type: LuxModule }, { kind: "component", type: i3.InputComponent, selector: "lux-input", inputs: ["rows", "cols", "step", "min", "max", "lang", "inlineErrors", "inputId", "aria-label", "readonly", "disabled", "pattern", "currency", "placeholder", "required", "type", "value"], outputs: ["valueChange", "keyPress"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] }); }
6183
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: TextMapEditorComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
6184
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.1.2", type: TextMapEditorComponent, isStandalone: true, selector: "daga-text-map-editor", inputs: { value: "value", keyInput: "keyInput", valueInput: "valueInput", disabled: "disabled" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div *ngFor=\"let item of value | keyvalue\" class=\"value-item-element\">\n <lux-input\n type=\"text\"\n [disabled]=\"disabled\"\n [value]=\"item.key\"\n (focusout)=\"editKey(item.key, getValueFromEvent($event))\"\n ></lux-input>\n <lux-input\n type=\"text\"\n [disabled]=\"disabled\"\n [value]=\"item.value\"\n (focusout)=\"editValue(item.key, getValueFromEvent($event))\"\n ></lux-input>\n <button\n *ngIf=\"!disabled\"\n class=\"property-button\"\n (click)=\"removeFromValue(item.key)\"\n >\n <div class=\"icon close-icon\"></div>\n </button>\n</div>\n<div *ngIf=\"!disabled\" class=\"value-item-input\">\n <div class=\"relatively-positioned\">\n <lux-input\n type=\"text\"\n (keyup)=\"onKeyUp($event)\"\n [(ngModel)]=\"keyInput\"\n ></lux-input>\n <button\n *ngIf=\"keyInput !== ''\"\n class=\"clear\"\n (click)=\"clearKeyInput()\"\n ></button>\n </div>\n <div class=\"relatively-positioned\">\n <lux-input\n type=\"text\"\n (keyup)=\"onKeyUp($event)\"\n [(ngModel)]=\"valueInput\"\n ></lux-input>\n <button\n *ngIf=\"valueInput !== ''\"\n class=\"clear\"\n (click)=\"clearValueInput()\"\n ></button>\n </div>\n <button class=\"property-button\" (click)=\"addToValue()\">\n <div class=\"icon add-icon\"></div>\n </button>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i2.KeyValuePipe, name: "keyvalue" }, { kind: "ngmodule", type: LuxModule }, { kind: "component", type: i3.InputComponent, selector: "lux-input", inputs: ["rows", "cols", "step", "min", "max", "lang", "inlineErrors", "inputId", "aria-label", "readonly", "disabled", "pattern", "currency", "placeholder", "required", "type", "value"], outputs: ["valueChange", "keyPress"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] }); }
5932
6185
  }
5933
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: TextMapEditorComponent, decorators: [{
6186
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: TextMapEditorComponent, decorators: [{
5934
6187
  type: Component,
5935
- args: [{ standalone: true, selector: 'daga-text-map-editor', imports: [CommonModule, LuxModule, FormsModule], template: "<div *ngFor=\"let item of value | keyvalue\" class=\"value-item-element\">\n <lux-input\n type=\"text\"\n [disabled]=\"disabled\"\n [value]=\"item.key\"\n (focusout)=\"editKey(item.key, getValueFromEvent($event))\"\n ></lux-input>\n <lux-input\n type=\"text\"\n [disabled]=\"disabled\"\n [value]=\"item.value\"\n (focusout)=\"editValue(item.key, getValueFromEvent($event))\"\n ></lux-input>\n <button\n *ngIf=\"!disabled\"\n class=\"property-button\"\n (click)=\"removeFromValue(item.key)\"\n >\n <img src=\"/assets/daga/icon/property/close.svg\" />\n </button>\n</div>\n<div *ngIf=\"!disabled\" class=\"value-item-input\">\n <div class=\"relatively-positioned\">\n <lux-input\n type=\"text\"\n (keyup)=\"onKeyUp($event)\"\n [(ngModel)]=\"keyInput\"\n ></lux-input>\n <button\n *ngIf=\"keyInput !== ''\"\n class=\"clear\"\n (click)=\"clearKeyInput()\"\n ></button>\n </div>\n <div class=\"relatively-positioned\">\n <lux-input\n type=\"text\"\n (keyup)=\"onKeyUp($event)\"\n [(ngModel)]=\"valueInput\"\n ></lux-input>\n <button\n *ngIf=\"valueInput !== ''\"\n class=\"clear\"\n (click)=\"clearValueInput()\"\n ></button>\n </div>\n <button class=\"property-button\" (click)=\"addToValue()\">\n <img src=\"/assets/daga/icon/property/add.svg\" />\n </button>\n</div>\n", styles: [".property{padding-top:.5rem;padding-bottom:.5rem}.property .property-name{display:flex;justify-content:space-between;align-items:center;height:1.5rem;padding-bottom:.5rem;margin:0;width:100%;font-size:.75rem;font-weight:500;text-transform:uppercase}.value-item-input,.value-item-element{display:flex;align-items:stretch;flex-direction:row;height:1.5rem;gap:.5rem}.value-item-element{margin-bottom:.5rem}.left-bar{padding-left:1rem;border-left:.25rem solid var(--property-background-color)}lux-input,.relatively-positioned,p.value-item{height:1.5rem;flex-grow:1;flex-basis:0}p.value-item{margin:0;overflow:hidden;text-overflow:ellipsis}.relatively-positioned{position:relative}button.property-button{min-width:1.5rem;min-height:1.5rem;width:1.5rem;height:1.5rem;padding:0;border-radius:.25rem;border:none;background-color:transparent;font-size:1rem}button.property-button img{padding:.25rem;width:1rem;height:1rem}button.property-button:hover{background-color:var(--property-background-color)}button.clear{position:absolute;top:0;right:0;min-width:1.5rem;min-height:1.5rem;width:1.5rem;height:1.5rem;padding:0;border-radius:.25rem;border:none;background-color:transparent;background:var(--lux-autocomplete-icon-clear);background-size:.5rem .5rem;z-index:1}\n"] }]
6188
+ args: [{ standalone: true, selector: 'daga-text-map-editor', imports: [CommonModule, LuxModule, FormsModule], template: "<div *ngFor=\"let item of value | keyvalue\" class=\"value-item-element\">\n <lux-input\n type=\"text\"\n [disabled]=\"disabled\"\n [value]=\"item.key\"\n (focusout)=\"editKey(item.key, getValueFromEvent($event))\"\n ></lux-input>\n <lux-input\n type=\"text\"\n [disabled]=\"disabled\"\n [value]=\"item.value\"\n (focusout)=\"editValue(item.key, getValueFromEvent($event))\"\n ></lux-input>\n <button\n *ngIf=\"!disabled\"\n class=\"property-button\"\n (click)=\"removeFromValue(item.key)\"\n >\n <div class=\"icon close-icon\"></div>\n </button>\n</div>\n<div *ngIf=\"!disabled\" class=\"value-item-input\">\n <div class=\"relatively-positioned\">\n <lux-input\n type=\"text\"\n (keyup)=\"onKeyUp($event)\"\n [(ngModel)]=\"keyInput\"\n ></lux-input>\n <button\n *ngIf=\"keyInput !== ''\"\n class=\"clear\"\n (click)=\"clearKeyInput()\"\n ></button>\n </div>\n <div class=\"relatively-positioned\">\n <lux-input\n type=\"text\"\n (keyup)=\"onKeyUp($event)\"\n [(ngModel)]=\"valueInput\"\n ></lux-input>\n <button\n *ngIf=\"valueInput !== ''\"\n class=\"clear\"\n (click)=\"clearValueInput()\"\n ></button>\n </div>\n <button class=\"property-button\" (click)=\"addToValue()\">\n <div class=\"icon add-icon\"></div>\n </button>\n</div>\n" }]
5936
6189
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { value: [{
5937
6190
  type: Input
5938
6191
  }], keyInput: [{
@@ -5949,6 +6202,9 @@ class ObjectEditorComponent {
5949
6202
  get canvas() {
5950
6203
  return this.canvasProvider.getCanvas();
5951
6204
  }
6205
+ get userCanEdit() {
6206
+ return this.canvas.userActions[DiagramActions.UpdateValuesAction] !== false;
6207
+ }
5952
6208
  get valueSet() {
5953
6209
  return this._valueSet;
5954
6210
  }
@@ -6025,10 +6281,10 @@ class ObjectEditorComponent {
6025
6281
  }
6026
6282
  return date && !isNaN(date.valueOf()) ? new Date(date).toISOString() : '';
6027
6283
  }
6028
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: ObjectEditorComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: CanvasProviderService }], target: i0.ɵɵFactoryTarget.Component }); }
6029
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.6", type: ObjectEditorComponent, isStandalone: true, selector: "daga-object-editor", inputs: { valueSet: "valueSet", depth: "depth" }, ngImport: i0, template: "<div\n *ngFor=\"let property of valueSet?.displayedProperties || []\"\n class=\"property\"\n [class]=\"property.name + ' depth-' + depth\"\n>\n <p class=\"property-name\">\n {{ property.name }}\n <button class=\"property-button\" (click)=\"hideProperty(property.name)\">\n <img src=\"/assets/daga/icon/property/hide.svg\" />\n </button>\n </p>\n\n <lux-input\n *ngIf=\"property.type === Type.Text\"\n type=\"text\"\n [disabled]=\"!property.editable\"\n [value]=\"valueSet?.getValue(property.name)\"\n (valueChange)=\"setValue(property, $event)\"\n ></lux-input>\n <textarea\n *ngIf=\"property.type === Type.TextArea\"\n [ngModel]=\"valueSet?.getValue(property.name)\"\n (ngModelChange)=\"setValue(property, $event)\"\n ></textarea>\n <lux-input\n *ngIf=\"property.type === Type.Number\"\n type=\"number\"\n [disabled]=\"!property.editable\"\n [value]=\"valueSet?.getValue(property.name)\"\n (valueChange)=\"setValue(property, $event)\"\n ></lux-input>\n <lux-input\n *ngIf=\"property.type === Type.Color\"\n type=\"color\"\n [disabled]=\"!property.editable\"\n [value]=\"valueSet?.getValue(property.name)\"\n (valueChange)=\"setValue(property, $event)\"\n ></lux-input>\n <lux-input\n *ngIf=\"property.type === Type.Date\"\n type=\"date\"\n [disabled]=\"!property.editable\"\n [value]=\"convertDate(valueSet?.getValue(property.name))\"\n (valueChange)=\"setValue(property, $event)\"\n ></lux-input>\n <lux-input\n *ngIf=\"property.type === Type.Time\"\n type=\"time\"\n [disabled]=\"!property.editable\"\n [value]=\"convertDate(valueSet?.getValue(property.name))\"\n (valueChange)=\"setValue(property, $event)\"\n ></lux-input>\n <lux-input\n *ngIf=\"property.type === Type.Url\"\n type=\"url\"\n [disabled]=\"!property.editable\"\n [value]=\"valueSet?.getValue(property.name)\"\n (valueChange)=\"setValue(property, $event)\"\n ></lux-input>\n <lux-radiogroup\n *ngIf=\"property.type === Type.Boolean\"\n [disabled]=\"!property.editable\"\n [items]=\"booleanRadioItems\"\n [value]=\"valueSet?.getValue(property.name)\"\n (valueChange)=\"setValue(property, $event)\"\n ></lux-radiogroup>\n <lux-autocomplete\n *ngIf=\"property.type === Type.Option\"\n [disabled]=\"!property.editable\"\n [dataSource]=\"property.options || []\"\n [value]=\"valueSet?.getValue(property.name)\"\n (valueChange)=\"setValue(property, $event)\"\n ></lux-autocomplete>\n <lux-autocomplete-list\n *ngIf=\"property.type === Type.OptionList\"\n [disabled]=\"!property.editable\"\n [dataSource]=\"property.options || []\"\n [value]=\"valueSet?.getValue(property.name)\"\n (valueChange)=\"setValue(property, $event)\"\n ></lux-autocomplete-list>\n <daga-text-list-editor\n *ngIf=\"property.type === Type.TextList\"\n [disabled]=\"!property.editable\"\n [value]=\"valueSet?.getValue(property.name)\"\n (valueChange)=\"setValue(property, $event)\"\n ></daga-text-list-editor>\n <daga-text-map-editor\n *ngIf=\"property.type === Type.TextMap\"\n [disabled]=\"!property.editable\"\n [value]=\"valueSet?.getValue(property.name)\"\n (valueChange)=\"setValue(property, $event)\"\n ></daga-text-map-editor>\n <div *ngIf=\"property.type === Type.Object\" class=\"left-bar\">\n <daga-object-editor\n [valueSet]=\"valueSet?.getSubValueSet(property.name)\"\n [depth]=\"depth + 1\"\n ></daga-object-editor>\n </div>\n</div>\n<div class=\"property\" *ngIf=\"valueSet && valueSet.hiddenProperties.length > 0\">\n <p class=\"property-name\">Add property:</p>\n <select (change)=\"displayProperty($event)\">\n <option value=\"\">Select a property</option>\n <option\n *ngFor=\"let property of valueSet?.hiddenProperties || []\"\n [value]=\"property.name\"\n >\n {{ property.name }}\n </option>\n </select>\n</div>\n", styles: [".property{padding-top:.5rem;padding-bottom:.5rem}.property .property-name{display:flex;justify-content:space-between;align-items:center;height:1.5rem;padding-bottom:.5rem;margin:0;width:100%;font-size:.75rem;font-weight:500;text-transform:uppercase}.value-item-input,.value-item-element{display:flex;align-items:stretch;flex-direction:row;height:1.5rem;gap:.5rem}.value-item-element{margin-bottom:.5rem}.left-bar{padding-left:1rem;border-left:.25rem solid var(--property-background-color)}lux-input,.relatively-positioned,p.value-item{height:1.5rem;flex-grow:1;flex-basis:0}p.value-item{margin:0;overflow:hidden;text-overflow:ellipsis}.relatively-positioned{position:relative}button.property-button{min-width:1.5rem;min-height:1.5rem;width:1.5rem;height:1.5rem;padding:0;border-radius:.25rem;border:none;background-color:transparent;font-size:1rem}button.property-button img{padding:.25rem;width:1rem;height:1rem}button.property-button:hover{background-color:var(--property-background-color)}button.clear{position:absolute;top:0;right:0;min-width:1.5rem;min-height:1.5rem;width:1.5rem;height:1.5rem;padding:0;border-radius:.25rem;border:none;background-color:transparent;background:var(--lux-autocomplete-icon-clear);background-size:.5rem .5rem;z-index:1}\n"], dependencies: [{ kind: "component", type: ObjectEditorComponent, selector: "daga-object-editor", inputs: ["valueSet", "depth"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: LuxModule }, { kind: "component", type: i3.AutocompleteComponent, selector: "lux-autocomplete", inputs: ["inputId", "disabled", "readonly", "label", "canAddNewValues", "keepOpenAfterDelete", "value", "dataSource", "required", "placeholder", "resolveLabelsFunction", "populateFunction", "instance"], outputs: ["valueChange", "dataSourceChange"] }, { kind: "component", type: i3.AutocompleteListComponent, selector: "lux-autocomplete-list", inputs: ["value", "lang", "inputId", "dataSource", "placeholder", "disabled", "deleteLabelTemplate", "addMessage", "required", "resolveLabelsFunction", "populateFunction", "instance"], outputs: ["valueChange"] }, { kind: "component", type: i3.InputComponent, selector: "lux-input", inputs: ["rows", "cols", "step", "min", "max", "lang", "inlineErrors", "inputId", "aria-label", "readonly", "disabled", "pattern", "currency", "placeholder", "required", "type", "value"], outputs: ["valueChange", "keyPress"] }, { kind: "component", type: i3.RadiogroupComponent, selector: "lux-radiogroup", inputs: ["name", "disabled", "readonly", "required", "items", "value"], outputs: ["itemsChange", "valueChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i4.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i4.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: TextListEditorComponent, selector: "daga-text-list-editor", inputs: ["value", "valueInput", "disabled"], outputs: ["valueChange"] }, { kind: "component", type: TextMapEditorComponent, selector: "daga-text-map-editor", inputs: ["value", "keyInput", "valueInput", "disabled"], outputs: ["valueChange"] }] }); }
6284
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: ObjectEditorComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: CanvasProviderService }], target: i0.ɵɵFactoryTarget.Component }); }
6285
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.1.2", type: ObjectEditorComponent, isStandalone: true, selector: "daga-object-editor", inputs: { valueSet: "valueSet", depth: "depth" }, ngImport: i0, template: "<div\n *ngFor=\"let property of valueSet?.displayedProperties || []\"\n class=\"property\"\n [class]=\"property.name + ' depth-' + depth\"\n>\n <p class=\"property-name\">\n {{ property.name }}\n <button class=\"property-button\" (click)=\"hideProperty(property.name)\">\n <div class=\"icon hide-icon\"></div>\n </button>\n </p>\n\n <lux-input\n *ngIf=\"property.type === Type.Text\"\n type=\"text\"\n [disabled]=\"!property.editable || !userCanEdit\"\n [value]=\"valueSet?.getValue(property.name)\"\n (valueChange)=\"setValue(property, $event)\"\n ></lux-input>\n <textarea\n *ngIf=\"property.type === Type.TextArea\"\n [disabled]=\"!property.editable || !userCanEdit\"\n [ngModel]=\"valueSet?.getValue(property.name)\"\n (ngModelChange)=\"setValue(property, $event)\"\n ></textarea>\n <lux-input\n *ngIf=\"property.type === Type.Number\"\n type=\"number\"\n [disabled]=\"!property.editable || !userCanEdit\"\n [value]=\"valueSet?.getValue(property.name)\"\n (valueChange)=\"setValue(property, $event)\"\n ></lux-input>\n <lux-input\n *ngIf=\"property.type === Type.Color\"\n type=\"color\"\n [disabled]=\"!property.editable || !userCanEdit\"\n [value]=\"valueSet?.getValue(property.name)\"\n (valueChange)=\"setValue(property, $event)\"\n ></lux-input>\n <lux-input\n *ngIf=\"property.type === Type.Date\"\n type=\"date\"\n [disabled]=\"!property.editable || !userCanEdit\"\n [value]=\"convertDate(valueSet?.getValue(property.name))\"\n (valueChange)=\"setValue(property, $event)\"\n ></lux-input>\n <lux-input\n *ngIf=\"property.type === Type.Time\"\n type=\"time\"\n [disabled]=\"!property.editable || !userCanEdit\"\n [value]=\"convertDate(valueSet?.getValue(property.name))\"\n (valueChange)=\"setValue(property, $event)\"\n ></lux-input>\n <lux-input\n *ngIf=\"property.type === Type.Url\"\n type=\"url\"\n [disabled]=\"!property.editable || !userCanEdit\"\n [value]=\"valueSet?.getValue(property.name)\"\n (valueChange)=\"setValue(property, $event)\"\n ></lux-input>\n <lux-radiogroup\n *ngIf=\"property.type === Type.Boolean\"\n [disabled]=\"!property.editable || !userCanEdit\"\n [items]=\"booleanRadioItems\"\n [value]=\"valueSet?.getValue(property.name)\"\n (valueChange)=\"setValue(property, $event)\"\n ></lux-radiogroup>\n <lux-autocomplete\n *ngIf=\"property.type === Type.Option\"\n [disabled]=\"!property.editable || !userCanEdit\"\n [dataSource]=\"property.options || []\"\n [value]=\"valueSet?.getValue(property.name)\"\n (valueChange)=\"setValue(property, $event)\"\n ></lux-autocomplete>\n <lux-autocomplete-list\n *ngIf=\"property.type === Type.OptionList\"\n [disabled]=\"!property.editable || !userCanEdit\"\n [dataSource]=\"property.options || []\"\n [value]=\"valueSet?.getValue(property.name)\"\n (valueChange)=\"setValue(property, $event)\"\n ></lux-autocomplete-list>\n <daga-text-list-editor\n *ngIf=\"property.type === Type.TextList\"\n [disabled]=\"!property.editable || !userCanEdit\"\n [value]=\"valueSet?.getValue(property.name)\"\n (valueChange)=\"setValue(property, $event)\"\n ></daga-text-list-editor>\n <daga-text-map-editor\n *ngIf=\"property.type === Type.TextMap\"\n [disabled]=\"!property.editable || !userCanEdit\"\n [value]=\"valueSet?.getValue(property.name)\"\n (valueChange)=\"setValue(property, $event)\"\n ></daga-text-map-editor>\n <div *ngIf=\"property.type === Type.Object\" class=\"left-bar\">\n <daga-object-editor\n [valueSet]=\"valueSet?.getSubValueSet(property.name)\"\n [depth]=\"depth + 1\"\n ></daga-object-editor>\n </div>\n</div>\n<div class=\"property\" *ngIf=\"valueSet && valueSet.hiddenProperties.length > 0\">\n <p class=\"property-name\">Add property:</p>\n <select (change)=\"displayProperty($event)\">\n <option value=\"\">Select a property</option>\n <option\n *ngFor=\"let property of valueSet?.hiddenProperties || []\"\n [value]=\"property.name\"\n >\n {{ property.name }}\n </option>\n </select>\n</div>\n", dependencies: [{ kind: "component", type: ObjectEditorComponent, selector: "daga-object-editor", inputs: ["valueSet", "depth"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: LuxModule }, { kind: "component", type: i3.AutocompleteComponent, selector: "lux-autocomplete", inputs: ["inputId", "disabled", "readonly", "label", "canAddNewValues", "keepOpenAfterDelete", "value", "dataSource", "required", "placeholder", "resolveLabelsFunction", "populateFunction", "instance"], outputs: ["valueChange", "dataSourceChange"] }, { kind: "component", type: i3.AutocompleteListComponent, selector: "lux-autocomplete-list", inputs: ["value", "lang", "inputId", "dataSource", "placeholder", "disabled", "deleteLabelTemplate", "addMessage", "required", "resolveLabelsFunction", "populateFunction", "instance"], outputs: ["valueChange"] }, { kind: "component", type: i3.InputComponent, selector: "lux-input", inputs: ["rows", "cols", "step", "min", "max", "lang", "inlineErrors", "inputId", "aria-label", "readonly", "disabled", "pattern", "currency", "placeholder", "required", "type", "value"], outputs: ["valueChange", "keyPress"] }, { kind: "component", type: i3.RadiogroupComponent, selector: "lux-radiogroup", inputs: ["name", "disabled", "readonly", "required", "items", "value"], outputs: ["itemsChange", "valueChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i4.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i4.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: TextListEditorComponent, selector: "daga-text-list-editor", inputs: ["value", "valueInput", "disabled"], outputs: ["valueChange"] }, { kind: "component", type: TextMapEditorComponent, selector: "daga-text-map-editor", inputs: ["value", "keyInput", "valueInput", "disabled"], outputs: ["valueChange"] }] }); }
6030
6286
  }
6031
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: ObjectEditorComponent, decorators: [{
6287
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: ObjectEditorComponent, decorators: [{
6032
6288
  type: Component,
6033
6289
  args: [{ standalone: true, selector: 'daga-object-editor', imports: [
6034
6290
  CommonModule,
@@ -6036,7 +6292,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.6", ngImpor
6036
6292
  FormsModule,
6037
6293
  TextListEditorComponent,
6038
6294
  TextMapEditorComponent
6039
- ], template: "<div\n *ngFor=\"let property of valueSet?.displayedProperties || []\"\n class=\"property\"\n [class]=\"property.name + ' depth-' + depth\"\n>\n <p class=\"property-name\">\n {{ property.name }}\n <button class=\"property-button\" (click)=\"hideProperty(property.name)\">\n <img src=\"/assets/daga/icon/property/hide.svg\" />\n </button>\n </p>\n\n <lux-input\n *ngIf=\"property.type === Type.Text\"\n type=\"text\"\n [disabled]=\"!property.editable\"\n [value]=\"valueSet?.getValue(property.name)\"\n (valueChange)=\"setValue(property, $event)\"\n ></lux-input>\n <textarea\n *ngIf=\"property.type === Type.TextArea\"\n [ngModel]=\"valueSet?.getValue(property.name)\"\n (ngModelChange)=\"setValue(property, $event)\"\n ></textarea>\n <lux-input\n *ngIf=\"property.type === Type.Number\"\n type=\"number\"\n [disabled]=\"!property.editable\"\n [value]=\"valueSet?.getValue(property.name)\"\n (valueChange)=\"setValue(property, $event)\"\n ></lux-input>\n <lux-input\n *ngIf=\"property.type === Type.Color\"\n type=\"color\"\n [disabled]=\"!property.editable\"\n [value]=\"valueSet?.getValue(property.name)\"\n (valueChange)=\"setValue(property, $event)\"\n ></lux-input>\n <lux-input\n *ngIf=\"property.type === Type.Date\"\n type=\"date\"\n [disabled]=\"!property.editable\"\n [value]=\"convertDate(valueSet?.getValue(property.name))\"\n (valueChange)=\"setValue(property, $event)\"\n ></lux-input>\n <lux-input\n *ngIf=\"property.type === Type.Time\"\n type=\"time\"\n [disabled]=\"!property.editable\"\n [value]=\"convertDate(valueSet?.getValue(property.name))\"\n (valueChange)=\"setValue(property, $event)\"\n ></lux-input>\n <lux-input\n *ngIf=\"property.type === Type.Url\"\n type=\"url\"\n [disabled]=\"!property.editable\"\n [value]=\"valueSet?.getValue(property.name)\"\n (valueChange)=\"setValue(property, $event)\"\n ></lux-input>\n <lux-radiogroup\n *ngIf=\"property.type === Type.Boolean\"\n [disabled]=\"!property.editable\"\n [items]=\"booleanRadioItems\"\n [value]=\"valueSet?.getValue(property.name)\"\n (valueChange)=\"setValue(property, $event)\"\n ></lux-radiogroup>\n <lux-autocomplete\n *ngIf=\"property.type === Type.Option\"\n [disabled]=\"!property.editable\"\n [dataSource]=\"property.options || []\"\n [value]=\"valueSet?.getValue(property.name)\"\n (valueChange)=\"setValue(property, $event)\"\n ></lux-autocomplete>\n <lux-autocomplete-list\n *ngIf=\"property.type === Type.OptionList\"\n [disabled]=\"!property.editable\"\n [dataSource]=\"property.options || []\"\n [value]=\"valueSet?.getValue(property.name)\"\n (valueChange)=\"setValue(property, $event)\"\n ></lux-autocomplete-list>\n <daga-text-list-editor\n *ngIf=\"property.type === Type.TextList\"\n [disabled]=\"!property.editable\"\n [value]=\"valueSet?.getValue(property.name)\"\n (valueChange)=\"setValue(property, $event)\"\n ></daga-text-list-editor>\n <daga-text-map-editor\n *ngIf=\"property.type === Type.TextMap\"\n [disabled]=\"!property.editable\"\n [value]=\"valueSet?.getValue(property.name)\"\n (valueChange)=\"setValue(property, $event)\"\n ></daga-text-map-editor>\n <div *ngIf=\"property.type === Type.Object\" class=\"left-bar\">\n <daga-object-editor\n [valueSet]=\"valueSet?.getSubValueSet(property.name)\"\n [depth]=\"depth + 1\"\n ></daga-object-editor>\n </div>\n</div>\n<div class=\"property\" *ngIf=\"valueSet && valueSet.hiddenProperties.length > 0\">\n <p class=\"property-name\">Add property:</p>\n <select (change)=\"displayProperty($event)\">\n <option value=\"\">Select a property</option>\n <option\n *ngFor=\"let property of valueSet?.hiddenProperties || []\"\n [value]=\"property.name\"\n >\n {{ property.name }}\n </option>\n </select>\n</div>\n", styles: [".property{padding-top:.5rem;padding-bottom:.5rem}.property .property-name{display:flex;justify-content:space-between;align-items:center;height:1.5rem;padding-bottom:.5rem;margin:0;width:100%;font-size:.75rem;font-weight:500;text-transform:uppercase}.value-item-input,.value-item-element{display:flex;align-items:stretch;flex-direction:row;height:1.5rem;gap:.5rem}.value-item-element{margin-bottom:.5rem}.left-bar{padding-left:1rem;border-left:.25rem solid var(--property-background-color)}lux-input,.relatively-positioned,p.value-item{height:1.5rem;flex-grow:1;flex-basis:0}p.value-item{margin:0;overflow:hidden;text-overflow:ellipsis}.relatively-positioned{position:relative}button.property-button{min-width:1.5rem;min-height:1.5rem;width:1.5rem;height:1.5rem;padding:0;border-radius:.25rem;border:none;background-color:transparent;font-size:1rem}button.property-button img{padding:.25rem;width:1rem;height:1rem}button.property-button:hover{background-color:var(--property-background-color)}button.clear{position:absolute;top:0;right:0;min-width:1.5rem;min-height:1.5rem;width:1.5rem;height:1.5rem;padding:0;border-radius:.25rem;border:none;background-color:transparent;background:var(--lux-autocomplete-icon-clear);background-size:.5rem .5rem;z-index:1}\n"] }]
6295
+ ], template: "<div\n *ngFor=\"let property of valueSet?.displayedProperties || []\"\n class=\"property\"\n [class]=\"property.name + ' depth-' + depth\"\n>\n <p class=\"property-name\">\n {{ property.name }}\n <button class=\"property-button\" (click)=\"hideProperty(property.name)\">\n <div class=\"icon hide-icon\"></div>\n </button>\n </p>\n\n <lux-input\n *ngIf=\"property.type === Type.Text\"\n type=\"text\"\n [disabled]=\"!property.editable || !userCanEdit\"\n [value]=\"valueSet?.getValue(property.name)\"\n (valueChange)=\"setValue(property, $event)\"\n ></lux-input>\n <textarea\n *ngIf=\"property.type === Type.TextArea\"\n [disabled]=\"!property.editable || !userCanEdit\"\n [ngModel]=\"valueSet?.getValue(property.name)\"\n (ngModelChange)=\"setValue(property, $event)\"\n ></textarea>\n <lux-input\n *ngIf=\"property.type === Type.Number\"\n type=\"number\"\n [disabled]=\"!property.editable || !userCanEdit\"\n [value]=\"valueSet?.getValue(property.name)\"\n (valueChange)=\"setValue(property, $event)\"\n ></lux-input>\n <lux-input\n *ngIf=\"property.type === Type.Color\"\n type=\"color\"\n [disabled]=\"!property.editable || !userCanEdit\"\n [value]=\"valueSet?.getValue(property.name)\"\n (valueChange)=\"setValue(property, $event)\"\n ></lux-input>\n <lux-input\n *ngIf=\"property.type === Type.Date\"\n type=\"date\"\n [disabled]=\"!property.editable || !userCanEdit\"\n [value]=\"convertDate(valueSet?.getValue(property.name))\"\n (valueChange)=\"setValue(property, $event)\"\n ></lux-input>\n <lux-input\n *ngIf=\"property.type === Type.Time\"\n type=\"time\"\n [disabled]=\"!property.editable || !userCanEdit\"\n [value]=\"convertDate(valueSet?.getValue(property.name))\"\n (valueChange)=\"setValue(property, $event)\"\n ></lux-input>\n <lux-input\n *ngIf=\"property.type === Type.Url\"\n type=\"url\"\n [disabled]=\"!property.editable || !userCanEdit\"\n [value]=\"valueSet?.getValue(property.name)\"\n (valueChange)=\"setValue(property, $event)\"\n ></lux-input>\n <lux-radiogroup\n *ngIf=\"property.type === Type.Boolean\"\n [disabled]=\"!property.editable || !userCanEdit\"\n [items]=\"booleanRadioItems\"\n [value]=\"valueSet?.getValue(property.name)\"\n (valueChange)=\"setValue(property, $event)\"\n ></lux-radiogroup>\n <lux-autocomplete\n *ngIf=\"property.type === Type.Option\"\n [disabled]=\"!property.editable || !userCanEdit\"\n [dataSource]=\"property.options || []\"\n [value]=\"valueSet?.getValue(property.name)\"\n (valueChange)=\"setValue(property, $event)\"\n ></lux-autocomplete>\n <lux-autocomplete-list\n *ngIf=\"property.type === Type.OptionList\"\n [disabled]=\"!property.editable || !userCanEdit\"\n [dataSource]=\"property.options || []\"\n [value]=\"valueSet?.getValue(property.name)\"\n (valueChange)=\"setValue(property, $event)\"\n ></lux-autocomplete-list>\n <daga-text-list-editor\n *ngIf=\"property.type === Type.TextList\"\n [disabled]=\"!property.editable || !userCanEdit\"\n [value]=\"valueSet?.getValue(property.name)\"\n (valueChange)=\"setValue(property, $event)\"\n ></daga-text-list-editor>\n <daga-text-map-editor\n *ngIf=\"property.type === Type.TextMap\"\n [disabled]=\"!property.editable || !userCanEdit\"\n [value]=\"valueSet?.getValue(property.name)\"\n (valueChange)=\"setValue(property, $event)\"\n ></daga-text-map-editor>\n <div *ngIf=\"property.type === Type.Object\" class=\"left-bar\">\n <daga-object-editor\n [valueSet]=\"valueSet?.getSubValueSet(property.name)\"\n [depth]=\"depth + 1\"\n ></daga-object-editor>\n </div>\n</div>\n<div class=\"property\" *ngIf=\"valueSet && valueSet.hiddenProperties.length > 0\">\n <p class=\"property-name\">Add property:</p>\n <select (change)=\"displayProperty($event)\">\n <option value=\"\">Select a property</option>\n <option\n *ngFor=\"let property of valueSet?.hiddenProperties || []\"\n [value]=\"property.name\"\n >\n {{ property.name }}\n </option>\n </select>\n</div>\n" }]
6040
6296
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: CanvasProviderService }], propDecorators: { valueSet: [{
6041
6297
  type: Input
6042
6298
  }], depth: [{
@@ -6074,12 +6330,12 @@ class PropertyEditorComponent {
6074
6330
  });
6075
6331
  }
6076
6332
  }
6077
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: PropertyEditorComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
6078
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.6", type: PropertyEditorComponent, isStandalone: true, selector: "daga-property-editor", inputs: { location: "location", valueSet: "valueSet" }, viewQueries: [{ propertyName: "panel", first: true, predicate: ["panel"], descendants: true }], ngImport: i0, template: "<div #panel class=\"panel bottom {{ location }}\">\n <daga-collapse-button\n [collapsableSelector]=\"panel\"\n [collapsableAdditionalSelector]=\"'.panel-content'\"\n [rule]=\"'display'\"\n [collapsedValue]=\"'none'\"\n [visibleValue]=\"'block'\"\n [disabled]=\"\n !valueSet ||\n !valueSet.propertySet ||\n !valueSet.propertySet.hasProperties()\n \"\n />\n <div\n *ngIf=\"\n valueSet && valueSet.propertySet && valueSet.propertySet.hasProperties()\n \"\n class=\"panel-content\"\n >\n <p *ngIf=\"title\" class=\"title\">{{ title }}</p>\n <daga-object-editor [valueSet]=\"valueSet\"></daga-object-editor>\n </div>\n</div>\n", styles: [".panel{width:24rem}.title{margin:0;width:100%;font-size:1rem;font-weight:500}.panel-content{padding:1rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: CollapseButtonComponent, selector: "daga-collapse-button", inputs: ["collapsableSelector", "collapsableAdditionalSelector", "collapsed", "disabled", "direction", "rule", "collapsedValue", "visibleValue"] }, { kind: "component", type: ObjectEditorComponent, selector: "daga-object-editor", inputs: ["valueSet", "depth"] }] }); }
6333
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: PropertyEditorComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
6334
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.1.2", type: PropertyEditorComponent, isStandalone: true, selector: "daga-property-editor", inputs: { location: "location", valueSet: "valueSet" }, viewQueries: [{ propertyName: "panel", first: true, predicate: ["panel"], descendants: true }], ngImport: i0, template: "<div #panel class=\"panel bottom {{ location }}\">\n <daga-collapse-button\n [collapsableSelector]=\"panel\"\n [collapsableAdditionalSelector]=\"'.panel-content'\"\n [rule]=\"'display'\"\n [collapsedValue]=\"'none'\"\n [visibleValue]=\"'block'\"\n [disabled]=\"\n !valueSet ||\n !valueSet.propertySet ||\n !valueSet.propertySet.hasProperties()\n \"\n />\n <div\n *ngIf=\"\n valueSet && valueSet.propertySet && valueSet.propertySet.hasProperties()\n \"\n class=\"panel-content\"\n >\n <p *ngIf=\"title\" class=\"title\">{{ title }}</p>\n <daga-object-editor [valueSet]=\"valueSet\"></daga-object-editor>\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: CollapseButtonComponent, selector: "daga-collapse-button", inputs: ["collapsableSelector", "collapsableAdditionalSelector", "collapsed", "disabled", "direction", "rule", "collapsedValue", "visibleValue"] }, { kind: "component", type: ObjectEditorComponent, selector: "daga-object-editor", inputs: ["valueSet", "depth"] }] }); }
6079
6335
  }
6080
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: PropertyEditorComponent, decorators: [{
6336
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: PropertyEditorComponent, decorators: [{
6081
6337
  type: Component,
6082
- args: [{ standalone: true, selector: 'daga-property-editor', imports: [CommonModule, CollapseButtonComponent, ObjectEditorComponent], template: "<div #panel class=\"panel bottom {{ location }}\">\n <daga-collapse-button\n [collapsableSelector]=\"panel\"\n [collapsableAdditionalSelector]=\"'.panel-content'\"\n [rule]=\"'display'\"\n [collapsedValue]=\"'none'\"\n [visibleValue]=\"'block'\"\n [disabled]=\"\n !valueSet ||\n !valueSet.propertySet ||\n !valueSet.propertySet.hasProperties()\n \"\n />\n <div\n *ngIf=\"\n valueSet && valueSet.propertySet && valueSet.propertySet.hasProperties()\n \"\n class=\"panel-content\"\n >\n <p *ngIf=\"title\" class=\"title\">{{ title }}</p>\n <daga-object-editor [valueSet]=\"valueSet\"></daga-object-editor>\n </div>\n</div>\n", styles: [".panel{width:24rem}.title{margin:0;width:100%;font-size:1rem;font-weight:500}.panel-content{padding:1rem}\n"] }]
6338
+ args: [{ standalone: true, selector: 'daga-property-editor', imports: [CommonModule, CollapseButtonComponent, ObjectEditorComponent], template: "<div #panel class=\"panel bottom {{ location }}\">\n <daga-collapse-button\n [collapsableSelector]=\"panel\"\n [collapsableAdditionalSelector]=\"'.panel-content'\"\n [rule]=\"'display'\"\n [collapsedValue]=\"'none'\"\n [visibleValue]=\"'block'\"\n [disabled]=\"\n !valueSet ||\n !valueSet.propertySet ||\n !valueSet.propertySet.hasProperties()\n \"\n />\n <div\n *ngIf=\"\n valueSet && valueSet.propertySet && valueSet.propertySet.hasProperties()\n \"\n class=\"panel-content\"\n >\n <p *ngIf=\"title\" class=\"title\">{{ title }}</p>\n <daga-object-editor [valueSet]=\"valueSet\"></daga-object-editor>\n </div>\n</div>\n" }]
6083
6339
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { panel: [{
6084
6340
  type: ViewChild,
6085
6341
  args: ['panel']
@@ -6099,10 +6355,10 @@ class DagaConfigurationService {
6099
6355
  getConfig() {
6100
6356
  return this._config;
6101
6357
  }
6102
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: DagaConfigurationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
6103
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: DagaConfigurationService }); }
6358
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: DagaConfigurationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
6359
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: DagaConfigurationService }); }
6104
6360
  }
6105
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: DagaConfigurationService, decorators: [{
6361
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: DagaConfigurationService, decorators: [{
6106
6362
  type: Injectable
6107
6363
  }] });
6108
6364
 
@@ -6124,10 +6380,10 @@ class DiagramEditorComponent {
6124
6380
  ngAfterViewInit() {
6125
6381
  this.canvasProvider.initCanvasView(this.appendTo.nativeElement);
6126
6382
  }
6127
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: DiagramEditorComponent, deps: [{ token: DagaConfigurationService }, { token: CanvasProviderService }], target: i0.ɵɵFactoryTarget.Component }); }
6128
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.6", type: DiagramEditorComponent, isStandalone: true, selector: "daga-diagram-editor", viewQueries: [{ propertyName: "appendTo", first: true, predicate: ["appendTo"], descendants: true }, { propertyName: "diagramButtons", first: true, predicate: ["diagramButtons"], descendants: true }, { propertyName: "palette", first: true, predicate: ["palette"], descendants: true }, { propertyName: "propertyEditor", first: true, predicate: ["propertyEditor"], descendants: true }], ngImport: i0, template: "<div class=\"append-to\" #appendTo></div>\n<daga-diagram-buttons #diagramButtons />\n<daga-palette\n *ngIf=\"config.palettes && config.palettes.length > 0\"\n #palette\n [location]=\"Corner.TopLeft\"\n [palettes]=\"config.palettes\"\n/>\n<daga-property-editor #propertyEditor [location]=\"Corner.TopRight\" />\n<daga-errors />\n", styles: [":host,.append-to{display:block;width:100%;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: DiagramButtonsComponent, selector: "daga-diagram-buttons", inputs: ["enableFilter", "enableLayout", "enableUndoRedo", "enableZoom", "zoomRate"] }, { kind: "component", type: PaletteComponent, selector: "daga-palette", inputs: ["palettes", "currentPalette", "currentCategory", "location"] }, { kind: "component", type: PropertyEditorComponent, selector: "daga-property-editor", inputs: ["location", "valueSet"] }, { kind: "component", type: ErrorsComponent, selector: "daga-errors" }] }); }
6383
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: DiagramEditorComponent, deps: [{ token: DagaConfigurationService }, { token: CanvasProviderService }], target: i0.ɵɵFactoryTarget.Component }); }
6384
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.1.2", type: DiagramEditorComponent, isStandalone: true, selector: "daga-diagram-editor", viewQueries: [{ propertyName: "appendTo", first: true, predicate: ["appendTo"], descendants: true }, { propertyName: "diagramButtons", first: true, predicate: ["diagramButtons"], descendants: true }, { propertyName: "palette", first: true, predicate: ["palette"], descendants: true }, { propertyName: "propertyEditor", first: true, predicate: ["propertyEditor"], descendants: true }], ngImport: i0, template: "<div class=\"append-to\" #appendTo></div>\n<daga-diagram-buttons #diagramButtons />\n<daga-palette\n *ngIf=\"config.palettes && config.palettes.length > 0\"\n #palette\n [location]=\"Corner.TopLeft\"\n [palettes]=\"config.palettes\"\n/>\n<daga-property-editor #propertyEditor [location]=\"Corner.TopRight\" />\n<daga-errors />\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: DiagramButtonsComponent, selector: "daga-diagram-buttons", inputs: ["enableFilter", "enableLayout", "enableUndoRedo", "enableZoom", "zoomRate"] }, { kind: "component", type: PaletteComponent, selector: "daga-palette", inputs: ["palettes", "currentPalette", "currentCategory", "location"] }, { kind: "component", type: PropertyEditorComponent, selector: "daga-property-editor", inputs: ["location", "valueSet"] }, { kind: "component", type: ErrorsComponent, selector: "daga-errors" }] }); }
6129
6385
  }
6130
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: DiagramEditorComponent, decorators: [{
6386
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: DiagramEditorComponent, decorators: [{
6131
6387
  type: Component,
6132
6388
  args: [{ standalone: true, selector: 'daga-diagram-editor', imports: [
6133
6389
  CommonModule,
@@ -6135,7 +6391,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.6", ngImpor
6135
6391
  PaletteComponent,
6136
6392
  PropertyEditorComponent,
6137
6393
  ErrorsComponent
6138
- ], template: "<div class=\"append-to\" #appendTo></div>\n<daga-diagram-buttons #diagramButtons />\n<daga-palette\n *ngIf=\"config.palettes && config.palettes.length > 0\"\n #palette\n [location]=\"Corner.TopLeft\"\n [palettes]=\"config.palettes\"\n/>\n<daga-property-editor #propertyEditor [location]=\"Corner.TopRight\" />\n<daga-errors />\n", styles: [":host,.append-to{display:block;width:100%;height:100%}\n"] }]
6394
+ ], template: "<div class=\"append-to\" #appendTo></div>\n<daga-diagram-buttons #diagramButtons />\n<daga-palette\n *ngIf=\"config.palettes && config.palettes.length > 0\"\n #palette\n [location]=\"Corner.TopLeft\"\n [palettes]=\"config.palettes\"\n/>\n<daga-property-editor #propertyEditor [location]=\"Corner.TopRight\" />\n<daga-errors />\n" }]
6139
6395
  }], ctorParameters: () => [{ type: DagaConfigurationService }, { type: CanvasProviderService }], propDecorators: { appendTo: [{
6140
6396
  type: ViewChild,
6141
6397
  args: ['appendTo']
@@ -6162,19 +6418,24 @@ class DiagramComponent {
6162
6418
  ngOnInit() {
6163
6419
  this.configurationService.init(this.config);
6164
6420
  }
6165
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: DiagramComponent, deps: [{ token: DagaConfigurationService }, { token: CanvasProviderService }], target: i0.ɵɵFactoryTarget.Component }); }
6166
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.6", type: DiagramComponent, isStandalone: true, selector: "daga-diagram", inputs: { config: "config" }, providers: [CanvasProviderService, DagaConfigurationService], ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, styles: [":host{position:absolute;min-width:40rem;min-height:20rem}\n"] }); }
6421
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: DiagramComponent, deps: [{ token: DagaConfigurationService }, { token: CanvasProviderService }], target: i0.ɵɵFactoryTarget.Component }); }
6422
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.1.2", type: DiagramComponent, isStandalone: true, selector: "daga-diagram", inputs: { config: "config" }, providers: [CanvasProviderService, DagaConfigurationService], ngImport: i0, template: `<ng-content></ng-content>`, isInline: true }); }
6167
6423
  }
6168
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: DiagramComponent, decorators: [{
6424
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: DiagramComponent, decorators: [{
6169
6425
  type: Component,
6170
- args: [{ standalone: true, selector: 'daga-diagram', template: `<ng-content></ng-content>`, providers: [CanvasProviderService, DagaConfigurationService], styles: [":host{position:absolute;min-width:40rem;min-height:20rem}\n"] }]
6426
+ args: [{
6427
+ standalone: true,
6428
+ selector: 'daga-diagram',
6429
+ template: `<ng-content></ng-content>`,
6430
+ providers: [CanvasProviderService, DagaConfigurationService]
6431
+ }]
6171
6432
  }], ctorParameters: () => [{ type: DagaConfigurationService }, { type: CanvasProviderService }], propDecorators: { config: [{
6172
6433
  type: Input
6173
6434
  }] } });
6174
6435
 
6175
6436
  class DagaModule {
6176
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: DagaModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
6177
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.0.6", ngImport: i0, type: DagaModule, imports: [CollapseButtonComponent,
6437
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: DagaModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
6438
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.1.2", ngImport: i0, type: DagaModule, imports: [CollapseButtonComponent,
6178
6439
  DiagramButtonsComponent,
6179
6440
  DiagramComponent,
6180
6441
  DiagramEditorComponent,
@@ -6187,7 +6448,7 @@ class DagaModule {
6187
6448
  CommonModule,
6188
6449
  FormsModule,
6189
6450
  LuxModule], exports: [DiagramComponent, DiagramEditorComponent] }); }
6190
- static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: DagaModule, providers: [DagaConfigurationService, CanvasProviderService], imports: [CollapseButtonComponent,
6451
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: DagaModule, providers: [DagaConfigurationService, CanvasProviderService], imports: [CollapseButtonComponent,
6191
6452
  DiagramButtonsComponent,
6192
6453
  DiagramEditorComponent,
6193
6454
  ErrorsComponent,
@@ -6200,7 +6461,7 @@ class DagaModule {
6200
6461
  FormsModule,
6201
6462
  LuxModule] }); }
6202
6463
  }
6203
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: DagaModule, decorators: [{
6464
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: DagaModule, decorators: [{
6204
6465
  type: NgModule,
6205
6466
  args: [{
6206
6467
  declarations: [],
@@ -6315,10 +6576,10 @@ class DagaImporter {
6315
6576
  model.createdAt = new Date(data.createdAt);
6316
6577
  model.updatedAt = new Date(data.updatedAt);
6317
6578
  for (const node of data.nodes || []) {
6318
- const newNodeType = model.getNodeType(node.type);
6579
+ const newNodeType = model.nodes.types.get(node.type);
6319
6580
  if (newNodeType) {
6320
6581
  const newNode = new DiagramNode(model, newNodeType, node.coords, node.id);
6321
- model.nodes.push(newNode);
6582
+ model.nodes.add(newNode);
6322
6583
  newNode.width = node.width;
6323
6584
  newNode.height = node.height;
6324
6585
  if (node.data) {
@@ -6337,13 +6598,13 @@ class DagaImporter {
6337
6598
  ], newNode.width - labelConfiguration.margin * 2, newNode.height - labelConfiguration.margin * 2, labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, '', labelConfiguration.editable);
6338
6599
  newField.text = node.label;
6339
6600
  newNode.label = newField;
6340
- model.fields.push(newField);
6601
+ model.fields.add(newField);
6341
6602
  }
6342
6603
  }
6343
6604
  for (const section of node.sections || []) {
6344
6605
  const newSection = new DiagramSection(model, newNode, section.coords, section.width, section.height, section.id);
6345
6606
  newNode.sections?.push(newSection);
6346
- model.sections.push(newSection);
6607
+ model.sections.add(newSection);
6347
6608
  if (section.label) {
6348
6609
  // add section label
6349
6610
  if (newNodeType.sections?.label) {
@@ -6357,14 +6618,14 @@ class DagaImporter {
6357
6618
  ], newSection.width - labelConfiguration.margin * 2, newSection.height - labelConfiguration.margin * 2, labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, '', labelConfiguration.editable);
6358
6619
  newField.text = section.label;
6359
6620
  newSection.label = newField;
6360
- model.fields.push(newField);
6621
+ model.fields.add(newField);
6361
6622
  }
6362
6623
  }
6363
6624
  let portCounter = 0;
6364
6625
  for (const port of section.ports || []) {
6365
6626
  const newPort = new DiagramPort(model, newSection, port.coords, port.direction, port.id);
6366
6627
  newSection.ports.push(newPort);
6367
- model.ports.push(newPort);
6628
+ model.ports.add(newPort);
6368
6629
  if (port.label) {
6369
6630
  // add port label
6370
6631
  if (newNodeType.ports.length > portCounter &&
@@ -6400,7 +6661,7 @@ class DagaImporter {
6400
6661
  const newField = new DiagramField(model, newPort, labelCoords, labelConfiguration.fontSize, labelConfiguration.fontSize, labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, '', labelConfiguration.editable);
6401
6662
  newField.text = port.label;
6402
6663
  newPort.label = newField;
6403
- model.fields.push(newField);
6664
+ model.fields.add(newField);
6404
6665
  }
6405
6666
  ++portCounter;
6406
6667
  }
@@ -6410,7 +6671,7 @@ class DagaImporter {
6410
6671
  for (const port of node.ports || []) {
6411
6672
  const newPort = new DiagramPort(model, newNode, port.coords, port.direction, port.id);
6412
6673
  newNode.ports.push(newPort);
6413
- model.ports.push(newPort);
6674
+ model.ports.add(newPort);
6414
6675
  if (port.label) {
6415
6676
  // add port label
6416
6677
  if (newNodeType.ports.length > portCounter &&
@@ -6446,7 +6707,7 @@ class DagaImporter {
6446
6707
  const newField = new DiagramField(model, newPort, labelCoords, labelConfiguration.fontSize, labelConfiguration.fontSize, labelConfiguration.fontSize, labelConfiguration.fontFamily, labelConfiguration.color, labelConfiguration.selectedColor, labelConfiguration.horizontalAlign, labelConfiguration.verticalAlign, '', labelConfiguration.editable);
6447
6708
  newField.text = port.label;
6448
6709
  newPort.label = newField;
6449
- model.fields.push(newField);
6710
+ model.fields.add(newField);
6450
6711
  }
6451
6712
  ++portCounter;
6452
6713
  }
@@ -6454,10 +6715,10 @@ class DagaImporter {
6454
6715
  }
6455
6716
  }
6456
6717
  for (const connection of data.connections || []) {
6457
- const newConnectionType = model.getConnectionType(connection.type);
6718
+ const newConnectionType = model.connections.types.get(connection.type);
6458
6719
  if (newConnectionType) {
6459
- const newConnection = new DiagramConnection(model, newConnectionType, connection.start ? model.getPort(connection.start) : undefined, connection.end ? model.getPort(connection.end) : undefined, connection.id);
6460
- model.connections.push(newConnection);
6720
+ const newConnection = new DiagramConnection(model, newConnectionType, connection.start ? model.ports.get(connection.start) : undefined, connection.end ? model.ports.get(connection.end) : undefined, connection.id);
6721
+ model.connections.add(newConnection);
6461
6722
  newConnection.startLabel = connection.startLabel;
6462
6723
  newConnection.middleLabel = connection.middleLabel;
6463
6724
  newConnection.endLabel = connection.endLabel;
@@ -6476,5 +6737,5 @@ class DagaImporter {
6476
6737
  * Generated bundle index. Do not edit.
6477
6738
  */
6478
6739
 
6479
- export { ACTION_QUEUE_SIZE, ActionQueue, AddConnectionAction, AddNodeAction, AdjacencyLayout, BreadthAdjacencyLayout, BreadthLayout, CanvasProviderService, CollapseButtonComponent, DagaConfigurationService, DagaExporter, DagaImporter, DagaModule, DiagramButtonsComponent, DiagramCanvas, DiagramComponent, DiagramConnection, DiagramConnectionType, DiagramEditorComponent, DiagramElement, DiagramField, DiagramModel, DiagramNode, DiagramNodeType, DiagramPort, EditFieldAction, ErrorsComponent, ForceLayout, HorizontalLayout, MoveNodeAction, ObjectEditorComponent, PaletteComponent, PriorityLayout, Property, PropertyEditorComponent, PropertySet, RemoveAction, StretchNodeAction, TextListEditorComponent, TextMapEditorComponent, Type, UpdateValuesAction, ValueSet, VerticalLayout, layouts };
6740
+ export { ACTION_QUEUE_SIZE, ActionQueue, AddConnectionAction, AddNodeAction, AdjacencyLayout, BreadthAdjacencyLayout, BreadthLayout, CanvasProviderService, ClosedShape, CollapseButtonComponent, Corner, DagaConfigurationService, DagaExporter, DagaImporter, DagaModule, DiagramActions, DiagramButtonsComponent, DiagramCanvas, DiagramComponent, DiagramConnection, DiagramConnectionSet, DiagramConnectionType, DiagramEditorComponent, DiagramElement, DiagramEntitySet, DiagramField, DiagramFieldSet, DiagramModel, DiagramNode, DiagramNodeSet, DiagramNodeType, DiagramPort, DiagramPortSet, DiagramSection, DiagramSectionSet, EditFieldAction, ErrorsComponent, ForceLayout, HorizontalAlign, HorizontalLayout, LineShape, LineStyle, MoveNodeAction, ObjectEditorComponent, PaletteComponent, PriorityLayout, Property, PropertyEditorComponent, PropertySet, RemoveAction, Side, StretchNodeAction, TextListEditorComponent, TextMapEditorComponent, Type, UpdateValuesAction, ValueSet, VerticalAlign, VerticalLayout, layouts };
6480
6741
  //# sourceMappingURL=metadev-daga.mjs.map