@redvars/peacock 3.5.0 → 3.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/BaseButton-BNFAYn-S.js +219 -0
- package/dist/BaseButton-BNFAYn-S.js.map +1 -0
- package/dist/BaseHyperlinkMixin-BNuwbiEf.js +65 -0
- package/dist/BaseHyperlinkMixin-BNuwbiEf.js.map +1 -0
- package/dist/BaseInput-14YmcfK7.js +27 -0
- package/dist/BaseInput-14YmcfK7.js.map +1 -0
- package/dist/assets/components.css +1 -1
- package/dist/assets/components.css.map +1 -1
- package/dist/assets/styles.css +1 -1
- package/dist/assets/styles.css.map +1 -1
- package/dist/banner.js +14 -30
- package/dist/banner.js.map +1 -1
- package/dist/{button-DMN1dPAg.js → button-colors-Ccys3hvS.js} +5 -468
- package/dist/button-colors-Ccys3hvS.js.map +1 -0
- package/dist/button-group.js +228 -8
- package/dist/button-group.js.map +1 -1
- package/dist/button.js +294 -8
- package/dist/button.js.map +1 -1
- package/dist/calendar-column-view.js +634 -0
- package/dist/calendar-column-view.js.map +1 -0
- package/dist/calendar-event-BrQ_SEKD.js +199 -0
- package/dist/calendar-event-BrQ_SEKD.js.map +1 -0
- package/dist/calendar-month-view.js +376 -0
- package/dist/calendar-month-view.js.map +1 -0
- package/dist/calendar.js +339 -0
- package/dist/calendar.js.map +1 -0
- package/dist/canvas.js +361 -0
- package/dist/canvas.js.map +1 -0
- package/dist/card.js +18 -73
- package/dist/card.js.map +1 -1
- package/dist/cb-compound-expression.js +125 -0
- package/dist/cb-compound-expression.js.map +1 -0
- package/dist/cb-divider.js +150 -0
- package/dist/cb-divider.js.map +1 -0
- package/dist/cb-expression.js +75 -0
- package/dist/cb-expression.js.map +1 -0
- package/dist/cb-predicate.js +137 -0
- package/dist/cb-predicate.js.map +1 -0
- package/dist/chart-bar.js.map +1 -1
- package/dist/chart-doughnut.js +2 -2
- package/dist/chart-doughnut.js.map +1 -1
- package/dist/chart-pie.js +2 -2
- package/dist/chart-pie.js.map +1 -1
- package/dist/chart-stacked-bar.js.map +1 -1
- package/dist/code-editor.js +2 -1
- package/dist/code-editor.js.map +1 -1
- package/dist/code-highlighter.js +2 -1
- package/dist/code-highlighter.js.map +1 -1
- package/dist/condition-builder.js +58 -0
- package/dist/condition-builder.js.map +1 -0
- package/dist/custom-elements-jsdocs.json +10860 -5567
- package/dist/custom-elements.json +16180 -7996
- package/dist/dropdown-button.js +216 -0
- package/dist/dropdown-button.js.map +1 -0
- package/dist/event-manager-D-QCmUgR.js +113 -0
- package/dist/event-manager-D-QCmUgR.js.map +1 -0
- package/dist/fab.js +421 -9
- package/dist/fab.js.map +1 -1
- package/dist/flow-designer-dZnLJOQT.js +1656 -0
- package/dist/flow-designer-dZnLJOQT.js.map +1 -0
- package/dist/flow-designer-node-XMe-jlKg.js +548 -0
- package/dist/flow-designer-node-XMe-jlKg.js.map +1 -0
- package/dist/flow-designer-node.js +4 -0
- package/dist/flow-designer-node.js.map +1 -0
- package/dist/flow-designer.js +16 -0
- package/dist/flow-designer.js.map +1 -0
- package/dist/html-editor.js +358 -0
- package/dist/html-editor.js.map +1 -0
- package/dist/icon-button-CK1ZuE-2.js +247 -0
- package/dist/icon-button-CK1ZuE-2.js.map +1 -0
- package/dist/index.js +31 -8
- package/dist/index.js.map +1 -1
- package/dist/{is-dark-mode-DicqGkCJ.js → is-dark-mode-DOcaw4Yq.js} +2 -27
- package/dist/is-dark-mode-DOcaw4Yq.js.map +1 -0
- package/dist/modal.js +418 -0
- package/dist/modal.js.map +1 -0
- package/dist/{select-4pl4XBj7.js → navigation-rail-DyO0oAZU.js} +2000 -2767
- package/dist/navigation-rail-DyO0oAZU.js.map +1 -0
- package/dist/notification-manager.js +268 -0
- package/dist/notification-manager.js.map +1 -0
- package/dist/notification.js +3 -2
- package/dist/notification.js.map +1 -1
- package/dist/peacock-loader.js +102 -14
- package/dist/peacock-loader.js.map +1 -1
- package/dist/popover-NC7b1lTq.js +1971 -0
- package/dist/popover-NC7b1lTq.js.map +1 -0
- package/dist/popover-content.js +125 -0
- package/dist/popover-content.js.map +1 -0
- package/dist/popover.js +4 -0
- package/dist/popover.js.map +1 -0
- package/dist/search.js +4 -0
- package/dist/search.js.map +1 -1
- package/dist/split-button.js +388 -0
- package/dist/split-button.js.map +1 -0
- package/dist/src/__controllers/floating-controller.d.ts +35 -0
- package/dist/src/__mixins/BaseButtonMixin.d.ts +20 -0
- package/dist/src/__mixins/BaseHyperlinkMixin.d.ts +18 -0
- package/dist/src/__mixins/MixinConstructor.d.ts +1 -0
- package/dist/src/banner/banner.d.ts +0 -4
- package/dist/src/button/BaseButton.d.ts +4 -47
- package/dist/src/button/button/button.d.ts +32 -3
- package/dist/src/button/button-group/button-group.d.ts +2 -2
- package/dist/src/button/icon-button/icon-button.d.ts +33 -8
- package/dist/src/calendar/base-event.d.ts +10 -0
- package/dist/src/calendar/calendar-column-view.d.ts +41 -0
- package/dist/src/calendar/calendar-event.d.ts +7 -0
- package/dist/src/calendar/calendar-month-view.d.ts +31 -0
- package/dist/src/calendar/calendar.d.ts +65 -0
- package/dist/src/calendar/event-manager.d.ts +17 -0
- package/dist/src/calendar/index.d.ts +4 -0
- package/dist/src/calendar/types.d.ts +13 -0
- package/dist/src/calendar/utils.d.ts +31 -0
- package/dist/src/canvas/canvas.d.ts +92 -0
- package/dist/src/canvas/index.d.ts +2 -0
- package/dist/src/card/card.d.ts +4 -15
- package/dist/src/condition-builder/cb-compound-expression.d.ts +31 -0
- package/dist/src/condition-builder/cb-divider.d.ts +26 -0
- package/dist/src/condition-builder/cb-expression.d.ts +31 -0
- package/dist/src/condition-builder/cb-predicate.d.ts +30 -0
- package/dist/src/condition-builder/condition-builder.d.ts +27 -0
- package/dist/src/condition-builder/index.d.ts +5 -0
- package/dist/src/dropdown-button/dropdown-button.d.ts +68 -0
- package/dist/src/dropdown-button/index.d.ts +1 -0
- package/dist/src/fab/fab.d.ts +4 -35
- package/dist/src/flow-designer/commands.d.ts +66 -0
- package/dist/src/flow-designer/flow-designer-node.d.ts +46 -0
- package/dist/src/flow-designer/flow-designer.d.ts +133 -0
- package/dist/src/flow-designer/index.d.ts +7 -0
- package/dist/src/flow-designer/layout.d.ts +30 -0
- package/dist/src/flow-designer/types.d.ts +142 -0
- package/dist/src/flow-designer/validation.d.ts +43 -0
- package/dist/src/flow-designer/workflow-utils.d.ts +40 -0
- package/dist/src/focus-ring/focus-ring.d.ts +11 -5
- package/dist/src/html-editor/html-editor.d.ts +56 -0
- package/dist/src/html-editor/index.d.ts +2 -0
- package/dist/src/index.d.ts +16 -1
- package/dist/src/link/link.d.ts +1 -1
- package/dist/src/menu/menu/menu.d.ts +5 -7
- package/dist/src/menu/menu-item/menu-item.d.ts +14 -13
- package/dist/src/modal/index.d.ts +1 -0
- package/dist/src/modal/modal.d.ts +63 -0
- package/dist/src/navigation-rail/index.d.ts +2 -0
- package/dist/src/navigation-rail/navigation-rail-item.d.ts +55 -0
- package/dist/src/navigation-rail/navigation-rail.d.ts +71 -0
- package/dist/src/notification-manager/index.d.ts +1 -0
- package/dist/src/notification-manager/notification-manager.d.ts +44 -0
- package/dist/src/popover/index.d.ts +2 -0
- package/dist/src/popover/popover-content.d.ts +29 -0
- package/dist/src/popover/popover.d.ts +62 -0
- package/dist/src/sidebar-menu/index.d.ts +3 -0
- package/dist/src/sidebar-menu/sidebar-menu-item.d.ts +58 -0
- package/dist/src/sidebar-menu/sidebar-menu.d.ts +38 -0
- package/dist/src/sidebar-menu/sidebar-sub-menu.d.ts +35 -0
- package/dist/src/split-button/index.d.ts +1 -0
- package/dist/src/split-button/split-button.d.ts +72 -0
- package/dist/src/toolbar/toolbar.d.ts +10 -10
- package/dist/src/tooltip/tooltip.d.ts +5 -15
- package/dist/src/url-field/index.d.ts +1 -0
- package/dist/src/url-field/url-field.d.ts +48 -0
- package/dist/test/flow-designer.test.d.ts +1 -0
- package/dist/test/sidebar-menu.test.d.ts +1 -0
- package/dist/toolbar.js +10 -10
- package/dist/toolbar.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -2
- package/readme.md +73 -65
- package/scss/mixin.scss +16 -0
- package/src/__controllers/floating-controller.ts +237 -0
- package/src/__mixins/BaseButtonMixin.ts +83 -0
- package/src/__mixins/BaseHyperlinkMixin.ts +68 -0
- package/src/__mixins/MixinConstructor.ts +1 -0
- package/src/{__base_element → __mixins}/README.md +2 -2
- package/src/banner/banner.scss +20 -25
- package/src/banner/banner.ts +1 -7
- package/src/button/BaseButton.ts +11 -100
- package/src/button/button/button-sizes.scss +4 -2
- package/src/button/button/button.ts +77 -23
- package/src/button/button-group/button-group.ts +2 -2
- package/src/button/icon-button/icon-button.ts +75 -33
- package/src/calendar/base-event.ts +49 -0
- package/src/calendar/calendar-column-view.scss +326 -0
- package/src/calendar/calendar-column-view.ts +392 -0
- package/src/calendar/calendar-event.ts +20 -0
- package/src/calendar/calendar-month-view.scss +192 -0
- package/src/calendar/calendar-month-view.ts +244 -0
- package/src/calendar/calendar.scss +71 -0
- package/src/calendar/calendar.ts +298 -0
- package/src/calendar/event-manager.ts +117 -0
- package/src/calendar/index.ts +4 -0
- package/src/calendar/types.ts +14 -0
- package/src/calendar/utils.ts +180 -0
- package/src/canvas/canvas.scss +60 -0
- package/src/canvas/canvas.ts +391 -0
- package/src/canvas/index.ts +2 -0
- package/src/card/card.ts +11 -71
- package/src/chart-bar/chart-bar.ts +9 -14
- package/src/chart-bar/chart-stacked-bar.ts +12 -18
- package/src/chart-doughnut/chart-doughnut.ts +23 -27
- package/src/chart-pie/chart-pie.ts +19 -23
- package/src/checkbox/checkbox.scss +17 -34
- package/src/checkbox/checkbox.ts +3 -1
- package/src/code-highlighter/code-highlighter.scss +1 -0
- package/src/code-highlighter/code-highlighter.ts +1 -1
- package/src/condition-builder/cb-compound-expression.scss +37 -0
- package/src/condition-builder/cb-compound-expression.ts +80 -0
- package/src/condition-builder/cb-divider.scss +93 -0
- package/src/condition-builder/cb-divider.ts +56 -0
- package/src/condition-builder/cb-expression.scss +14 -0
- package/src/condition-builder/cb-expression.ts +49 -0
- package/src/condition-builder/cb-predicate.scss +35 -0
- package/src/condition-builder/cb-predicate.ts +102 -0
- package/src/condition-builder/condition-builder.scss +13 -0
- package/src/condition-builder/condition-builder.ts +38 -0
- package/src/condition-builder/index.ts +5 -0
- package/src/date-picker/date-picker.ts +1 -1
- package/src/dropdown-button/demo/index.html +110 -0
- package/src/dropdown-button/dropdown-button.scss +22 -0
- package/src/dropdown-button/dropdown-button.ts +206 -0
- package/src/dropdown-button/index.ts +1 -0
- package/src/elevation/elevation.scss +5 -5
- package/src/fab/fab.ts +29 -100
- package/src/flow-designer/DEMO.md +239 -0
- package/src/flow-designer/commands.ts +278 -0
- package/src/flow-designer/flow-designer-node.ts +172 -0
- package/src/flow-designer/flow-designer.scss +457 -0
- package/src/flow-designer/flow-designer.ts +611 -0
- package/src/flow-designer/index.ts +41 -0
- package/src/flow-designer/layout.ts +357 -0
- package/src/flow-designer/types.ts +166 -0
- package/src/flow-designer/validation.ts +284 -0
- package/src/flow-designer/workflow-utils.ts +282 -0
- package/src/focus-ring/focus-ring.ts +47 -40
- package/src/html-editor/html-editor.scss +146 -0
- package/src/html-editor/html-editor.ts +276 -0
- package/src/html-editor/index.ts +3 -0
- package/src/index.ts +28 -1
- package/src/input/input.ts +3 -1
- package/src/link/link.ts +2 -2
- package/src/menu/menu/menu.scss +2 -2
- package/src/menu/menu/menu.ts +91 -101
- package/src/menu/menu-item/menu-item.scss +4 -0
- package/src/menu/menu-item/menu-item.ts +85 -79
- package/src/modal/index.ts +1 -0
- package/src/modal/modal.scss +206 -0
- package/src/modal/modal.ts +201 -0
- package/src/navigation-rail/index.ts +2 -0
- package/src/navigation-rail/navigation-rail-item.scss +216 -0
- package/src/navigation-rail/navigation-rail-item.ts +223 -0
- package/src/navigation-rail/navigation-rail.scss +72 -0
- package/src/navigation-rail/navigation-rail.ts +149 -0
- package/src/notification/notification.ts +3 -2
- package/src/notification-manager/index.ts +1 -0
- package/src/notification-manager/notification-manager.scss +113 -0
- package/src/notification-manager/notification-manager.ts +199 -0
- package/src/number-field/number-field.ts +6 -4
- package/src/pagination/pagination.ts +6 -4
- package/src/peacock-loader.ts +93 -5
- package/src/popover/index.ts +2 -0
- package/src/popover/popover-content.scss +69 -0
- package/src/popover/popover-content.ts +51 -0
- package/src/popover/popover.scss +7 -0
- package/src/popover/popover.ts +170 -0
- package/src/search/search.ts +4 -0
- package/src/sidebar-menu/demo/index.html +68 -0
- package/src/sidebar-menu/index.ts +3 -0
- package/src/sidebar-menu/sidebar-menu-item.scss +102 -0
- package/src/sidebar-menu/sidebar-menu-item.ts +151 -0
- package/src/{tree-view/tree-view.scss → sidebar-menu/sidebar-menu.scss} +1 -1
- package/src/sidebar-menu/sidebar-menu.ts +182 -0
- package/src/sidebar-menu/sidebar-sub-menu.scss +130 -0
- package/src/sidebar-menu/sidebar-sub-menu.ts +160 -0
- package/src/skeleton/skeleton.scss +18 -24
- package/src/snackbar/snackbar.ts +1 -1
- package/src/split-button/index.ts +1 -0
- package/src/split-button/split-button-colors.scss +56 -0
- package/src/split-button/split-button-sizes.scss +28 -0
- package/src/split-button/split-button.scss +79 -0
- package/src/split-button/split-button.ts +236 -0
- package/src/table/table.ts +2 -2
- package/src/tabs/tab.ts +4 -3
- package/src/text/text.css-component.scss +7 -1
- package/src/time-picker/time-picker.ts +1 -1
- package/src/toolbar/toolbar.ts +10 -10
- package/src/tooltip/tooltip.scss +4 -3
- package/src/tooltip/tooltip.ts +64 -98
- package/src/url-field/index.ts +1 -0
- package/src/url-field/url-field.scss +50 -0
- package/src/url-field/url-field.ts +239 -0
- package/dist/button-DMN1dPAg.js.map +0 -1
- package/dist/button-group-CX9CUUXk.js +0 -435
- package/dist/button-group-CX9CUUXk.js.map +0 -1
- package/dist/fab-C5Nzxk0E.js +0 -497
- package/dist/fab-C5Nzxk0E.js.map +0 -1
- package/dist/is-dark-mode-DicqGkCJ.js.map +0 -1
- package/dist/select-4pl4XBj7.js.map +0 -1
- package/dist/spread-B5cgadZl.js +0 -32
- package/dist/spread-B5cgadZl.js.map +0 -1
- package/dist/src/__base_element/BaseHyperlink.d.ts +0 -20
- package/dist/src/menu/menu/MenuSurfaceController.d.ts +0 -18
- package/dist/src/tree-view/index.d.ts +0 -2
- package/dist/src/tree-view/tree-node.d.ts +0 -69
- package/dist/src/tree-view/tree-view.d.ts +0 -40
- package/dist/src/tree-view/wc-tree-view.d.ts +0 -6
- package/dist/test/tree-view.test.d.ts +0 -1
- package/dist/throttle-C7ZAPqtu.js +0 -24
- package/dist/throttle-C7ZAPqtu.js.map +0 -1
- package/src/__base_element/BaseHyperlink.ts +0 -42
- package/src/menu/menu/MenuSurfaceController.ts +0 -61
- package/src/tree-view/demo/index.html +0 -57
- package/src/tree-view/index.ts +0 -2
- package/src/tree-view/tree-node.scss +0 -101
- package/src/tree-view/tree-node.ts +0 -268
- package/src/tree-view/tree-view.ts +0 -182
- package/src/tree-view/wc-tree-view.ts +0 -9
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
import type { Workflow, WorkflowNode, WorkflowCommand } from './types.js';
|
|
2
|
+
import {
|
|
3
|
+
findNodeById,
|
|
4
|
+
cloneWorkflow,
|
|
5
|
+
removeNodeById,
|
|
6
|
+
insertNodeIntoWorkflow,
|
|
7
|
+
} from './workflow-utils.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Add Node Command
|
|
11
|
+
*/
|
|
12
|
+
export class AddNodeCommand implements WorkflowCommand {
|
|
13
|
+
description = 'Add node';
|
|
14
|
+
|
|
15
|
+
constructor(
|
|
16
|
+
private nodeToAdd: WorkflowNode,
|
|
17
|
+
private parentNodeId: string,
|
|
18
|
+
private connectionType: 'child' | 'branch' | 'task' = 'child',
|
|
19
|
+
private branchKey?: string
|
|
20
|
+
) {}
|
|
21
|
+
|
|
22
|
+
execute(workflow: Workflow): Workflow {
|
|
23
|
+
const result = cloneWorkflow(workflow);
|
|
24
|
+
const parent = findNodeById(result.nodes, this.parentNodeId);
|
|
25
|
+
if (!parent) return workflow; // Validation in parent component
|
|
26
|
+
|
|
27
|
+
insertNodeIntoWorkflow(parent, this.nodeToAdd, this.connectionType, this.branchKey);
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
undo(workflow: Workflow): Workflow {
|
|
32
|
+
const result = cloneWorkflow(workflow);
|
|
33
|
+
removeNodeById(result.nodes, this.nodeToAdd.id);
|
|
34
|
+
return result;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Delete Node Command
|
|
40
|
+
*/
|
|
41
|
+
export class DeleteNodeCommand implements WorkflowCommand {
|
|
42
|
+
description = 'Delete node';
|
|
43
|
+
private deletedNode: WorkflowNode | null = null;
|
|
44
|
+
private parentReference: {
|
|
45
|
+
parentId: string;
|
|
46
|
+
connectionType: 'child' | 'branch' | 'task';
|
|
47
|
+
branchKey?: string;
|
|
48
|
+
} | null = null;
|
|
49
|
+
|
|
50
|
+
constructor(
|
|
51
|
+
private nodeId: string,
|
|
52
|
+
workflow?: Workflow
|
|
53
|
+
) {
|
|
54
|
+
if (workflow) {
|
|
55
|
+
this.captureNodeContext(workflow);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
private captureNodeContext(workflow: Workflow) {
|
|
60
|
+
const node = findNodeById(workflow.nodes, this.nodeId);
|
|
61
|
+
if (!node) return;
|
|
62
|
+
this.deletedNode = cloneWorkflow({ workflow_id: '', nodes: node }).nodes;
|
|
63
|
+
|
|
64
|
+
// Find parent reference
|
|
65
|
+
this.findParentReference(workflow.nodes);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
private findParentReference(node: WorkflowNode) {
|
|
69
|
+
if (node.children) {
|
|
70
|
+
const idx = node.children.findIndex((n) => n.id === this.nodeId);
|
|
71
|
+
if (idx !== -1) {
|
|
72
|
+
this.parentReference = {
|
|
73
|
+
parentId: node.id,
|
|
74
|
+
connectionType: 'child',
|
|
75
|
+
};
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
for (const child of node.children) {
|
|
79
|
+
this.findParentReference(child);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (node.tasks) {
|
|
84
|
+
const idx = node.tasks.findIndex((n) => n.id === this.nodeId);
|
|
85
|
+
if (idx !== -1) {
|
|
86
|
+
this.parentReference = {
|
|
87
|
+
parentId: node.id,
|
|
88
|
+
connectionType: 'task',
|
|
89
|
+
};
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
for (const task of node.tasks) {
|
|
93
|
+
this.findParentReference(task);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (node.branches) {
|
|
98
|
+
for (const [branchKey, branchNodes] of Object.entries(node.branches)) {
|
|
99
|
+
const idx = branchNodes.findIndex((n) => n.id === this.nodeId);
|
|
100
|
+
if (idx !== -1) {
|
|
101
|
+
this.parentReference = {
|
|
102
|
+
parentId: node.id,
|
|
103
|
+
connectionType: 'branch',
|
|
104
|
+
branchKey,
|
|
105
|
+
};
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
for (const branchNode of branchNodes) {
|
|
109
|
+
this.findParentReference(branchNode);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
execute(workflow: Workflow): Workflow {
|
|
116
|
+
const result = cloneWorkflow(workflow);
|
|
117
|
+
removeNodeById(result.nodes, this.nodeId);
|
|
118
|
+
return result;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
undo(workflow: Workflow): Workflow {
|
|
122
|
+
if (!this.deletedNode || !this.parentReference) return workflow;
|
|
123
|
+
const result = cloneWorkflow(workflow);
|
|
124
|
+
const parent = findNodeById(result.nodes, this.parentReference.parentId);
|
|
125
|
+
if (!parent) return workflow;
|
|
126
|
+
|
|
127
|
+
insertNodeIntoWorkflow(
|
|
128
|
+
parent,
|
|
129
|
+
this.deletedNode,
|
|
130
|
+
this.parentReference.connectionType,
|
|
131
|
+
this.parentReference.branchKey
|
|
132
|
+
);
|
|
133
|
+
return result;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Edit Node Command
|
|
139
|
+
*/
|
|
140
|
+
export class EditNodeCommand implements WorkflowCommand {
|
|
141
|
+
description = 'Edit node';
|
|
142
|
+
private previousState: Record<string, any> = {};
|
|
143
|
+
|
|
144
|
+
constructor(
|
|
145
|
+
private nodeId: string,
|
|
146
|
+
private updates: Partial<WorkflowNode>,
|
|
147
|
+
workflow?: Workflow
|
|
148
|
+
) {
|
|
149
|
+
if (workflow) {
|
|
150
|
+
const node = findNodeById(workflow.nodes, nodeId);
|
|
151
|
+
if (node) {
|
|
152
|
+
// Store only edited fields
|
|
153
|
+
Object.keys(updates).forEach((key) => {
|
|
154
|
+
this.previousState[key] = (node as Record<string, any>)[key];
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
execute(workflow: Workflow): Workflow {
|
|
161
|
+
const result = cloneWorkflow(workflow);
|
|
162
|
+
const node = findNodeById(result.nodes, this.nodeId);
|
|
163
|
+
if (!node) return workflow;
|
|
164
|
+
|
|
165
|
+
Object.assign(node, this.updates);
|
|
166
|
+
return result;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
undo(workflow: Workflow): Workflow {
|
|
170
|
+
const result = cloneWorkflow(workflow);
|
|
171
|
+
const node = findNodeById(result.nodes, this.nodeId);
|
|
172
|
+
if (!node) return workflow;
|
|
173
|
+
|
|
174
|
+
Object.assign(node, this.previousState);
|
|
175
|
+
return result;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Move Node Command - reorder in array or change parent
|
|
181
|
+
*/
|
|
182
|
+
export class MoveNodeCommand implements WorkflowCommand {
|
|
183
|
+
description = 'Move node';
|
|
184
|
+
private previousState: {
|
|
185
|
+
parentId: string;
|
|
186
|
+
index: number;
|
|
187
|
+
connectionType: 'child' | 'branch' | 'task';
|
|
188
|
+
branchKey?: string;
|
|
189
|
+
} | null = null;
|
|
190
|
+
|
|
191
|
+
constructor(
|
|
192
|
+
private nodeId: string,
|
|
193
|
+
private newParentId: string,
|
|
194
|
+
private newIndex: number,
|
|
195
|
+
private newConnectionType: 'child' | 'branch' | 'task' = 'child',
|
|
196
|
+
private newBranchKey?: string,
|
|
197
|
+
workflow?: Workflow
|
|
198
|
+
) {
|
|
199
|
+
if (workflow) {
|
|
200
|
+
this.captureCurrentPosition(workflow);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
private captureCurrentPosition(workflow: Workflow) {
|
|
205
|
+
// Store current parent/position for undo
|
|
206
|
+
// Implementation depends on finding current parent location
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
execute(workflow: Workflow): Workflow {
|
|
210
|
+
// Remove from old parent, insert at new parent
|
|
211
|
+
let result = cloneWorkflow(workflow);
|
|
212
|
+
result.nodes = removeNodeById(result.nodes, this.nodeId);
|
|
213
|
+
const newParent = findNodeById(result.nodes, this.newParentId);
|
|
214
|
+
if (!newParent) return workflow;
|
|
215
|
+
|
|
216
|
+
const node = findNodeById(workflow.nodes, this.nodeId);
|
|
217
|
+
if (!node) return workflow;
|
|
218
|
+
|
|
219
|
+
insertNodeIntoWorkflow(
|
|
220
|
+
newParent,
|
|
221
|
+
node,
|
|
222
|
+
this.newConnectionType,
|
|
223
|
+
this.newBranchKey
|
|
224
|
+
);
|
|
225
|
+
return result;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
undo(workflow: Workflow): Workflow {
|
|
229
|
+
// Restore to previous position
|
|
230
|
+
if (!this.previousState) return workflow;
|
|
231
|
+
let result = cloneWorkflow(workflow);
|
|
232
|
+
result.nodes = removeNodeById(result.nodes, this.nodeId);
|
|
233
|
+
const prevParent = findNodeById(result.nodes, this.previousState.parentId);
|
|
234
|
+
if (!prevParent) return workflow;
|
|
235
|
+
|
|
236
|
+
const node = findNodeById(workflow.nodes, this.nodeId);
|
|
237
|
+
if (!node) return workflow;
|
|
238
|
+
|
|
239
|
+
insertNodeIntoWorkflow(
|
|
240
|
+
prevParent,
|
|
241
|
+
node,
|
|
242
|
+
this.previousState.connectionType,
|
|
243
|
+
this.previousState.branchKey
|
|
244
|
+
);
|
|
245
|
+
return result;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Batch Command - combine multiple commands into one undo/redo step
|
|
251
|
+
*/
|
|
252
|
+
export class BatchCommand implements WorkflowCommand {
|
|
253
|
+
description: string;
|
|
254
|
+
|
|
255
|
+
constructor(
|
|
256
|
+
private commands: WorkflowCommand[],
|
|
257
|
+
description: string = `Batch operation (${commands.length} steps)`
|
|
258
|
+
) {
|
|
259
|
+
this.description = description;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
execute(workflow: Workflow): Workflow {
|
|
263
|
+
let result = workflow;
|
|
264
|
+
for (const command of this.commands) {
|
|
265
|
+
result = command.execute(result);
|
|
266
|
+
}
|
|
267
|
+
return result;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
undo(workflow: Workflow): Workflow {
|
|
271
|
+
let result = workflow;
|
|
272
|
+
// Execute commands in reverse order to undo
|
|
273
|
+
for (let i = this.commands.length - 1; i >= 0; i--) {
|
|
274
|
+
result = this.commands[i].undo(result);
|
|
275
|
+
}
|
|
276
|
+
return result;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { html, LitElement, nothing } from 'lit';
|
|
2
|
+
import { property, state } from 'lit/decorators.js';
|
|
3
|
+
import IndividualComponent from '@/IndividualComponent.js';
|
|
4
|
+
import styles from './flow-designer.scss';
|
|
5
|
+
import type { WorkflowNode } from './types.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Individual node component for flow designer
|
|
9
|
+
* Renders a single workflow node with customizable slot templates
|
|
10
|
+
*
|
|
11
|
+
* @tag wc-flow-designer-node
|
|
12
|
+
* @rawTag flow-designer-node
|
|
13
|
+
* @wip true
|
|
14
|
+
*/
|
|
15
|
+
@IndividualComponent
|
|
16
|
+
export class FlowDesignerNode extends LitElement {
|
|
17
|
+
static styles = [styles];
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The workflow node to render
|
|
21
|
+
*/
|
|
22
|
+
@property({ type: Object })
|
|
23
|
+
node: WorkflowNode = { id: '', type: 'action', label: '' };
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Whether this node is currently selected
|
|
27
|
+
*/
|
|
28
|
+
@property({ type: Boolean, reflect: true, attribute: 'selected' })
|
|
29
|
+
isSelected: boolean = false;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Whether this node is in edit mode
|
|
33
|
+
*/
|
|
34
|
+
@property({ type: Boolean, reflect: true, attribute: 'editing' })
|
|
35
|
+
isEditing: boolean = false;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Whether this node is disabled
|
|
39
|
+
*/
|
|
40
|
+
@property({ type: Boolean, reflect: true })
|
|
41
|
+
disabled: boolean = false;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Whether to show the delete button
|
|
45
|
+
*/
|
|
46
|
+
@property({ type: Boolean, attribute: 'show-delete' })
|
|
47
|
+
showDelete: boolean = true;
|
|
48
|
+
|
|
49
|
+
private _handleClick = () => {
|
|
50
|
+
this.dispatchEvent(
|
|
51
|
+
new CustomEvent('node-click', {
|
|
52
|
+
detail: { nodeId: this.node.id },
|
|
53
|
+
bubbles: true,
|
|
54
|
+
composed: true,
|
|
55
|
+
})
|
|
56
|
+
);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
private _handleDoubleClick = () => {
|
|
60
|
+
this.dispatchEvent(
|
|
61
|
+
new CustomEvent('node-edit-start', {
|
|
62
|
+
detail: { nodeId: this.node.id },
|
|
63
|
+
bubbles: true,
|
|
64
|
+
composed: true,
|
|
65
|
+
})
|
|
66
|
+
);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
private _handleDelete = (e: Event) => {
|
|
70
|
+
e.stopPropagation();
|
|
71
|
+
if (confirm(`Delete "${this.node.label}"?`)) {
|
|
72
|
+
this.dispatchEvent(
|
|
73
|
+
new CustomEvent('node-delete', {
|
|
74
|
+
detail: { nodeId: this.node.id },
|
|
75
|
+
bubbles: true,
|
|
76
|
+
composed: true,
|
|
77
|
+
})
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
private _handleMouseEnter = () => {
|
|
83
|
+
// Node hover state handled via CSS
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
private _handleMouseLeave = () => {
|
|
87
|
+
// Node hover state handled via CSS
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
render() {
|
|
91
|
+
const { node, isSelected, isEditing, disabled } = this;
|
|
92
|
+
const nodeType = node.type || 'action';
|
|
93
|
+
|
|
94
|
+
return html`
|
|
95
|
+
<div
|
|
96
|
+
class="node-card ${nodeType}"
|
|
97
|
+
?selected=${isSelected}
|
|
98
|
+
?editing=${isEditing}
|
|
99
|
+
?disabled=${disabled}
|
|
100
|
+
@click=${this._handleClick}
|
|
101
|
+
@dblclick=${this._handleDoubleClick}
|
|
102
|
+
role="button"
|
|
103
|
+
tabindex="0"
|
|
104
|
+
@keydown=${(e: KeyboardEvent) => {
|
|
105
|
+
if (e.key === 'Enter' || e.key === ' ') this._handleClick();
|
|
106
|
+
}}
|
|
107
|
+
>
|
|
108
|
+
<!-- Customizable header slot -->
|
|
109
|
+
<slot name="${nodeType}-header">
|
|
110
|
+
${this._renderDefaultHeader()}
|
|
111
|
+
</slot>
|
|
112
|
+
|
|
113
|
+
<!-- Customizable body slot -->
|
|
114
|
+
<slot name="${nodeType}-body">${this._renderDefaultBody()}</slot>
|
|
115
|
+
|
|
116
|
+
<!-- Action buttons -->
|
|
117
|
+
${this.isEditing
|
|
118
|
+
? html`
|
|
119
|
+
<div class="node-actions">
|
|
120
|
+
<button class="btn-sm" @click=${this._handleDelete}>
|
|
121
|
+
Delete
|
|
122
|
+
</button>
|
|
123
|
+
</div>
|
|
124
|
+
`
|
|
125
|
+
: nothing}
|
|
126
|
+
</div>
|
|
127
|
+
`;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
private _renderDefaultHeader() {
|
|
131
|
+
const { node } = this;
|
|
132
|
+
const iconMap: Record<string, string> = {
|
|
133
|
+
trigger: 'play-circle',
|
|
134
|
+
action: 'check-circle',
|
|
135
|
+
decision: 'help-circle',
|
|
136
|
+
loop_start: 'repeat',
|
|
137
|
+
loop_end: 'repeat',
|
|
138
|
+
fork: 'git-branch',
|
|
139
|
+
join: 'git-merge',
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
const icon = iconMap[node.type] || 'activity';
|
|
143
|
+
|
|
144
|
+
return html`
|
|
145
|
+
<div class="node-header">
|
|
146
|
+
<wc-icon name=${icon} class="node-icon"></wc-icon>
|
|
147
|
+
<span class="node-title">${node.label}</span>
|
|
148
|
+
</div>
|
|
149
|
+
`;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
private _renderDefaultBody() {
|
|
153
|
+
const { node } = this;
|
|
154
|
+
return html`
|
|
155
|
+
<div class="node-body">
|
|
156
|
+
${node.description
|
|
157
|
+
? html`<p class="node-description">${node.description}</p>`
|
|
158
|
+
: nothing}
|
|
159
|
+
<div class="node-metadata">
|
|
160
|
+
<span class="node-type-tag">${node.type}</span>
|
|
161
|
+
${node.id ? html`<span class="node-id">${node.id}</span>` : nothing}
|
|
162
|
+
</div>
|
|
163
|
+
</div>
|
|
164
|
+
`;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
declare global {
|
|
169
|
+
interface HTMLElementTagNameMap {
|
|
170
|
+
'wc-flow-designer-node': FlowDesignerNode;
|
|
171
|
+
}
|
|
172
|
+
}
|