@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.
Files changed (314) hide show
  1. package/dist/BaseButton-BNFAYn-S.js +219 -0
  2. package/dist/BaseButton-BNFAYn-S.js.map +1 -0
  3. package/dist/BaseHyperlinkMixin-BNuwbiEf.js +65 -0
  4. package/dist/BaseHyperlinkMixin-BNuwbiEf.js.map +1 -0
  5. package/dist/BaseInput-14YmcfK7.js +27 -0
  6. package/dist/BaseInput-14YmcfK7.js.map +1 -0
  7. package/dist/assets/components.css +1 -1
  8. package/dist/assets/components.css.map +1 -1
  9. package/dist/assets/styles.css +1 -1
  10. package/dist/assets/styles.css.map +1 -1
  11. package/dist/banner.js +14 -30
  12. package/dist/banner.js.map +1 -1
  13. package/dist/{button-DMN1dPAg.js → button-colors-Ccys3hvS.js} +5 -468
  14. package/dist/button-colors-Ccys3hvS.js.map +1 -0
  15. package/dist/button-group.js +228 -8
  16. package/dist/button-group.js.map +1 -1
  17. package/dist/button.js +294 -8
  18. package/dist/button.js.map +1 -1
  19. package/dist/calendar-column-view.js +634 -0
  20. package/dist/calendar-column-view.js.map +1 -0
  21. package/dist/calendar-event-BrQ_SEKD.js +199 -0
  22. package/dist/calendar-event-BrQ_SEKD.js.map +1 -0
  23. package/dist/calendar-month-view.js +376 -0
  24. package/dist/calendar-month-view.js.map +1 -0
  25. package/dist/calendar.js +339 -0
  26. package/dist/calendar.js.map +1 -0
  27. package/dist/canvas.js +361 -0
  28. package/dist/canvas.js.map +1 -0
  29. package/dist/card.js +18 -73
  30. package/dist/card.js.map +1 -1
  31. package/dist/cb-compound-expression.js +125 -0
  32. package/dist/cb-compound-expression.js.map +1 -0
  33. package/dist/cb-divider.js +150 -0
  34. package/dist/cb-divider.js.map +1 -0
  35. package/dist/cb-expression.js +75 -0
  36. package/dist/cb-expression.js.map +1 -0
  37. package/dist/cb-predicate.js +137 -0
  38. package/dist/cb-predicate.js.map +1 -0
  39. package/dist/chart-bar.js.map +1 -1
  40. package/dist/chart-doughnut.js +2 -2
  41. package/dist/chart-doughnut.js.map +1 -1
  42. package/dist/chart-pie.js +2 -2
  43. package/dist/chart-pie.js.map +1 -1
  44. package/dist/chart-stacked-bar.js.map +1 -1
  45. package/dist/code-editor.js +2 -1
  46. package/dist/code-editor.js.map +1 -1
  47. package/dist/code-highlighter.js +2 -1
  48. package/dist/code-highlighter.js.map +1 -1
  49. package/dist/condition-builder.js +58 -0
  50. package/dist/condition-builder.js.map +1 -0
  51. package/dist/custom-elements-jsdocs.json +10860 -5567
  52. package/dist/custom-elements.json +16180 -7996
  53. package/dist/dropdown-button.js +216 -0
  54. package/dist/dropdown-button.js.map +1 -0
  55. package/dist/event-manager-D-QCmUgR.js +113 -0
  56. package/dist/event-manager-D-QCmUgR.js.map +1 -0
  57. package/dist/fab.js +421 -9
  58. package/dist/fab.js.map +1 -1
  59. package/dist/flow-designer-dZnLJOQT.js +1656 -0
  60. package/dist/flow-designer-dZnLJOQT.js.map +1 -0
  61. package/dist/flow-designer-node-XMe-jlKg.js +548 -0
  62. package/dist/flow-designer-node-XMe-jlKg.js.map +1 -0
  63. package/dist/flow-designer-node.js +4 -0
  64. package/dist/flow-designer-node.js.map +1 -0
  65. package/dist/flow-designer.js +16 -0
  66. package/dist/flow-designer.js.map +1 -0
  67. package/dist/html-editor.js +358 -0
  68. package/dist/html-editor.js.map +1 -0
  69. package/dist/icon-button-CK1ZuE-2.js +247 -0
  70. package/dist/icon-button-CK1ZuE-2.js.map +1 -0
  71. package/dist/index.js +31 -8
  72. package/dist/index.js.map +1 -1
  73. package/dist/{is-dark-mode-DicqGkCJ.js → is-dark-mode-DOcaw4Yq.js} +2 -27
  74. package/dist/is-dark-mode-DOcaw4Yq.js.map +1 -0
  75. package/dist/modal.js +418 -0
  76. package/dist/modal.js.map +1 -0
  77. package/dist/{select-4pl4XBj7.js → navigation-rail-DyO0oAZU.js} +2000 -2767
  78. package/dist/navigation-rail-DyO0oAZU.js.map +1 -0
  79. package/dist/notification-manager.js +268 -0
  80. package/dist/notification-manager.js.map +1 -0
  81. package/dist/notification.js +3 -2
  82. package/dist/notification.js.map +1 -1
  83. package/dist/peacock-loader.js +102 -14
  84. package/dist/peacock-loader.js.map +1 -1
  85. package/dist/popover-NC7b1lTq.js +1971 -0
  86. package/dist/popover-NC7b1lTq.js.map +1 -0
  87. package/dist/popover-content.js +125 -0
  88. package/dist/popover-content.js.map +1 -0
  89. package/dist/popover.js +4 -0
  90. package/dist/popover.js.map +1 -0
  91. package/dist/search.js +4 -0
  92. package/dist/search.js.map +1 -1
  93. package/dist/split-button.js +388 -0
  94. package/dist/split-button.js.map +1 -0
  95. package/dist/src/__controllers/floating-controller.d.ts +35 -0
  96. package/dist/src/__mixins/BaseButtonMixin.d.ts +20 -0
  97. package/dist/src/__mixins/BaseHyperlinkMixin.d.ts +18 -0
  98. package/dist/src/__mixins/MixinConstructor.d.ts +1 -0
  99. package/dist/src/banner/banner.d.ts +0 -4
  100. package/dist/src/button/BaseButton.d.ts +4 -47
  101. package/dist/src/button/button/button.d.ts +32 -3
  102. package/dist/src/button/button-group/button-group.d.ts +2 -2
  103. package/dist/src/button/icon-button/icon-button.d.ts +33 -8
  104. package/dist/src/calendar/base-event.d.ts +10 -0
  105. package/dist/src/calendar/calendar-column-view.d.ts +41 -0
  106. package/dist/src/calendar/calendar-event.d.ts +7 -0
  107. package/dist/src/calendar/calendar-month-view.d.ts +31 -0
  108. package/dist/src/calendar/calendar.d.ts +65 -0
  109. package/dist/src/calendar/event-manager.d.ts +17 -0
  110. package/dist/src/calendar/index.d.ts +4 -0
  111. package/dist/src/calendar/types.d.ts +13 -0
  112. package/dist/src/calendar/utils.d.ts +31 -0
  113. package/dist/src/canvas/canvas.d.ts +92 -0
  114. package/dist/src/canvas/index.d.ts +2 -0
  115. package/dist/src/card/card.d.ts +4 -15
  116. package/dist/src/condition-builder/cb-compound-expression.d.ts +31 -0
  117. package/dist/src/condition-builder/cb-divider.d.ts +26 -0
  118. package/dist/src/condition-builder/cb-expression.d.ts +31 -0
  119. package/dist/src/condition-builder/cb-predicate.d.ts +30 -0
  120. package/dist/src/condition-builder/condition-builder.d.ts +27 -0
  121. package/dist/src/condition-builder/index.d.ts +5 -0
  122. package/dist/src/dropdown-button/dropdown-button.d.ts +68 -0
  123. package/dist/src/dropdown-button/index.d.ts +1 -0
  124. package/dist/src/fab/fab.d.ts +4 -35
  125. package/dist/src/flow-designer/commands.d.ts +66 -0
  126. package/dist/src/flow-designer/flow-designer-node.d.ts +46 -0
  127. package/dist/src/flow-designer/flow-designer.d.ts +133 -0
  128. package/dist/src/flow-designer/index.d.ts +7 -0
  129. package/dist/src/flow-designer/layout.d.ts +30 -0
  130. package/dist/src/flow-designer/types.d.ts +142 -0
  131. package/dist/src/flow-designer/validation.d.ts +43 -0
  132. package/dist/src/flow-designer/workflow-utils.d.ts +40 -0
  133. package/dist/src/focus-ring/focus-ring.d.ts +11 -5
  134. package/dist/src/html-editor/html-editor.d.ts +56 -0
  135. package/dist/src/html-editor/index.d.ts +2 -0
  136. package/dist/src/index.d.ts +16 -1
  137. package/dist/src/link/link.d.ts +1 -1
  138. package/dist/src/menu/menu/menu.d.ts +5 -7
  139. package/dist/src/menu/menu-item/menu-item.d.ts +14 -13
  140. package/dist/src/modal/index.d.ts +1 -0
  141. package/dist/src/modal/modal.d.ts +63 -0
  142. package/dist/src/navigation-rail/index.d.ts +2 -0
  143. package/dist/src/navigation-rail/navigation-rail-item.d.ts +55 -0
  144. package/dist/src/navigation-rail/navigation-rail.d.ts +71 -0
  145. package/dist/src/notification-manager/index.d.ts +1 -0
  146. package/dist/src/notification-manager/notification-manager.d.ts +44 -0
  147. package/dist/src/popover/index.d.ts +2 -0
  148. package/dist/src/popover/popover-content.d.ts +29 -0
  149. package/dist/src/popover/popover.d.ts +62 -0
  150. package/dist/src/sidebar-menu/index.d.ts +3 -0
  151. package/dist/src/sidebar-menu/sidebar-menu-item.d.ts +58 -0
  152. package/dist/src/sidebar-menu/sidebar-menu.d.ts +38 -0
  153. package/dist/src/sidebar-menu/sidebar-sub-menu.d.ts +35 -0
  154. package/dist/src/split-button/index.d.ts +1 -0
  155. package/dist/src/split-button/split-button.d.ts +72 -0
  156. package/dist/src/toolbar/toolbar.d.ts +10 -10
  157. package/dist/src/tooltip/tooltip.d.ts +5 -15
  158. package/dist/src/url-field/index.d.ts +1 -0
  159. package/dist/src/url-field/url-field.d.ts +48 -0
  160. package/dist/test/flow-designer.test.d.ts +1 -0
  161. package/dist/test/sidebar-menu.test.d.ts +1 -0
  162. package/dist/toolbar.js +10 -10
  163. package/dist/toolbar.js.map +1 -1
  164. package/dist/tsconfig.tsbuildinfo +1 -1
  165. package/package.json +4 -2
  166. package/readme.md +73 -65
  167. package/scss/mixin.scss +16 -0
  168. package/src/__controllers/floating-controller.ts +237 -0
  169. package/src/__mixins/BaseButtonMixin.ts +83 -0
  170. package/src/__mixins/BaseHyperlinkMixin.ts +68 -0
  171. package/src/__mixins/MixinConstructor.ts +1 -0
  172. package/src/{__base_element → __mixins}/README.md +2 -2
  173. package/src/banner/banner.scss +20 -25
  174. package/src/banner/banner.ts +1 -7
  175. package/src/button/BaseButton.ts +11 -100
  176. package/src/button/button/button-sizes.scss +4 -2
  177. package/src/button/button/button.ts +77 -23
  178. package/src/button/button-group/button-group.ts +2 -2
  179. package/src/button/icon-button/icon-button.ts +75 -33
  180. package/src/calendar/base-event.ts +49 -0
  181. package/src/calendar/calendar-column-view.scss +326 -0
  182. package/src/calendar/calendar-column-view.ts +392 -0
  183. package/src/calendar/calendar-event.ts +20 -0
  184. package/src/calendar/calendar-month-view.scss +192 -0
  185. package/src/calendar/calendar-month-view.ts +244 -0
  186. package/src/calendar/calendar.scss +71 -0
  187. package/src/calendar/calendar.ts +298 -0
  188. package/src/calendar/event-manager.ts +117 -0
  189. package/src/calendar/index.ts +4 -0
  190. package/src/calendar/types.ts +14 -0
  191. package/src/calendar/utils.ts +180 -0
  192. package/src/canvas/canvas.scss +60 -0
  193. package/src/canvas/canvas.ts +391 -0
  194. package/src/canvas/index.ts +2 -0
  195. package/src/card/card.ts +11 -71
  196. package/src/chart-bar/chart-bar.ts +9 -14
  197. package/src/chart-bar/chart-stacked-bar.ts +12 -18
  198. package/src/chart-doughnut/chart-doughnut.ts +23 -27
  199. package/src/chart-pie/chart-pie.ts +19 -23
  200. package/src/checkbox/checkbox.scss +17 -34
  201. package/src/checkbox/checkbox.ts +3 -1
  202. package/src/code-highlighter/code-highlighter.scss +1 -0
  203. package/src/code-highlighter/code-highlighter.ts +1 -1
  204. package/src/condition-builder/cb-compound-expression.scss +37 -0
  205. package/src/condition-builder/cb-compound-expression.ts +80 -0
  206. package/src/condition-builder/cb-divider.scss +93 -0
  207. package/src/condition-builder/cb-divider.ts +56 -0
  208. package/src/condition-builder/cb-expression.scss +14 -0
  209. package/src/condition-builder/cb-expression.ts +49 -0
  210. package/src/condition-builder/cb-predicate.scss +35 -0
  211. package/src/condition-builder/cb-predicate.ts +102 -0
  212. package/src/condition-builder/condition-builder.scss +13 -0
  213. package/src/condition-builder/condition-builder.ts +38 -0
  214. package/src/condition-builder/index.ts +5 -0
  215. package/src/date-picker/date-picker.ts +1 -1
  216. package/src/dropdown-button/demo/index.html +110 -0
  217. package/src/dropdown-button/dropdown-button.scss +22 -0
  218. package/src/dropdown-button/dropdown-button.ts +206 -0
  219. package/src/dropdown-button/index.ts +1 -0
  220. package/src/elevation/elevation.scss +5 -5
  221. package/src/fab/fab.ts +29 -100
  222. package/src/flow-designer/DEMO.md +239 -0
  223. package/src/flow-designer/commands.ts +278 -0
  224. package/src/flow-designer/flow-designer-node.ts +172 -0
  225. package/src/flow-designer/flow-designer.scss +457 -0
  226. package/src/flow-designer/flow-designer.ts +611 -0
  227. package/src/flow-designer/index.ts +41 -0
  228. package/src/flow-designer/layout.ts +357 -0
  229. package/src/flow-designer/types.ts +166 -0
  230. package/src/flow-designer/validation.ts +284 -0
  231. package/src/flow-designer/workflow-utils.ts +282 -0
  232. package/src/focus-ring/focus-ring.ts +47 -40
  233. package/src/html-editor/html-editor.scss +146 -0
  234. package/src/html-editor/html-editor.ts +276 -0
  235. package/src/html-editor/index.ts +3 -0
  236. package/src/index.ts +28 -1
  237. package/src/input/input.ts +3 -1
  238. package/src/link/link.ts +2 -2
  239. package/src/menu/menu/menu.scss +2 -2
  240. package/src/menu/menu/menu.ts +91 -101
  241. package/src/menu/menu-item/menu-item.scss +4 -0
  242. package/src/menu/menu-item/menu-item.ts +85 -79
  243. package/src/modal/index.ts +1 -0
  244. package/src/modal/modal.scss +206 -0
  245. package/src/modal/modal.ts +201 -0
  246. package/src/navigation-rail/index.ts +2 -0
  247. package/src/navigation-rail/navigation-rail-item.scss +216 -0
  248. package/src/navigation-rail/navigation-rail-item.ts +223 -0
  249. package/src/navigation-rail/navigation-rail.scss +72 -0
  250. package/src/navigation-rail/navigation-rail.ts +149 -0
  251. package/src/notification/notification.ts +3 -2
  252. package/src/notification-manager/index.ts +1 -0
  253. package/src/notification-manager/notification-manager.scss +113 -0
  254. package/src/notification-manager/notification-manager.ts +199 -0
  255. package/src/number-field/number-field.ts +6 -4
  256. package/src/pagination/pagination.ts +6 -4
  257. package/src/peacock-loader.ts +93 -5
  258. package/src/popover/index.ts +2 -0
  259. package/src/popover/popover-content.scss +69 -0
  260. package/src/popover/popover-content.ts +51 -0
  261. package/src/popover/popover.scss +7 -0
  262. package/src/popover/popover.ts +170 -0
  263. package/src/search/search.ts +4 -0
  264. package/src/sidebar-menu/demo/index.html +68 -0
  265. package/src/sidebar-menu/index.ts +3 -0
  266. package/src/sidebar-menu/sidebar-menu-item.scss +102 -0
  267. package/src/sidebar-menu/sidebar-menu-item.ts +151 -0
  268. package/src/{tree-view/tree-view.scss → sidebar-menu/sidebar-menu.scss} +1 -1
  269. package/src/sidebar-menu/sidebar-menu.ts +182 -0
  270. package/src/sidebar-menu/sidebar-sub-menu.scss +130 -0
  271. package/src/sidebar-menu/sidebar-sub-menu.ts +160 -0
  272. package/src/skeleton/skeleton.scss +18 -24
  273. package/src/snackbar/snackbar.ts +1 -1
  274. package/src/split-button/index.ts +1 -0
  275. package/src/split-button/split-button-colors.scss +56 -0
  276. package/src/split-button/split-button-sizes.scss +28 -0
  277. package/src/split-button/split-button.scss +79 -0
  278. package/src/split-button/split-button.ts +236 -0
  279. package/src/table/table.ts +2 -2
  280. package/src/tabs/tab.ts +4 -3
  281. package/src/text/text.css-component.scss +7 -1
  282. package/src/time-picker/time-picker.ts +1 -1
  283. package/src/toolbar/toolbar.ts +10 -10
  284. package/src/tooltip/tooltip.scss +4 -3
  285. package/src/tooltip/tooltip.ts +64 -98
  286. package/src/url-field/index.ts +1 -0
  287. package/src/url-field/url-field.scss +50 -0
  288. package/src/url-field/url-field.ts +239 -0
  289. package/dist/button-DMN1dPAg.js.map +0 -1
  290. package/dist/button-group-CX9CUUXk.js +0 -435
  291. package/dist/button-group-CX9CUUXk.js.map +0 -1
  292. package/dist/fab-C5Nzxk0E.js +0 -497
  293. package/dist/fab-C5Nzxk0E.js.map +0 -1
  294. package/dist/is-dark-mode-DicqGkCJ.js.map +0 -1
  295. package/dist/select-4pl4XBj7.js.map +0 -1
  296. package/dist/spread-B5cgadZl.js +0 -32
  297. package/dist/spread-B5cgadZl.js.map +0 -1
  298. package/dist/src/__base_element/BaseHyperlink.d.ts +0 -20
  299. package/dist/src/menu/menu/MenuSurfaceController.d.ts +0 -18
  300. package/dist/src/tree-view/index.d.ts +0 -2
  301. package/dist/src/tree-view/tree-node.d.ts +0 -69
  302. package/dist/src/tree-view/tree-view.d.ts +0 -40
  303. package/dist/src/tree-view/wc-tree-view.d.ts +0 -6
  304. package/dist/test/tree-view.test.d.ts +0 -1
  305. package/dist/throttle-C7ZAPqtu.js +0 -24
  306. package/dist/throttle-C7ZAPqtu.js.map +0 -1
  307. package/src/__base_element/BaseHyperlink.ts +0 -42
  308. package/src/menu/menu/MenuSurfaceController.ts +0 -61
  309. package/src/tree-view/demo/index.html +0 -57
  310. package/src/tree-view/index.ts +0 -2
  311. package/src/tree-view/tree-node.scss +0 -101
  312. package/src/tree-view/tree-node.ts +0 -268
  313. package/src/tree-view/tree-view.ts +0 -182
  314. 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
+ }