@octaviaflow/core 3.0.18-beta.2 → 3.0.18-beta.21
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/chunk-2NGC7AI3.js +2637 -0
- package/dist/chunk-2NGC7AI3.js.map +1 -0
- package/dist/chunk-2O6K5PLY.js +2637 -0
- package/dist/chunk-2O6K5PLY.js.map +1 -0
- package/dist/chunk-2ZIOFEIS.js +3001 -0
- package/dist/chunk-2ZIOFEIS.js.map +1 -0
- package/dist/chunk-3DWB2PUF.js +2991 -0
- package/dist/chunk-3DWB2PUF.js.map +1 -0
- package/dist/chunk-4ZALUTZS.js +2936 -0
- package/dist/chunk-4ZALUTZS.js.map +1 -0
- package/dist/chunk-5ARKSRED.js +2951 -0
- package/dist/chunk-5ARKSRED.js.map +1 -0
- package/dist/chunk-5OSGSJMM.js +2981 -0
- package/dist/chunk-5OSGSJMM.js.map +1 -0
- package/dist/chunk-5YQQMEF3.js +2981 -0
- package/dist/chunk-5YQQMEF3.js.map +1 -0
- package/dist/chunk-6QCJK7H7.js +2991 -0
- package/dist/chunk-6QCJK7H7.js.map +1 -0
- package/dist/chunk-76TP67ED.js +2984 -0
- package/dist/chunk-76TP67ED.js.map +1 -0
- package/dist/chunk-A6KMO4JV.js +2949 -0
- package/dist/chunk-A6KMO4JV.js.map +1 -0
- package/dist/chunk-B7FTWSTM.js +2938 -0
- package/dist/chunk-B7FTWSTM.js.map +1 -0
- package/dist/chunk-BCO6M26F.js +2940 -0
- package/dist/chunk-BCO6M26F.js.map +1 -0
- package/dist/chunk-C3UD2AZ5.js +2637 -0
- package/dist/chunk-C3UD2AZ5.js.map +1 -0
- package/dist/chunk-CEUP4NK2.js +2850 -0
- package/dist/chunk-CEUP4NK2.js.map +1 -0
- package/dist/chunk-DBNSBJO7.js +2993 -0
- package/dist/chunk-DBNSBJO7.js.map +1 -0
- package/dist/chunk-ECIHUVU7.js +2986 -0
- package/dist/chunk-ECIHUVU7.js.map +1 -0
- package/dist/chunk-EERNYLFL.js +2860 -0
- package/dist/chunk-EERNYLFL.js.map +1 -0
- package/dist/chunk-EKFDJX4G.js +2872 -0
- package/dist/chunk-EKFDJX4G.js.map +1 -0
- package/dist/chunk-GJA3GJUZ.js +2844 -0
- package/dist/chunk-GJA3GJUZ.js.map +1 -0
- package/dist/chunk-HDOTOZNA.js +2936 -0
- package/dist/chunk-HDOTOZNA.js.map +1 -0
- package/dist/chunk-IOKUV7FD.js +2658 -0
- package/dist/chunk-IOKUV7FD.js.map +1 -0
- package/dist/chunk-IUIICQU5.js +2946 -0
- package/dist/chunk-IUIICQU5.js.map +1 -0
- package/dist/chunk-J2UYZI6D.js +2946 -0
- package/dist/chunk-J2UYZI6D.js.map +1 -0
- package/dist/chunk-J7YASALS.js +2859 -0
- package/dist/chunk-J7YASALS.js.map +1 -0
- package/dist/chunk-JIEUYBQT.js +2658 -0
- package/dist/chunk-JIEUYBQT.js.map +1 -0
- package/dist/chunk-K2H7JLQW.js +2952 -0
- package/dist/chunk-K2H7JLQW.js.map +1 -0
- package/dist/chunk-KUXYBP66.js +2953 -0
- package/dist/chunk-KUXYBP66.js.map +1 -0
- package/dist/chunk-KYMYNYFV.js +2656 -0
- package/dist/chunk-KYMYNYFV.js.map +1 -0
- package/dist/chunk-MMXL343D.js +2974 -0
- package/dist/chunk-MMXL343D.js.map +1 -0
- package/dist/chunk-MXJL3EPE.js +2986 -0
- package/dist/chunk-MXJL3EPE.js.map +1 -0
- package/dist/chunk-MYZ25B2R.js +2995 -0
- package/dist/chunk-MYZ25B2R.js.map +1 -0
- package/dist/chunk-NTMEYB7B.js +2949 -0
- package/dist/chunk-NTMEYB7B.js.map +1 -0
- package/dist/chunk-PVJXX6GP.js +2640 -0
- package/dist/chunk-PVJXX6GP.js.map +1 -0
- package/dist/chunk-Q6ERDPQR.js +2981 -0
- package/dist/chunk-Q6ERDPQR.js.map +1 -0
- package/dist/chunk-S2SSBMWJ.js +2658 -0
- package/dist/chunk-S2SSBMWJ.js.map +1 -0
- package/dist/chunk-SLVDAZSX.js +2946 -0
- package/dist/chunk-SLVDAZSX.js.map +1 -0
- package/dist/chunk-UQBPYONV.js +2991 -0
- package/dist/chunk-UQBPYONV.js.map +1 -0
- package/dist/chunk-UXMNBS22.js +2955 -0
- package/dist/chunk-UXMNBS22.js.map +1 -0
- package/dist/chunk-WEGED7TA.js +2991 -0
- package/dist/chunk-WEGED7TA.js.map +1 -0
- package/dist/chunk-WEPTBLWX.js +2847 -0
- package/dist/chunk-WEPTBLWX.js.map +1 -0
- package/dist/chunk-WG4ZQMPS.js +2844 -0
- package/dist/chunk-WG4ZQMPS.js.map +1 -0
- package/dist/chunk-XEPEBHAW.js +2808 -0
- package/dist/chunk-XEPEBHAW.js.map +1 -0
- package/dist/chunk-XG2OYFX6.js +2925 -0
- package/dist/chunk-XG2OYFX6.js.map +1 -0
- package/dist/chunk-ZAMJEU42.js +2992 -0
- package/dist/chunk-ZAMJEU42.js.map +1 -0
- package/dist/chunk-ZRAM6FXB.js +2949 -0
- package/dist/chunk-ZRAM6FXB.js.map +1 -0
- package/dist/components/CsvViewer/CsvViewer.d.ts +51 -0
- package/dist/components/CsvViewer/CsvViewer.d.ts.map +1 -0
- package/dist/components/CsvViewer/index.d.ts +2 -0
- package/dist/components/CsvViewer/index.d.ts.map +1 -0
- package/dist/components/DataTable/DataTable.d.ts +19 -1
- package/dist/components/DataTable/DataTable.d.ts.map +1 -1
- package/dist/components/DropdownMenu/DropdownMenu.d.ts +12 -2
- package/dist/components/DropdownMenu/DropdownMenu.d.ts.map +1 -1
- package/dist/components/ExecutionConsole/ExecutionConsole.d.ts +8 -2
- package/dist/components/ExecutionConsole/ExecutionConsole.d.ts.map +1 -1
- package/dist/components/FlowMinimap/FlowMinimap.d.ts +17 -1
- package/dist/components/FlowMinimap/FlowMinimap.d.ts.map +1 -1
- package/dist/components/FlowToolbar/FlowToolbar.d.ts +16 -10
- package/dist/components/FlowToolbar/FlowToolbar.d.ts.map +1 -1
- package/dist/components/JsonViewer/JsonViewer.d.ts +42 -7
- package/dist/components/JsonViewer/JsonViewer.d.ts.map +1 -1
- package/dist/components/JsonViewer/index.d.ts +1 -1
- package/dist/components/JsonViewer/index.d.ts.map +1 -1
- package/dist/components/Select/Select.d.ts.map +1 -1
- package/dist/components/WorkflowHeader/WorkflowHeader.d.ts +130 -0
- package/dist/components/WorkflowHeader/WorkflowHeader.d.ts.map +1 -0
- package/dist/components/WorkflowHeader/WorkflowHeaderExpanded.d.ts +69 -0
- package/dist/components/WorkflowHeader/WorkflowHeaderExpanded.d.ts.map +1 -0
- package/dist/components/WorkflowHeader/index.d.ts +3 -0
- package/dist/components/WorkflowHeader/index.d.ts.map +1 -0
- package/dist/components/WorkflowHeader/misc/WorkflowHeaderCentered.d.ts +40 -0
- package/dist/components/WorkflowHeader/misc/WorkflowHeaderCentered.d.ts.map +1 -0
- package/dist/components/WorkflowHeader/misc/WorkflowHeaderCommand.d.ts +39 -0
- package/dist/components/WorkflowHeader/misc/WorkflowHeaderCommand.d.ts.map +1 -0
- package/dist/components/WorkflowHeader/misc/WorkflowHeaderMinimal.d.ts +44 -0
- package/dist/components/WorkflowHeader/misc/WorkflowHeaderMinimal.d.ts.map +1 -0
- package/dist/components/WorkflowHeader/misc/WorkflowHeaderRail.d.ts +45 -0
- package/dist/components/WorkflowHeader/misc/WorkflowHeaderRail.d.ts.map +1 -0
- package/dist/components/WorkflowHeader/misc/WorkflowHeaderStudio.d.ts +48 -0
- package/dist/components/WorkflowHeader/misc/WorkflowHeaderStudio.d.ts.map +1 -0
- package/dist/components/WorkflowHeader/misc/WorkflowHeaderTiered.d.ts +52 -0
- package/dist/components/WorkflowHeader/misc/WorkflowHeaderTiered.d.ts.map +1 -0
- package/dist/components/XmlViewer/XmlViewer.d.ts +26 -1
- package/dist/components/XmlViewer/XmlViewer.d.ts.map +1 -1
- package/dist/components/XmlViewer/index.d.ts +1 -1
- package/dist/components/XmlViewer/index.d.ts.map +1 -1
- package/dist/components/YamlViewer/YamlViewer.d.ts +26 -1
- package/dist/components/YamlViewer/YamlViewer.d.ts.map +1 -1
- package/dist/components/YamlViewer/index.d.ts +1 -1
- package/dist/components/YamlViewer/index.d.ts.map +1 -1
- package/dist/hooks/useRelativeTime.d.ts +28 -0
- package/dist/hooks/useRelativeTime.d.ts.map +1 -0
- package/dist/hooks/useWorkflowRuntime.d.ts +20 -0
- package/dist/hooks/useWorkflowRuntime.d.ts.map +1 -0
- package/dist/index.cjs +4918 -3536
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +7 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4317 -3305
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/workflow/components/ConfigPanel/ConfigPanel.d.ts +27 -9
- package/dist/workflow/components/ConfigPanel/ConfigPanel.d.ts.map +1 -1
- package/dist/workflow/components/FlowCanvas/FlowCanvas.d.ts +49 -1
- package/dist/workflow/components/FlowCanvas/FlowCanvas.d.ts.map +1 -1
- package/dist/workflow/components/FlowEdge/FlowEdge.d.ts.map +1 -1
- package/dist/workflow/components/FxPanel/FxPanel.d.ts +61 -0
- package/dist/workflow/components/FxPanel/FxPanel.d.ts.map +1 -0
- package/dist/workflow/components/FxPanel/FxToggleButton.d.ts +9 -0
- package/dist/workflow/components/FxPanel/FxToggleButton.d.ts.map +1 -0
- package/dist/workflow/components/Handle/Handle.d.ts +9 -1
- package/dist/workflow/components/Handle/Handle.d.ts.map +1 -1
- package/dist/workflow/components/Handle/handleRegistry.d.ts +19 -0
- package/dist/workflow/components/Handle/handleRegistry.d.ts.map +1 -1
- package/dist/workflow/components/kinds/index.d.ts +4 -0
- package/dist/workflow/components/kinds/index.d.ts.map +1 -1
- package/dist/workflow/index.d.ts +3 -1
- package/dist/workflow/index.d.ts.map +1 -1
- package/dist/workflow/store/selectors.d.ts +12 -0
- package/dist/workflow/store/selectors.d.ts.map +1 -1
- package/dist/workflow/utils/parenting.d.ts +5 -3
- package/dist/workflow/utils/parenting.d.ts.map +1 -1
- package/dist/workflow.cjs +915 -446
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.js +309 -256
- package/dist/workflow.js.map +1 -1
- package/package.json +7 -3
package/dist/workflow.cjs
CHANGED
|
@@ -31,6 +31,8 @@ __export(workflow_exports, {
|
|
|
31
31
|
FlowEdge: () => FlowEdge,
|
|
32
32
|
FlowNode: () => FlowNode,
|
|
33
33
|
ForEachNode: () => ForEachNode,
|
|
34
|
+
FxPanel: () => FxPanel,
|
|
35
|
+
FxToggleButton: () => FxToggleButton,
|
|
34
36
|
GroupNode: () => GroupNode,
|
|
35
37
|
Handle: () => Handle,
|
|
36
38
|
HttpRequestNode: () => HttpRequestNode,
|
|
@@ -77,7 +79,8 @@ __export(workflow_exports, {
|
|
|
77
79
|
useNodeData: () => useNodeData,
|
|
78
80
|
useNodes: () => useNodes,
|
|
79
81
|
useSelection: () => useSelection,
|
|
80
|
-
useViewport: () => useViewport
|
|
82
|
+
useViewport: () => useViewport,
|
|
83
|
+
useViewportOrNull: () => useViewportOrNull
|
|
81
84
|
});
|
|
82
85
|
module.exports = __toCommonJS(workflow_exports);
|
|
83
86
|
|
|
@@ -646,6 +649,23 @@ function useEdges() {
|
|
|
646
649
|
function useViewport() {
|
|
647
650
|
return useFlowSelector((s) => s.viewport);
|
|
648
651
|
}
|
|
652
|
+
var VIEWPORT_OR_NULL_NO_STORE_SUBSCRIBE = (_cb) => () => {
|
|
653
|
+
};
|
|
654
|
+
var VIEWPORT_OR_NULL_NO_STORE_SNAPSHOT = () => null;
|
|
655
|
+
function useViewportOrNull() {
|
|
656
|
+
const store = (0, import_react5.useContext)(FlowStoreContext);
|
|
657
|
+
const { sub, snap } = (0, import_react5.useMemo)(
|
|
658
|
+
() => store ? {
|
|
659
|
+
sub: store.subscribe,
|
|
660
|
+
snap: () => store.getSnapshot().viewport
|
|
661
|
+
} : {
|
|
662
|
+
sub: VIEWPORT_OR_NULL_NO_STORE_SUBSCRIBE,
|
|
663
|
+
snap: VIEWPORT_OR_NULL_NO_STORE_SNAPSHOT
|
|
664
|
+
},
|
|
665
|
+
[store]
|
|
666
|
+
);
|
|
667
|
+
return (0, import_react5.useSyncExternalStore)(sub, snap, snap);
|
|
668
|
+
}
|
|
649
669
|
function useNodeById(id) {
|
|
650
670
|
return useFlowSelector((s) => s.nodes.find((n) => n.id === id));
|
|
651
671
|
}
|
|
@@ -708,26 +728,27 @@ var SAVE_STATE_DOT = {
|
|
|
708
728
|
function ConfigPanel({
|
|
709
729
|
open = true,
|
|
710
730
|
title,
|
|
711
|
-
kindLabel,
|
|
712
731
|
icon,
|
|
732
|
+
headerActions,
|
|
713
733
|
banner,
|
|
714
734
|
tabs,
|
|
715
735
|
activeTab: controlledActive,
|
|
716
736
|
defaultActiveTab,
|
|
717
737
|
onTabChange,
|
|
718
|
-
saveState
|
|
738
|
+
saveState,
|
|
719
739
|
onTitleChange,
|
|
720
740
|
onClose,
|
|
721
741
|
onSave,
|
|
722
742
|
onCancel,
|
|
743
|
+
padding = 12,
|
|
723
744
|
resizable = true,
|
|
724
|
-
defaultWidth =
|
|
725
|
-
minWidth =
|
|
745
|
+
defaultWidth = 400,
|
|
746
|
+
minWidth = 400,
|
|
726
747
|
maxWidth = 720,
|
|
727
748
|
maxWidthContainerInset = 80,
|
|
728
749
|
variant = "pinned",
|
|
729
750
|
children,
|
|
730
|
-
|
|
751
|
+
footerActions,
|
|
731
752
|
className,
|
|
732
753
|
style
|
|
733
754
|
}) {
|
|
@@ -824,55 +845,53 @@ function ConfigPanel({
|
|
|
824
845
|
"aria-hidden": "true"
|
|
825
846
|
}
|
|
826
847
|
),
|
|
827
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
828
|
-
|
|
829
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
"input",
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
"button",
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
] })
|
|
875
|
-
] }),
|
|
848
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("header", { className: "ods-flow-config-panel__header", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "ods-flow-config-panel__title-row", children: [
|
|
849
|
+
icon && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "ods-flow-config-panel__icon", children: icon }),
|
|
850
|
+
editingTitle ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
851
|
+
"input",
|
|
852
|
+
{
|
|
853
|
+
className: "ods-flow-config-panel__title-input",
|
|
854
|
+
value: draftTitle,
|
|
855
|
+
autoFocus: true,
|
|
856
|
+
onChange: (e) => setDraftTitle(e.target.value),
|
|
857
|
+
onBlur: () => commitTitle(draftTitle),
|
|
858
|
+
onKeyDown: titleKeyDown,
|
|
859
|
+
"aria-label": "Edit title"
|
|
860
|
+
}
|
|
861
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
862
|
+
"button",
|
|
863
|
+
{
|
|
864
|
+
type: "button",
|
|
865
|
+
className: "ods-flow-config-panel__title",
|
|
866
|
+
onDoubleClick: () => {
|
|
867
|
+
if (!onTitleChange) return;
|
|
868
|
+
setDraftTitle(title ?? "");
|
|
869
|
+
setEditingTitle(true);
|
|
870
|
+
},
|
|
871
|
+
title: onTitleChange ? "Double-click to rename" : void 0,
|
|
872
|
+
children: title ?? "Untitled"
|
|
873
|
+
}
|
|
874
|
+
),
|
|
875
|
+
headerActions && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "ods-flow-config-panel__header-actions", children: headerActions }),
|
|
876
|
+
onClose && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
877
|
+
"button",
|
|
878
|
+
{
|
|
879
|
+
type: "button",
|
|
880
|
+
className: "ods-flow-config-panel__close",
|
|
881
|
+
onClick: onClose,
|
|
882
|
+
"aria-label": "Close panel",
|
|
883
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { width: "14", height: "14", viewBox: "0 0 14 14", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
884
|
+
"path",
|
|
885
|
+
{
|
|
886
|
+
d: "M3 3l8 8M11 3l-8 8",
|
|
887
|
+
stroke: "currentColor",
|
|
888
|
+
strokeWidth: "1.5",
|
|
889
|
+
strokeLinecap: "round"
|
|
890
|
+
}
|
|
891
|
+
) })
|
|
892
|
+
}
|
|
893
|
+
)
|
|
894
|
+
] }) }),
|
|
876
895
|
tabs && tabs.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("nav", { className: "ods-flow-config-panel__tabs", role: "tablist", children: tabs.map((t) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
877
896
|
"button",
|
|
878
897
|
{
|
|
@@ -893,9 +912,17 @@ function ConfigPanel({
|
|
|
893
912
|
t.id
|
|
894
913
|
)) }),
|
|
895
914
|
banner && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "ods-flow-config-panel__banner", children: banner }),
|
|
896
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
915
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
916
|
+
"div",
|
|
917
|
+
{
|
|
918
|
+
className: "ods-flow-config-panel__body",
|
|
919
|
+
role: "tabpanel",
|
|
920
|
+
style: { padding },
|
|
921
|
+
children: tabs ? activeTab?.content : children
|
|
922
|
+
}
|
|
923
|
+
),
|
|
897
924
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("footer", { className: "ods-flow-config-panel__footer", children: [
|
|
898
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
925
|
+
saveState && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
899
926
|
"span",
|
|
900
927
|
{
|
|
901
928
|
className: cn(
|
|
@@ -915,7 +942,7 @@ function ConfigPanel({
|
|
|
915
942
|
]
|
|
916
943
|
}
|
|
917
944
|
),
|
|
918
|
-
|
|
945
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "ods-flow-config-panel__footer-actions", children: footerActions ?? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
919
946
|
onCancel && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
920
947
|
"button",
|
|
921
948
|
{
|
|
@@ -931,11 +958,11 @@ function ConfigPanel({
|
|
|
931
958
|
type: "button",
|
|
932
959
|
className: "ods-flow-config-panel__btn ods-flow-config-panel__btn--primary",
|
|
933
960
|
onClick: onSave,
|
|
934
|
-
disabled: saveState === "saving"
|
|
961
|
+
disabled: saveState === "saving",
|
|
935
962
|
children: saveState === "saving" ? "Saving\u2026" : "Save"
|
|
936
963
|
}
|
|
937
964
|
)
|
|
938
|
-
] })
|
|
965
|
+
] }) })
|
|
939
966
|
] })
|
|
940
967
|
]
|
|
941
968
|
}
|
|
@@ -943,7 +970,7 @@ function ConfigPanel({
|
|
|
943
970
|
}
|
|
944
971
|
|
|
945
972
|
// src/workflow/components/FlowCanvas/FlowCanvas.tsx
|
|
946
|
-
var
|
|
973
|
+
var import_react15 = require("react");
|
|
947
974
|
|
|
948
975
|
// src/workflow/store/createFlowStore.ts
|
|
949
976
|
var DEFAULT_VIEWPORT = { x: 0, y: 0, zoom: 1 };
|
|
@@ -1126,7 +1153,7 @@ function findContainingGroup(point, nodes, exclude = []) {
|
|
|
1126
1153
|
for (let i = nodes.length - 1; i >= 0; i--) {
|
|
1127
1154
|
const n = nodes[i];
|
|
1128
1155
|
if (exclude.includes(n.id)) continue;
|
|
1129
|
-
if (n.type !== "group") continue;
|
|
1156
|
+
if (n.type !== "group" && n.type !== "forEach") continue;
|
|
1130
1157
|
if (n.data && typeof n.data === "object" && n.data.collapsed) {
|
|
1131
1158
|
continue;
|
|
1132
1159
|
}
|
|
@@ -1336,6 +1363,9 @@ function createHandleRegistry() {
|
|
|
1336
1363
|
resolve(nodeId, type, handleId) {
|
|
1337
1364
|
return map.get(key(nodeId, type, handleId));
|
|
1338
1365
|
},
|
|
1366
|
+
all() {
|
|
1367
|
+
return Array.from(map.values());
|
|
1368
|
+
},
|
|
1339
1369
|
subscribe(listener) {
|
|
1340
1370
|
listeners.add(listener);
|
|
1341
1371
|
return () => {
|
|
@@ -1376,6 +1406,8 @@ function FlowEdgeImpl({
|
|
|
1376
1406
|
const targetDesc = registry.resolve(targetNode.id, "target", targetHandleId);
|
|
1377
1407
|
const sourceSide = sourceDesc?.side ?? sourceNode.sourcePosition ?? "bottom";
|
|
1378
1408
|
const targetSide = targetDesc?.side ?? targetNode.targetPosition ?? "top";
|
|
1409
|
+
const sourceRoute = sourceDesc?.routeSide ?? sourceSide;
|
|
1410
|
+
const targetRoute = targetDesc?.routeSide ?? targetSide;
|
|
1379
1411
|
const sourceIndex = sourceDesc?.index ?? 0;
|
|
1380
1412
|
const sourceTotal = sourceDesc?.total ?? 1;
|
|
1381
1413
|
const targetIndex = targetDesc?.index ?? 0;
|
|
@@ -1383,14 +1415,14 @@ function FlowEdgeImpl({
|
|
|
1383
1415
|
const rawStart = handleCentre(sourceNode, sourceSide, sourceIndex, sourceTotal);
|
|
1384
1416
|
const rawEnd = handleCentre(targetNode, targetSide, targetIndex, targetTotal);
|
|
1385
1417
|
const HANDLE_GAP = 8;
|
|
1386
|
-
const start = offsetAlongSide2(rawStart,
|
|
1387
|
-
const end = offsetAlongSide2(rawEnd,
|
|
1418
|
+
const start = offsetAlongSide2(rawStart, sourceRoute, HANDLE_GAP);
|
|
1419
|
+
const end = offsetAlongSide2(rawEnd, targetRoute, HANDLE_GAP);
|
|
1388
1420
|
const routing = edge.routing ?? "bezier";
|
|
1389
|
-
const { d, midX, midY } = buildEdgePath(routing, start,
|
|
1421
|
+
const { d, midX, midY } = buildEdgePath(routing, start, sourceRoute, end, targetRoute, {
|
|
1390
1422
|
curvature,
|
|
1391
1423
|
borderRadius
|
|
1392
1424
|
});
|
|
1393
|
-
const { d: hitD } = buildEdgePath(routing, rawStart,
|
|
1425
|
+
const { d: hitD } = buildEdgePath(routing, rawStart, sourceRoute, rawEnd, targetRoute, {
|
|
1394
1426
|
curvature,
|
|
1395
1427
|
borderRadius
|
|
1396
1428
|
});
|
|
@@ -1437,6 +1469,12 @@ function FlowEdgeImpl({
|
|
|
1437
1469
|
e.stopPropagation();
|
|
1438
1470
|
onSelect?.(edge.id);
|
|
1439
1471
|
},
|
|
1472
|
+
onDoubleClick: (e) => {
|
|
1473
|
+
if (!onLabelChange) return;
|
|
1474
|
+
e.stopPropagation();
|
|
1475
|
+
setDraftLabel(edge.label ?? "");
|
|
1476
|
+
setEditing(true);
|
|
1477
|
+
},
|
|
1440
1478
|
children: [
|
|
1441
1479
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1442
1480
|
"marker",
|
|
@@ -1708,6 +1746,7 @@ var DEFAULT_HANDLE_ID = "default";
|
|
|
1708
1746
|
function Handle({
|
|
1709
1747
|
type,
|
|
1710
1748
|
position,
|
|
1749
|
+
routeSide,
|
|
1711
1750
|
id = DEFAULT_HANDLE_ID,
|
|
1712
1751
|
isConnectable = true,
|
|
1713
1752
|
isConnectableStart,
|
|
@@ -1730,11 +1769,14 @@ function Handle({
|
|
|
1730
1769
|
handleId: id,
|
|
1731
1770
|
type,
|
|
1732
1771
|
side: position,
|
|
1772
|
+
routeSide: routeSide ?? position,
|
|
1733
1773
|
index,
|
|
1734
|
-
total
|
|
1774
|
+
total,
|
|
1775
|
+
canStart,
|
|
1776
|
+
canEnd
|
|
1735
1777
|
});
|
|
1736
1778
|
return dispose;
|
|
1737
|
-
}, [registry, node.id, id, type, position, index, total]);
|
|
1779
|
+
}, [registry, node.id, id, type, position, routeSide, index, total, canStart, canEnd]);
|
|
1738
1780
|
const handlePointerDown = (e) => {
|
|
1739
1781
|
if (!canStart) return;
|
|
1740
1782
|
e.stopPropagation();
|
|
@@ -1791,10 +1833,155 @@ function handleSideStyle(side, index, total) {
|
|
|
1791
1833
|
}
|
|
1792
1834
|
}
|
|
1793
1835
|
|
|
1794
|
-
// src/workflow/components/
|
|
1795
|
-
var import_icons = require("@octaviaflow/icons");
|
|
1836
|
+
// src/workflow/components/NodeResizer/NodeResizer.tsx
|
|
1796
1837
|
var import_react13 = require("react");
|
|
1797
1838
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
1839
|
+
function NodeResizer({
|
|
1840
|
+
isVisible,
|
|
1841
|
+
minWidth = 80,
|
|
1842
|
+
minHeight = 60,
|
|
1843
|
+
maxWidth,
|
|
1844
|
+
maxHeight,
|
|
1845
|
+
keepAspectRatio = false,
|
|
1846
|
+
onResize,
|
|
1847
|
+
onResizeEnd,
|
|
1848
|
+
color
|
|
1849
|
+
}) {
|
|
1850
|
+
const { node, selected } = useFlowNodeContext();
|
|
1851
|
+
const viewport = useViewport();
|
|
1852
|
+
const flow = useFlow();
|
|
1853
|
+
const dragRef = (0, import_react13.useRef)(null);
|
|
1854
|
+
const show = isVisible ?? selected;
|
|
1855
|
+
if (!show) return null;
|
|
1856
|
+
const beginResize = (e, corner) => {
|
|
1857
|
+
e.preventDefault();
|
|
1858
|
+
e.stopPropagation();
|
|
1859
|
+
e.target.setPointerCapture(e.pointerId);
|
|
1860
|
+
const w = node.width ?? DEFAULT_NODE_WIDTH;
|
|
1861
|
+
const h = node.height ?? DEFAULT_NODE_HEIGHT;
|
|
1862
|
+
dragRef.current = {
|
|
1863
|
+
pointerId: e.pointerId,
|
|
1864
|
+
corner,
|
|
1865
|
+
startClientX: e.clientX,
|
|
1866
|
+
startClientY: e.clientY,
|
|
1867
|
+
startWidth: w,
|
|
1868
|
+
startHeight: h,
|
|
1869
|
+
startX: node.position.x,
|
|
1870
|
+
startY: node.position.y,
|
|
1871
|
+
aspect: w / Math.max(1, h)
|
|
1872
|
+
};
|
|
1873
|
+
};
|
|
1874
|
+
const onMove = (e) => {
|
|
1875
|
+
const drag = dragRef.current;
|
|
1876
|
+
if (!drag || drag.pointerId !== e.pointerId) return;
|
|
1877
|
+
const dx = (e.clientX - drag.startClientX) / viewport.zoom;
|
|
1878
|
+
const dy = (e.clientY - drag.startClientY) / viewport.zoom;
|
|
1879
|
+
let nextW = drag.startWidth;
|
|
1880
|
+
let nextH = drag.startHeight;
|
|
1881
|
+
let nextX = drag.startX;
|
|
1882
|
+
let nextY = drag.startY;
|
|
1883
|
+
switch (drag.corner) {
|
|
1884
|
+
case "se":
|
|
1885
|
+
nextW = drag.startWidth + dx;
|
|
1886
|
+
nextH = drag.startHeight + dy;
|
|
1887
|
+
break;
|
|
1888
|
+
case "sw":
|
|
1889
|
+
nextW = drag.startWidth - dx;
|
|
1890
|
+
nextH = drag.startHeight + dy;
|
|
1891
|
+
nextX = drag.startX + dx;
|
|
1892
|
+
break;
|
|
1893
|
+
case "ne":
|
|
1894
|
+
nextW = drag.startWidth + dx;
|
|
1895
|
+
nextH = drag.startHeight - dy;
|
|
1896
|
+
nextY = drag.startY + dy;
|
|
1897
|
+
break;
|
|
1898
|
+
case "nw":
|
|
1899
|
+
nextW = drag.startWidth - dx;
|
|
1900
|
+
nextH = drag.startHeight - dy;
|
|
1901
|
+
nextX = drag.startX + dx;
|
|
1902
|
+
nextY = drag.startY + dy;
|
|
1903
|
+
break;
|
|
1904
|
+
}
|
|
1905
|
+
if (keepAspectRatio) {
|
|
1906
|
+
nextH = nextW / drag.aspect;
|
|
1907
|
+
if (drag.corner === "nw" || drag.corner === "ne") {
|
|
1908
|
+
nextY = drag.startY + (drag.startHeight - nextH);
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1911
|
+
nextW = Math.max(minWidth, maxWidth ? Math.min(maxWidth, nextW) : nextW);
|
|
1912
|
+
nextH = Math.max(minHeight, maxHeight ? Math.min(maxHeight, nextH) : nextH);
|
|
1913
|
+
flow.updateNode(node.id, {
|
|
1914
|
+
width: nextW,
|
|
1915
|
+
height: nextH,
|
|
1916
|
+
position: { x: nextX, y: nextY }
|
|
1917
|
+
});
|
|
1918
|
+
onResize?.({ width: nextW, height: nextH });
|
|
1919
|
+
};
|
|
1920
|
+
const onUp = (e) => {
|
|
1921
|
+
if (dragRef.current?.pointerId === e.pointerId) {
|
|
1922
|
+
const cur = flow.getNode(node.id);
|
|
1923
|
+
if (cur) {
|
|
1924
|
+
onResizeEnd?.({
|
|
1925
|
+
width: cur.width ?? DEFAULT_NODE_WIDTH,
|
|
1926
|
+
height: cur.height ?? DEFAULT_NODE_HEIGHT
|
|
1927
|
+
});
|
|
1928
|
+
}
|
|
1929
|
+
dragRef.current = null;
|
|
1930
|
+
}
|
|
1931
|
+
};
|
|
1932
|
+
const handleColor = color ?? "var(--ods-accent)";
|
|
1933
|
+
const handleStyle = (corner) => {
|
|
1934
|
+
const base = {
|
|
1935
|
+
position: "absolute",
|
|
1936
|
+
width: 12,
|
|
1937
|
+
height: 12,
|
|
1938
|
+
background: "var(--ods-surface-canvas)",
|
|
1939
|
+
border: `2px solid ${handleColor}`,
|
|
1940
|
+
borderRadius: 2,
|
|
1941
|
+
cursor: cursorFor(corner),
|
|
1942
|
+
touchAction: "none",
|
|
1943
|
+
// Place each handle so its CENTRE sits on the corresponding corner.
|
|
1944
|
+
transform: "translate(-50%, -50%)"
|
|
1945
|
+
};
|
|
1946
|
+
switch (corner) {
|
|
1947
|
+
case "nw":
|
|
1948
|
+
return { ...base, top: 0, left: 0 };
|
|
1949
|
+
case "ne":
|
|
1950
|
+
return { ...base, top: 0, left: "100%" };
|
|
1951
|
+
case "sw":
|
|
1952
|
+
return { ...base, top: "100%", left: 0 };
|
|
1953
|
+
case "se":
|
|
1954
|
+
return { ...base, top: "100%", left: "100%" };
|
|
1955
|
+
}
|
|
1956
|
+
};
|
|
1957
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: cn("ods-node-resizer"), "data-flow-no-drag": "true", children: ["nw", "ne", "sw", "se"].map((corner) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
1958
|
+
"div",
|
|
1959
|
+
{
|
|
1960
|
+
style: handleStyle(corner),
|
|
1961
|
+
onPointerDown: (e) => beginResize(e, corner),
|
|
1962
|
+
onPointerMove: onMove,
|
|
1963
|
+
onPointerUp: onUp,
|
|
1964
|
+
onPointerCancel: onUp,
|
|
1965
|
+
"aria-label": `Resize ${corner}`
|
|
1966
|
+
},
|
|
1967
|
+
corner
|
|
1968
|
+
)) });
|
|
1969
|
+
}
|
|
1970
|
+
function cursorFor(corner) {
|
|
1971
|
+
switch (corner) {
|
|
1972
|
+
case "nw":
|
|
1973
|
+
case "se":
|
|
1974
|
+
return "nwse-resize";
|
|
1975
|
+
case "ne":
|
|
1976
|
+
case "sw":
|
|
1977
|
+
return "nesw-resize";
|
|
1978
|
+
}
|
|
1979
|
+
}
|
|
1980
|
+
|
|
1981
|
+
// src/workflow/components/kinds/BaseNode.tsx
|
|
1982
|
+
var import_icons = require("@octaviaflow/icons");
|
|
1983
|
+
var import_react14 = require("react");
|
|
1984
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1798
1985
|
function BaseNode({
|
|
1799
1986
|
kind,
|
|
1800
1987
|
kindIcon,
|
|
@@ -1810,10 +1997,10 @@ function BaseNode({
|
|
|
1810
1997
|
className,
|
|
1811
1998
|
children
|
|
1812
1999
|
}) {
|
|
1813
|
-
const ctx = (0,
|
|
1814
|
-
const bridge = (0,
|
|
2000
|
+
const ctx = (0, import_react14.useContext)(FlowNodeContext);
|
|
2001
|
+
const bridge = (0, import_react14.useContext)(FlowNodeBridgeContext);
|
|
1815
2002
|
const deleteHandler = onDelete === false ? void 0 : onDelete ?? (ctx && bridge ? () => bridge.deleteNode(ctx.id) : void 0);
|
|
1816
|
-
return /* @__PURE__ */ (0,
|
|
2003
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
1817
2004
|
"div",
|
|
1818
2005
|
{
|
|
1819
2006
|
className: cn(
|
|
@@ -1823,31 +2010,31 @@ function BaseNode({
|
|
|
1823
2010
|
className
|
|
1824
2011
|
),
|
|
1825
2012
|
children: [
|
|
1826
|
-
/* @__PURE__ */ (0,
|
|
1827
|
-
kindIcon && /* @__PURE__ */ (0,
|
|
1828
|
-
/* @__PURE__ */ (0,
|
|
2013
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "ods-flow-base-node__pill", children: [
|
|
2014
|
+
kindIcon && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "ods-flow-base-node__pill-icon", "aria-hidden": "true", children: kindIcon }),
|
|
2015
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "ods-flow-base-node__pill-label", children: kind })
|
|
1829
2016
|
] }),
|
|
1830
|
-
status && status !== "idle" && /* @__PURE__ */ (0,
|
|
2017
|
+
status && status !== "idle" && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1831
2018
|
"span",
|
|
1832
2019
|
{
|
|
1833
2020
|
className: cn("ods-flow-base-node__status", `ods-flow-base-node__status--${status}`),
|
|
1834
2021
|
"aria-hidden": "true"
|
|
1835
2022
|
}
|
|
1836
2023
|
),
|
|
1837
|
-
/* @__PURE__ */ (0,
|
|
1838
|
-
/* @__PURE__ */ (0,
|
|
1839
|
-
/* @__PURE__ */ (0,
|
|
1840
|
-
/* @__PURE__ */ (0,
|
|
1841
|
-
/* @__PURE__ */ (0,
|
|
1842
|
-
(chip !== void 0 || description !== void 0 || valueChip !== void 0) && /* @__PURE__ */ (0,
|
|
1843
|
-
chip !== void 0 && /* @__PURE__ */ (0,
|
|
1844
|
-
description !== void 0 && /* @__PURE__ */ (0,
|
|
1845
|
-
valueChip !== void 0 && /* @__PURE__ */ (0,
|
|
2024
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "ods-flow-base-node__body", children: [
|
|
2025
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "ods-flow-base-node__content", children: [
|
|
2026
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "ods-flow-base-node__bubble", "aria-hidden": "true", children: icon }),
|
|
2027
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "ods-flow-base-node__content-text", children: [
|
|
2028
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "ods-flow-base-node__content-title", children: title }),
|
|
2029
|
+
(chip !== void 0 || description !== void 0 || valueChip !== void 0) && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "ods-flow-base-node__content-info", children: [
|
|
2030
|
+
chip !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "ods-flow-base-node__chip", children: chip }),
|
|
2031
|
+
description !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "ods-flow-base-node__description", children: description }),
|
|
2032
|
+
valueChip !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "ods-flow-base-node__value-chip", children: valueChip })
|
|
1846
2033
|
] })
|
|
1847
2034
|
] })
|
|
1848
2035
|
] }),
|
|
1849
|
-
footer && /* @__PURE__ */ (0,
|
|
1850
|
-
deleteHandler && /* @__PURE__ */ (0,
|
|
2036
|
+
footer && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "ods-flow-base-node__footer", children: footer }),
|
|
2037
|
+
deleteHandler && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1851
2038
|
"button",
|
|
1852
2039
|
{
|
|
1853
2040
|
type: "button",
|
|
@@ -1859,7 +2046,7 @@ function BaseNode({
|
|
|
1859
2046
|
"aria-label": "Delete node",
|
|
1860
2047
|
"data-flow-no-drag": "true",
|
|
1861
2048
|
title: "Delete node",
|
|
1862
|
-
children: /* @__PURE__ */ (0,
|
|
2049
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_icons.TrashCanIcon, { size: 16, "aria-hidden": true })
|
|
1863
2050
|
}
|
|
1864
2051
|
)
|
|
1865
2052
|
] }),
|
|
@@ -1870,12 +2057,12 @@ function BaseNode({
|
|
|
1870
2057
|
}
|
|
1871
2058
|
|
|
1872
2059
|
// src/workflow/components/kinds/index.tsx
|
|
1873
|
-
var
|
|
2060
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1874
2061
|
var ActionNode = ({
|
|
1875
2062
|
node
|
|
1876
2063
|
}) => {
|
|
1877
2064
|
const d = node.data ?? {};
|
|
1878
|
-
return /* @__PURE__ */ (0,
|
|
2065
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1879
2066
|
BaseNode,
|
|
1880
2067
|
{
|
|
1881
2068
|
kind: d.kind ?? "ACTION",
|
|
@@ -1887,8 +2074,8 @@ var ActionNode = ({
|
|
|
1887
2074
|
status: d.status,
|
|
1888
2075
|
accent: "green",
|
|
1889
2076
|
children: [
|
|
1890
|
-
/* @__PURE__ */ (0,
|
|
1891
|
-
/* @__PURE__ */ (0,
|
|
2077
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Handle, { type: "target", position: "top" }),
|
|
2078
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Handle, { type: "source", position: "bottom" })
|
|
1892
2079
|
]
|
|
1893
2080
|
}
|
|
1894
2081
|
);
|
|
@@ -1897,7 +2084,7 @@ var TriggerNode = ({
|
|
|
1897
2084
|
node
|
|
1898
2085
|
}) => {
|
|
1899
2086
|
const d = node.data ?? {};
|
|
1900
|
-
return /* @__PURE__ */ (0,
|
|
2087
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1901
2088
|
BaseNode,
|
|
1902
2089
|
{
|
|
1903
2090
|
kind: d.kind ?? "TRIGGER",
|
|
@@ -1908,7 +2095,7 @@ var TriggerNode = ({
|
|
|
1908
2095
|
valueChip: d.valueChip,
|
|
1909
2096
|
status: d.status,
|
|
1910
2097
|
accent: "green",
|
|
1911
|
-
children: /* @__PURE__ */ (0,
|
|
2098
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Handle, { type: "source", position: "bottom" })
|
|
1912
2099
|
}
|
|
1913
2100
|
);
|
|
1914
2101
|
};
|
|
@@ -1920,7 +2107,7 @@ var ConditionNode = ({
|
|
|
1920
2107
|
{ id: "true", label: "true" },
|
|
1921
2108
|
{ id: "false", label: "false" }
|
|
1922
2109
|
];
|
|
1923
|
-
return /* @__PURE__ */ (0,
|
|
2110
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1924
2111
|
BaseNode,
|
|
1925
2112
|
{
|
|
1926
2113
|
kind: d.kind ?? "CONDITION",
|
|
@@ -1932,8 +2119,8 @@ var ConditionNode = ({
|
|
|
1932
2119
|
status: d.status,
|
|
1933
2120
|
accent: "amber",
|
|
1934
2121
|
children: [
|
|
1935
|
-
/* @__PURE__ */ (0,
|
|
1936
|
-
branches.map((b, i) => /* @__PURE__ */ (0,
|
|
2122
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Handle, { type: "target", position: "top" }),
|
|
2123
|
+
branches.map((b, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1937
2124
|
Handle,
|
|
1938
2125
|
{
|
|
1939
2126
|
type: "source",
|
|
@@ -1954,24 +2141,27 @@ var GroupNode = ({
|
|
|
1954
2141
|
}) => {
|
|
1955
2142
|
const d = node.data ?? {};
|
|
1956
2143
|
const collapsed = !!d.collapsed;
|
|
2144
|
+
const disabled = !!d.disabled;
|
|
1957
2145
|
const hiddenCount = d.hiddenCount;
|
|
1958
2146
|
const bridge = useFlowNodeBridge();
|
|
1959
2147
|
const onChevronClick = (e) => {
|
|
1960
2148
|
e.stopPropagation();
|
|
1961
2149
|
bridge.toggleNodeCollapse(node.id);
|
|
1962
2150
|
};
|
|
1963
|
-
return /* @__PURE__ */ (0,
|
|
2151
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
1964
2152
|
"div",
|
|
1965
2153
|
{
|
|
1966
2154
|
className: "ods-flow-group",
|
|
1967
2155
|
"data-collapsed": collapsed ? "true" : "false",
|
|
2156
|
+
"data-disabled": disabled ? "true" : void 0,
|
|
1968
2157
|
style: {
|
|
1969
2158
|
width: node.width ?? 360,
|
|
1970
2159
|
height: collapsed ? 36 : node.height ?? 200
|
|
1971
2160
|
},
|
|
1972
2161
|
children: [
|
|
1973
|
-
/* @__PURE__ */ (0,
|
|
1974
|
-
|
|
2162
|
+
!collapsed && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(NodeResizer, { minWidth: 240, minHeight: 120 }),
|
|
2163
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "ods-flow-group__header", "data-flow-no-drag": "false", children: [
|
|
2164
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1975
2165
|
"button",
|
|
1976
2166
|
{
|
|
1977
2167
|
type: "button",
|
|
@@ -1984,15 +2174,16 @@ var GroupNode = ({
|
|
|
1984
2174
|
children: collapsed ? "\u25B8" : "\u25BE"
|
|
1985
2175
|
}
|
|
1986
2176
|
),
|
|
1987
|
-
/* @__PURE__ */ (0,
|
|
1988
|
-
d.subtitle && /* @__PURE__ */ (0,
|
|
1989
|
-
|
|
2177
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "ods-flow-group__title", children: d.title ?? "Group" }),
|
|
2178
|
+
d.subtitle && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "ods-flow-group__subtitle", children: d.subtitle }),
|
|
2179
|
+
disabled && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "ods-flow-group__disabled-badge", "aria-label": "Disabled subflow", children: "Disabled" }),
|
|
2180
|
+
collapsed && hiddenCount !== void 0 && hiddenCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "ods-flow-group__count", "aria-label": `${hiddenCount} hidden steps`, children: [
|
|
1990
2181
|
hiddenCount,
|
|
1991
2182
|
" steps"
|
|
1992
2183
|
] })
|
|
1993
2184
|
] }),
|
|
1994
|
-
/* @__PURE__ */ (0,
|
|
1995
|
-
/* @__PURE__ */ (0,
|
|
2185
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Handle, { type: "target", position: "top", id: "__group_in" }),
|
|
2186
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Handle, { type: "source", position: "bottom", id: "__group_out" })
|
|
1996
2187
|
]
|
|
1997
2188
|
}
|
|
1998
2189
|
);
|
|
@@ -2003,24 +2194,27 @@ var ForEachNode = ({
|
|
|
2003
2194
|
const d = node.data ?? {};
|
|
2004
2195
|
const iteratorExpr = d.iterator ?? d.description ?? "items[]";
|
|
2005
2196
|
const collapsed = !!d.collapsed;
|
|
2197
|
+
const disabled = !!d.disabled;
|
|
2006
2198
|
const hiddenCount = d.hiddenCount;
|
|
2007
2199
|
const bridge = useFlowNodeBridge();
|
|
2008
2200
|
const onChevronClick = (e) => {
|
|
2009
2201
|
e.stopPropagation();
|
|
2010
2202
|
bridge.toggleNodeCollapse(node.id);
|
|
2011
2203
|
};
|
|
2012
|
-
return /* @__PURE__ */ (0,
|
|
2204
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
2013
2205
|
"div",
|
|
2014
2206
|
{
|
|
2015
2207
|
className: "ods-flow-foreach",
|
|
2016
2208
|
"data-collapsed": collapsed ? "true" : "false",
|
|
2209
|
+
"data-disabled": disabled ? "true" : void 0,
|
|
2017
2210
|
style: {
|
|
2018
2211
|
width: node.width ?? 420,
|
|
2019
2212
|
height: collapsed ? 40 : node.height ?? 260
|
|
2020
2213
|
},
|
|
2021
2214
|
children: [
|
|
2022
|
-
/* @__PURE__ */ (0,
|
|
2023
|
-
|
|
2215
|
+
!collapsed && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(NodeResizer, { minWidth: 240, minHeight: 120 }),
|
|
2216
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "ods-flow-foreach__header", children: [
|
|
2217
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2024
2218
|
"button",
|
|
2025
2219
|
{
|
|
2026
2220
|
type: "button",
|
|
@@ -2033,24 +2227,57 @@ var ForEachNode = ({
|
|
|
2033
2227
|
children: collapsed ? "\u25B8" : "\u25BE"
|
|
2034
2228
|
}
|
|
2035
2229
|
),
|
|
2036
|
-
/* @__PURE__ */ (0,
|
|
2037
|
-
/* @__PURE__ */ (0,
|
|
2038
|
-
/* @__PURE__ */ (0,
|
|
2039
|
-
|
|
2230
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "ods-flow-foreach__icon", "aria-hidden": "true", children: "\u21BB" }),
|
|
2231
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "ods-flow-foreach__title", children: d.title ?? "For each" }),
|
|
2232
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("code", { className: "ods-flow-foreach__iterator", children: iteratorExpr }),
|
|
2233
|
+
disabled && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2234
|
+
"span",
|
|
2235
|
+
{
|
|
2236
|
+
className: "ods-flow-foreach__disabled-badge",
|
|
2237
|
+
"aria-label": "Disabled subflow",
|
|
2238
|
+
children: "Disabled"
|
|
2239
|
+
}
|
|
2240
|
+
),
|
|
2241
|
+
collapsed && hiddenCount !== void 0 && hiddenCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "ods-flow-foreach__count", "aria-label": `${hiddenCount} hidden steps`, children: [
|
|
2040
2242
|
hiddenCount,
|
|
2041
2243
|
" steps"
|
|
2042
2244
|
] })
|
|
2043
2245
|
] }),
|
|
2044
|
-
/* @__PURE__ */ (0,
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2246
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Handle, { type: "target", position: "top", id: "__group_in", label: !collapsed ? "in" : void 0 }),
|
|
2247
|
+
collapsed ? (
|
|
2248
|
+
// Collapsed: single bottom exit so the container behaves like a
|
|
2249
|
+
// regular action in the chain.
|
|
2250
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Handle, { type: "source", position: "bottom", id: "__group_out" })
|
|
2251
|
+
) : (
|
|
2252
|
+
// Expanded: two bottom outputs spread across the bottom edge.
|
|
2253
|
+
// Index/total tell the Handle to position them at 33% and 66%
|
|
2254
|
+
// along the edge (per `handleSideStyle`). `each` is left of
|
|
2255
|
+
// centre, `__group_out` (labelled "done") is right of centre.
|
|
2256
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
2257
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2258
|
+
Handle,
|
|
2259
|
+
{
|
|
2260
|
+
type: "source",
|
|
2261
|
+
position: "bottom",
|
|
2262
|
+
id: "each",
|
|
2263
|
+
label: "each",
|
|
2264
|
+
index: 0,
|
|
2265
|
+
total: 2
|
|
2266
|
+
}
|
|
2267
|
+
),
|
|
2268
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2269
|
+
Handle,
|
|
2270
|
+
{
|
|
2271
|
+
type: "source",
|
|
2272
|
+
position: "bottom",
|
|
2273
|
+
id: "__group_out",
|
|
2274
|
+
label: "done",
|
|
2275
|
+
index: 1,
|
|
2276
|
+
total: 2
|
|
2277
|
+
}
|
|
2278
|
+
)
|
|
2279
|
+
] })
|
|
2280
|
+
)
|
|
2054
2281
|
]
|
|
2055
2282
|
}
|
|
2056
2283
|
);
|
|
@@ -2059,7 +2286,7 @@ var OutputNode = ({
|
|
|
2059
2286
|
node
|
|
2060
2287
|
}) => {
|
|
2061
2288
|
const d = node.data ?? {};
|
|
2062
|
-
return /* @__PURE__ */ (0,
|
|
2289
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2063
2290
|
BaseNode,
|
|
2064
2291
|
{
|
|
2065
2292
|
kind: d.kind ?? "OUTPUT",
|
|
@@ -2069,7 +2296,7 @@ var OutputNode = ({
|
|
|
2069
2296
|
description: d.description ?? d.subtitle,
|
|
2070
2297
|
status: d.status,
|
|
2071
2298
|
accent: "green",
|
|
2072
|
-
children: /* @__PURE__ */ (0,
|
|
2299
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Handle, { type: "target", position: "top" })
|
|
2073
2300
|
}
|
|
2074
2301
|
);
|
|
2075
2302
|
};
|
|
@@ -2077,7 +2304,7 @@ var ErrorNode = ({
|
|
|
2077
2304
|
node
|
|
2078
2305
|
}) => {
|
|
2079
2306
|
const d = node.data ?? {};
|
|
2080
|
-
return /* @__PURE__ */ (0,
|
|
2307
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
2081
2308
|
BaseNode,
|
|
2082
2309
|
{
|
|
2083
2310
|
kind: d.kind ?? "ERROR",
|
|
@@ -2088,8 +2315,8 @@ var ErrorNode = ({
|
|
|
2088
2315
|
status: d.status ?? "error",
|
|
2089
2316
|
accent: "red",
|
|
2090
2317
|
children: [
|
|
2091
|
-
/* @__PURE__ */ (0,
|
|
2092
|
-
/* @__PURE__ */ (0,
|
|
2318
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Handle, { type: "target", position: "top" }),
|
|
2319
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Handle, { type: "source", position: "bottom" })
|
|
2093
2320
|
]
|
|
2094
2321
|
}
|
|
2095
2322
|
);
|
|
@@ -2100,7 +2327,7 @@ var WaitNode = ({
|
|
|
2100
2327
|
const d = node.data ?? {};
|
|
2101
2328
|
const waitMs = d.waitMs;
|
|
2102
2329
|
const durationChip = waitMs ? `${Math.round(waitMs / 100) / 10}s` : void 0;
|
|
2103
|
-
return /* @__PURE__ */ (0,
|
|
2330
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
2104
2331
|
BaseNode,
|
|
2105
2332
|
{
|
|
2106
2333
|
kind: d.kind ?? "WAIT",
|
|
@@ -2111,8 +2338,8 @@ var WaitNode = ({
|
|
|
2111
2338
|
status: d.status,
|
|
2112
2339
|
accent: "violet",
|
|
2113
2340
|
children: [
|
|
2114
|
-
/* @__PURE__ */ (0,
|
|
2115
|
-
/* @__PURE__ */ (0,
|
|
2341
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Handle, { type: "target", position: "top" }),
|
|
2342
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Handle, { type: "source", position: "bottom" })
|
|
2116
2343
|
]
|
|
2117
2344
|
}
|
|
2118
2345
|
);
|
|
@@ -2125,7 +2352,7 @@ var ParallelNode = ({
|
|
|
2125
2352
|
{ id: "a", label: "a" },
|
|
2126
2353
|
{ id: "b", label: "b" }
|
|
2127
2354
|
];
|
|
2128
|
-
return /* @__PURE__ */ (0,
|
|
2355
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
2129
2356
|
BaseNode,
|
|
2130
2357
|
{
|
|
2131
2358
|
kind: d.kind ?? "PARALLEL",
|
|
@@ -2136,8 +2363,8 @@ var ParallelNode = ({
|
|
|
2136
2363
|
status: d.status,
|
|
2137
2364
|
accent: "blue",
|
|
2138
2365
|
children: [
|
|
2139
|
-
/* @__PURE__ */ (0,
|
|
2140
|
-
branches.map((b, i) => /* @__PURE__ */ (0,
|
|
2366
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Handle, { type: "target", position: "top" }),
|
|
2367
|
+
branches.map((b, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2141
2368
|
Handle,
|
|
2142
2369
|
{
|
|
2143
2370
|
type: "source",
|
|
@@ -2157,7 +2384,7 @@ var StickyNode = ({
|
|
|
2157
2384
|
node
|
|
2158
2385
|
}) => {
|
|
2159
2386
|
const d = node.data ?? {};
|
|
2160
|
-
return /* @__PURE__ */ (0,
|
|
2387
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
2161
2388
|
"div",
|
|
2162
2389
|
{
|
|
2163
2390
|
className: "ods-flow-sticky",
|
|
@@ -2166,8 +2393,8 @@ var StickyNode = ({
|
|
|
2166
2393
|
minHeight: node.height ?? 120
|
|
2167
2394
|
},
|
|
2168
2395
|
children: [
|
|
2169
|
-
d.title && /* @__PURE__ */ (0,
|
|
2170
|
-
d.description && /* @__PURE__ */ (0,
|
|
2396
|
+
d.title && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "ods-flow-sticky__title", children: d.title }),
|
|
2397
|
+
d.description && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "ods-flow-sticky__body", children: d.description })
|
|
2171
2398
|
]
|
|
2172
2399
|
}
|
|
2173
2400
|
);
|
|
@@ -2176,7 +2403,7 @@ var WebhookNode = ({
|
|
|
2176
2403
|
node
|
|
2177
2404
|
}) => {
|
|
2178
2405
|
const d = node.data ?? {};
|
|
2179
|
-
return /* @__PURE__ */ (0,
|
|
2406
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2180
2407
|
BaseNode,
|
|
2181
2408
|
{
|
|
2182
2409
|
kind: d.kind ?? "WEBHOOK",
|
|
@@ -2187,7 +2414,7 @@ var WebhookNode = ({
|
|
|
2187
2414
|
valueChip: d.valueChip,
|
|
2188
2415
|
status: d.status,
|
|
2189
2416
|
accent: "blue",
|
|
2190
|
-
children: /* @__PURE__ */ (0,
|
|
2417
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Handle, { type: "source", position: "bottom" })
|
|
2191
2418
|
}
|
|
2192
2419
|
);
|
|
2193
2420
|
};
|
|
@@ -2195,7 +2422,7 @@ var HttpRequestNode = ({
|
|
|
2195
2422
|
node
|
|
2196
2423
|
}) => {
|
|
2197
2424
|
const d = node.data ?? {};
|
|
2198
|
-
return /* @__PURE__ */ (0,
|
|
2425
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
2199
2426
|
BaseNode,
|
|
2200
2427
|
{
|
|
2201
2428
|
kind: d.kind ?? "HTTP",
|
|
@@ -2207,8 +2434,8 @@ var HttpRequestNode = ({
|
|
|
2207
2434
|
status: d.status,
|
|
2208
2435
|
accent: "blue",
|
|
2209
2436
|
children: [
|
|
2210
|
-
/* @__PURE__ */ (0,
|
|
2211
|
-
/* @__PURE__ */ (0,
|
|
2437
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Handle, { type: "target", position: "top" }),
|
|
2438
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Handle, { type: "source", position: "bottom" })
|
|
2212
2439
|
]
|
|
2213
2440
|
}
|
|
2214
2441
|
);
|
|
@@ -2229,52 +2456,60 @@ var DEFAULT_NODE_KINDS = {
|
|
|
2229
2456
|
};
|
|
2230
2457
|
|
|
2231
2458
|
// src/workflow/components/FlowCanvas/FlowCanvas.tsx
|
|
2232
|
-
var
|
|
2459
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
2233
2460
|
var DEFAULT_VIEWPORT2 = { x: 0, y: 0, zoom: 1 };
|
|
2234
|
-
function FlowCanvas({
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2461
|
+
function FlowCanvas(props) {
|
|
2462
|
+
const viewportPropProvided = props.viewport !== void 0 || props.defaultViewport !== void 0;
|
|
2463
|
+
const {
|
|
2464
|
+
nodes,
|
|
2465
|
+
edges,
|
|
2466
|
+
onNodesChange,
|
|
2467
|
+
onEdgesChange,
|
|
2468
|
+
viewport: controlledViewport,
|
|
2469
|
+
defaultViewport = DEFAULT_VIEWPORT2,
|
|
2470
|
+
onViewportChange,
|
|
2471
|
+
minZoom = 0.25,
|
|
2472
|
+
maxZoom = 2,
|
|
2473
|
+
fitViewOnInit,
|
|
2474
|
+
nodeKinds,
|
|
2475
|
+
onConnect,
|
|
2476
|
+
onConnectStart,
|
|
2477
|
+
onConnectEnd,
|
|
2478
|
+
isValidConnection,
|
|
2479
|
+
onSelectionChange,
|
|
2480
|
+
onPaneClick,
|
|
2481
|
+
onNodeClick,
|
|
2482
|
+
onEdgeClick,
|
|
2483
|
+
onEdgeLabelChange,
|
|
2484
|
+
onInit,
|
|
2485
|
+
onBeforeDelete,
|
|
2486
|
+
onNodeContextMenu,
|
|
2487
|
+
onEdgeContextMenu,
|
|
2488
|
+
onPaneContextMenu,
|
|
2489
|
+
nodesDraggable = true,
|
|
2490
|
+
nodesConnectable = true,
|
|
2491
|
+
panOnDrag: panOnDragProp,
|
|
2492
|
+
zoomOnScroll: zoomOnScrollProp,
|
|
2493
|
+
preset = "mouse",
|
|
2494
|
+
paneClickDistance = 4,
|
|
2495
|
+
paneClickClearsSelection = true,
|
|
2496
|
+
background = "dots",
|
|
2497
|
+
gridSize = 20,
|
|
2498
|
+
snapToGrid = false,
|
|
2499
|
+
nodeCollisionGap = -1,
|
|
2500
|
+
subflowCollisionGap,
|
|
2501
|
+
reparentOnDrag = false,
|
|
2502
|
+
autoResizeContainers = false,
|
|
2503
|
+
containerAutoResizePadding = 32,
|
|
2504
|
+
containerMinWidth = 320,
|
|
2505
|
+
containerMinHeight = 200,
|
|
2506
|
+
height = "100%",
|
|
2507
|
+
width = "100%",
|
|
2508
|
+
className,
|
|
2509
|
+
style,
|
|
2510
|
+
children,
|
|
2511
|
+
emptyState
|
|
2512
|
+
} = props;
|
|
2278
2513
|
const presetDefaults = {
|
|
2279
2514
|
mouse: { panOnDrag: true, zoomOnScroll: true },
|
|
2280
2515
|
trackpad: { panOnDrag: true, zoomOnScroll: true },
|
|
@@ -2282,46 +2517,46 @@ function FlowCanvas({
|
|
|
2282
2517
|
};
|
|
2283
2518
|
const panOnDrag = panOnDragProp ?? presetDefaults[preset].panOnDrag;
|
|
2284
2519
|
const zoomOnScroll = zoomOnScrollProp ?? presetDefaults[preset].zoomOnScroll;
|
|
2285
|
-
const store = (0,
|
|
2520
|
+
const store = (0, import_react15.useState)(
|
|
2286
2521
|
() => createFlowStore({
|
|
2287
2522
|
initialNodes: nodes,
|
|
2288
2523
|
initialEdges: edges,
|
|
2289
2524
|
initialViewport: controlledViewport ?? defaultViewport
|
|
2290
2525
|
})
|
|
2291
2526
|
)[0];
|
|
2292
|
-
const handleRegistry = (0,
|
|
2293
|
-
const [handleVersion, setHandleVersion] = (0,
|
|
2294
|
-
(0,
|
|
2527
|
+
const handleRegistry = (0, import_react15.useState)(() => createHandleRegistry())[0];
|
|
2528
|
+
const [handleVersion, setHandleVersion] = (0, import_react15.useState)(0);
|
|
2529
|
+
(0, import_react15.useEffect)(() => {
|
|
2295
2530
|
const unsub = handleRegistry.subscribe(() => {
|
|
2296
2531
|
setHandleVersion((v) => v + 1);
|
|
2297
2532
|
});
|
|
2298
2533
|
return unsub;
|
|
2299
2534
|
}, [handleRegistry]);
|
|
2300
|
-
const kinds = (0,
|
|
2301
|
-
const containerRef = (0,
|
|
2302
|
-
(0,
|
|
2303
|
-
(0,
|
|
2304
|
-
const [uncontrolledVp, setUncontrolledVp] = (0,
|
|
2535
|
+
const kinds = (0, import_react15.useMemo)(() => buildNodeKindRegistry(DEFAULT_NODE_KINDS, nodeKinds), [nodeKinds]);
|
|
2536
|
+
const containerRef = (0, import_react15.useRef)(null);
|
|
2537
|
+
(0, import_react15.useEffect)(() => store.setNodes(nodes), [store, nodes]);
|
|
2538
|
+
(0, import_react15.useEffect)(() => store.setEdges(edges), [store, edges]);
|
|
2539
|
+
const [uncontrolledVp, setUncontrolledVp] = (0, import_react15.useState)(controlledViewport ?? defaultViewport);
|
|
2305
2540
|
const viewport = controlledViewport ?? uncontrolledVp;
|
|
2306
|
-
(0,
|
|
2307
|
-
const setViewport = (0,
|
|
2541
|
+
(0, import_react15.useEffect)(() => store.setViewport(viewport), [store, viewport]);
|
|
2542
|
+
const setViewport = (0, import_react15.useCallback)(
|
|
2308
2543
|
(next) => {
|
|
2309
2544
|
if (controlledViewport === void 0) setUncontrolledVp(next);
|
|
2310
2545
|
onViewportChange?.(next);
|
|
2311
2546
|
},
|
|
2312
2547
|
[controlledViewport, onViewportChange]
|
|
2313
2548
|
);
|
|
2314
|
-
const selectedNodeIds = (0,
|
|
2549
|
+
const selectedNodeIds = (0, import_react15.useMemo)(() => {
|
|
2315
2550
|
const s = /* @__PURE__ */ new Set();
|
|
2316
2551
|
for (const n of nodes) if (n.selected) s.add(n.id);
|
|
2317
2552
|
return s;
|
|
2318
2553
|
}, [nodes]);
|
|
2319
|
-
const selectedEdgeIds = (0,
|
|
2554
|
+
const selectedEdgeIds = (0, import_react15.useMemo)(() => {
|
|
2320
2555
|
const s = /* @__PURE__ */ new Set();
|
|
2321
2556
|
for (const e of edges) if (e.selected) s.add(e.id);
|
|
2322
2557
|
return s;
|
|
2323
2558
|
}, [edges]);
|
|
2324
|
-
(0,
|
|
2559
|
+
(0, import_react15.useEffect)(() => {
|
|
2325
2560
|
store.setSelection(selectedNodeIds, selectedEdgeIds);
|
|
2326
2561
|
if (onSelectionChange) {
|
|
2327
2562
|
onSelectionChange({
|
|
@@ -2330,7 +2565,7 @@ function FlowCanvas({
|
|
|
2330
2565
|
});
|
|
2331
2566
|
}
|
|
2332
2567
|
}, [store, selectedNodeIds, selectedEdgeIds, nodes, edges, onSelectionChange]);
|
|
2333
|
-
const selectNode = (0,
|
|
2568
|
+
const selectNode = (0, import_react15.useCallback)(
|
|
2334
2569
|
(id, additive) => {
|
|
2335
2570
|
const next = [];
|
|
2336
2571
|
const nextEdges = [];
|
|
@@ -2353,14 +2588,14 @@ function FlowCanvas({
|
|
|
2353
2588
|
},
|
|
2354
2589
|
[nodes, edges, selectedNodeIds, onNodesChange, onEdgesChange]
|
|
2355
2590
|
);
|
|
2356
|
-
const notifyNodeClick = (0,
|
|
2591
|
+
const notifyNodeClick = (0, import_react15.useCallback)(
|
|
2357
2592
|
(id) => {
|
|
2358
2593
|
const node = nodes.find((n) => n.id === id);
|
|
2359
2594
|
if (node) onNodeClick?.(node);
|
|
2360
2595
|
},
|
|
2361
2596
|
[nodes, onNodeClick]
|
|
2362
2597
|
);
|
|
2363
|
-
const selectEdge = (0,
|
|
2598
|
+
const selectEdge = (0, import_react15.useCallback)(
|
|
2364
2599
|
(id, additive) => {
|
|
2365
2600
|
const next = [];
|
|
2366
2601
|
const nextNodes = [];
|
|
@@ -2385,7 +2620,7 @@ function FlowCanvas({
|
|
|
2385
2620
|
},
|
|
2386
2621
|
[nodes, edges, selectedEdgeIds, onEdgesChange, onNodesChange, onEdgeClick]
|
|
2387
2622
|
);
|
|
2388
|
-
const clearSelection = (0,
|
|
2623
|
+
const clearSelection = (0, import_react15.useCallback)(() => {
|
|
2389
2624
|
const ns = [];
|
|
2390
2625
|
const es = [];
|
|
2391
2626
|
for (const n of nodes) if (n.selected) ns.push(change.node.select(n.id, false));
|
|
@@ -2393,9 +2628,9 @@ function FlowCanvas({
|
|
|
2393
2628
|
if (ns.length) onNodesChange?.(ns);
|
|
2394
2629
|
if (es.length) onEdgesChange?.(es);
|
|
2395
2630
|
}, [nodes, edges, onNodesChange, onEdgesChange]);
|
|
2396
|
-
const dragRef = (0,
|
|
2397
|
-
const [draggingId, setDraggingId] = (0,
|
|
2398
|
-
const beginNodeDrag = (0,
|
|
2631
|
+
const dragRef = (0, import_react15.useRef)(null);
|
|
2632
|
+
const [draggingId, setDraggingId] = (0, import_react15.useState)(null);
|
|
2633
|
+
const beginNodeDrag = (0, import_react15.useCallback)(
|
|
2399
2634
|
(nodeId, pointerId, clientX, clientY, altKey = false) => {
|
|
2400
2635
|
if (!nodesDraggable) return;
|
|
2401
2636
|
const node = nodes.find((n) => n.id === nodeId);
|
|
@@ -2404,6 +2639,9 @@ function FlowCanvas({
|
|
|
2404
2639
|
id: d.id,
|
|
2405
2640
|
startPosition: d.position
|
|
2406
2641
|
}));
|
|
2642
|
+
const evaluateReparent = altKey || reparentOnDragRef.current;
|
|
2643
|
+
const hasParent = !!node.parentId;
|
|
2644
|
+
const skipClamp = altKey || reparentOnDragRef.current && !hasParent;
|
|
2407
2645
|
dragRef.current = {
|
|
2408
2646
|
pointerId,
|
|
2409
2647
|
nodeId,
|
|
@@ -2411,7 +2649,8 @@ function FlowCanvas({
|
|
|
2411
2649
|
startClientY: clientY,
|
|
2412
2650
|
startPosition: node.position,
|
|
2413
2651
|
descendants: kids,
|
|
2414
|
-
|
|
2652
|
+
skipClamp,
|
|
2653
|
+
evaluateReparent,
|
|
2415
2654
|
rafScheduled: false,
|
|
2416
2655
|
nextDelta: null
|
|
2417
2656
|
};
|
|
@@ -2420,12 +2659,12 @@ function FlowCanvas({
|
|
|
2420
2659
|
},
|
|
2421
2660
|
[nodes, nodesDraggable, selectNode]
|
|
2422
2661
|
);
|
|
2423
|
-
const [conn, setConn] = (0,
|
|
2424
|
-
const connRef = (0,
|
|
2425
|
-
(0,
|
|
2662
|
+
const [conn, setConn] = (0, import_react15.useState)(null);
|
|
2663
|
+
const connRef = (0, import_react15.useRef)(null);
|
|
2664
|
+
(0, import_react15.useEffect)(() => {
|
|
2426
2665
|
connRef.current = conn;
|
|
2427
2666
|
}, [conn]);
|
|
2428
|
-
const beginConnection = (0,
|
|
2667
|
+
const beginConnection = (0, import_react15.useCallback)(
|
|
2429
2668
|
(nodeId, handleId, handleType, pointerId, clientX, clientY) => {
|
|
2430
2669
|
if (!nodesConnectable) return;
|
|
2431
2670
|
const node = nodes.find((n) => n.id === nodeId);
|
|
@@ -2458,63 +2697,83 @@ function FlowCanvas({
|
|
|
2458
2697
|
},
|
|
2459
2698
|
[nodes, nodesConnectable, handleRegistry, viewport, store, onConnectStart]
|
|
2460
2699
|
);
|
|
2461
|
-
const viewportRef = (0,
|
|
2462
|
-
const nodesRef = (0,
|
|
2463
|
-
const edgesRef = (0,
|
|
2464
|
-
const onNodesChangeRefForInstance = (0,
|
|
2465
|
-
const onEdgesChangeRefForInstance = (0,
|
|
2466
|
-
const onBeforeDeleteRef = (0,
|
|
2467
|
-
const snapToGridRef = (0,
|
|
2468
|
-
const gridSizeRef = (0,
|
|
2469
|
-
const nodeCollisionGapRef = (0,
|
|
2470
|
-
const subflowCollisionGapRef = (0,
|
|
2471
|
-
(0,
|
|
2700
|
+
const viewportRef = (0, import_react15.useRef)(viewport);
|
|
2701
|
+
const nodesRef = (0, import_react15.useRef)(nodes);
|
|
2702
|
+
const edgesRef = (0, import_react15.useRef)(edges);
|
|
2703
|
+
const onNodesChangeRefForInstance = (0, import_react15.useRef)(onNodesChange);
|
|
2704
|
+
const onEdgesChangeRefForInstance = (0, import_react15.useRef)(onEdgesChange);
|
|
2705
|
+
const onBeforeDeleteRef = (0, import_react15.useRef)(onBeforeDelete);
|
|
2706
|
+
const snapToGridRef = (0, import_react15.useRef)(snapToGrid);
|
|
2707
|
+
const gridSizeRef = (0, import_react15.useRef)(gridSize);
|
|
2708
|
+
const nodeCollisionGapRef = (0, import_react15.useRef)(nodeCollisionGap);
|
|
2709
|
+
const subflowCollisionGapRef = (0, import_react15.useRef)(subflowCollisionGap ?? nodeCollisionGap);
|
|
2710
|
+
const reparentOnDragRef = (0, import_react15.useRef)(reparentOnDrag);
|
|
2711
|
+
const autoResizeContainersRef = (0, import_react15.useRef)(autoResizeContainers);
|
|
2712
|
+
const containerAutoResizePaddingRef = (0, import_react15.useRef)(containerAutoResizePadding);
|
|
2713
|
+
const containerMinWidthRef = (0, import_react15.useRef)(containerMinWidth);
|
|
2714
|
+
const containerMinHeightRef = (0, import_react15.useRef)(containerMinHeight);
|
|
2715
|
+
(0, import_react15.useEffect)(() => {
|
|
2472
2716
|
edgesRef.current = edges;
|
|
2473
2717
|
}, [edges]);
|
|
2474
|
-
(0,
|
|
2718
|
+
(0, import_react15.useEffect)(() => {
|
|
2475
2719
|
onNodesChangeRefForInstance.current = onNodesChange;
|
|
2476
2720
|
}, [onNodesChange]);
|
|
2477
|
-
(0,
|
|
2721
|
+
(0, import_react15.useEffect)(() => {
|
|
2478
2722
|
onEdgesChangeRefForInstance.current = onEdgesChange;
|
|
2479
2723
|
}, [onEdgesChange]);
|
|
2480
|
-
(0,
|
|
2724
|
+
(0, import_react15.useEffect)(() => {
|
|
2481
2725
|
onBeforeDeleteRef.current = onBeforeDelete;
|
|
2482
2726
|
}, [onBeforeDelete]);
|
|
2483
|
-
(0,
|
|
2727
|
+
(0, import_react15.useEffect)(() => {
|
|
2484
2728
|
snapToGridRef.current = snapToGrid;
|
|
2485
2729
|
}, [snapToGrid]);
|
|
2486
|
-
(0,
|
|
2730
|
+
(0, import_react15.useEffect)(() => {
|
|
2487
2731
|
gridSizeRef.current = gridSize;
|
|
2488
2732
|
}, [gridSize]);
|
|
2489
|
-
(0,
|
|
2733
|
+
(0, import_react15.useEffect)(() => {
|
|
2490
2734
|
nodeCollisionGapRef.current = nodeCollisionGap;
|
|
2491
2735
|
}, [nodeCollisionGap]);
|
|
2492
|
-
(0,
|
|
2736
|
+
(0, import_react15.useEffect)(() => {
|
|
2493
2737
|
subflowCollisionGapRef.current = subflowCollisionGap ?? nodeCollisionGap;
|
|
2494
2738
|
}, [subflowCollisionGap, nodeCollisionGap]);
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2739
|
+
(0, import_react15.useEffect)(() => {
|
|
2740
|
+
reparentOnDragRef.current = reparentOnDrag;
|
|
2741
|
+
}, [reparentOnDrag]);
|
|
2742
|
+
(0, import_react15.useEffect)(() => {
|
|
2743
|
+
autoResizeContainersRef.current = autoResizeContainers;
|
|
2744
|
+
}, [autoResizeContainers]);
|
|
2745
|
+
(0, import_react15.useEffect)(() => {
|
|
2746
|
+
containerAutoResizePaddingRef.current = containerAutoResizePadding;
|
|
2747
|
+
}, [containerAutoResizePadding]);
|
|
2748
|
+
(0, import_react15.useEffect)(() => {
|
|
2749
|
+
containerMinWidthRef.current = containerMinWidth;
|
|
2750
|
+
}, [containerMinWidth]);
|
|
2751
|
+
(0, import_react15.useEffect)(() => {
|
|
2752
|
+
containerMinHeightRef.current = containerMinHeight;
|
|
2753
|
+
}, [containerMinHeight]);
|
|
2754
|
+
const onNodesChangeRef = (0, import_react15.useRef)(onNodesChange);
|
|
2755
|
+
const onConnectRef = (0, import_react15.useRef)(onConnect);
|
|
2756
|
+
const onConnectEndRef = (0, import_react15.useRef)(onConnectEnd);
|
|
2757
|
+
const isValidConnectionRef = (0, import_react15.useRef)(isValidConnection);
|
|
2758
|
+
(0, import_react15.useEffect)(() => {
|
|
2500
2759
|
viewportRef.current = viewport;
|
|
2501
2760
|
}, [viewport]);
|
|
2502
|
-
(0,
|
|
2761
|
+
(0, import_react15.useEffect)(() => {
|
|
2503
2762
|
nodesRef.current = nodes;
|
|
2504
2763
|
}, [nodes]);
|
|
2505
|
-
(0,
|
|
2764
|
+
(0, import_react15.useEffect)(() => {
|
|
2506
2765
|
onNodesChangeRef.current = onNodesChange;
|
|
2507
2766
|
}, [onNodesChange]);
|
|
2508
|
-
(0,
|
|
2767
|
+
(0, import_react15.useEffect)(() => {
|
|
2509
2768
|
onConnectRef.current = onConnect;
|
|
2510
2769
|
}, [onConnect]);
|
|
2511
|
-
(0,
|
|
2770
|
+
(0, import_react15.useEffect)(() => {
|
|
2512
2771
|
onConnectEndRef.current = onConnectEnd;
|
|
2513
2772
|
}, [onConnectEnd]);
|
|
2514
|
-
(0,
|
|
2773
|
+
(0, import_react15.useEffect)(() => {
|
|
2515
2774
|
isValidConnectionRef.current = isValidConnection;
|
|
2516
2775
|
}, [isValidConnection]);
|
|
2517
|
-
(0,
|
|
2776
|
+
(0, import_react15.useEffect)(() => {
|
|
2518
2777
|
const onPointerMove = (e) => {
|
|
2519
2778
|
const vp = viewportRef.current;
|
|
2520
2779
|
const drag = dragRef.current;
|
|
@@ -2536,7 +2795,7 @@ function FlowCanvas({
|
|
|
2536
2795
|
x: d.startPosition.x + delta.dx,
|
|
2537
2796
|
y: d.startPosition.y + delta.dy
|
|
2538
2797
|
};
|
|
2539
|
-
const clamped = d.
|
|
2798
|
+
const clamped = d.skipClamp ? proposed : clampToParentExtent(dragNode, proposed, nodesRef.current);
|
|
2540
2799
|
const isContainer = dragNode.type === "group" || dragNode.type === "forEach";
|
|
2541
2800
|
const gap = isContainer ? subflowCollisionGapRef.current : nodeCollisionGapRef.current;
|
|
2542
2801
|
const excludeIds = /* @__PURE__ */ new Set([d.nodeId, ...d.descendants.map((kid) => kid.id)]);
|
|
@@ -2588,7 +2847,7 @@ function FlowCanvas({
|
|
|
2588
2847
|
y: Math.round(proposed.y / g) * g
|
|
2589
2848
|
};
|
|
2590
2849
|
}
|
|
2591
|
-
const clamped = drag.
|
|
2850
|
+
const clamped = drag.skipClamp ? proposed : clampToParentExtent(dragNode, proposed, nodesRef.current);
|
|
2592
2851
|
const isContainer = dragNode.type === "group" || dragNode.type === "forEach";
|
|
2593
2852
|
const gap = isContainer ? subflowCollisionGapRef.current : nodeCollisionGapRef.current;
|
|
2594
2853
|
const excludeIds = /* @__PURE__ */ new Set([
|
|
@@ -2611,7 +2870,7 @@ function FlowCanvas({
|
|
|
2611
2870
|
)
|
|
2612
2871
|
);
|
|
2613
2872
|
}
|
|
2614
|
-
if (drag.
|
|
2873
|
+
if (drag.evaluateReparent) {
|
|
2615
2874
|
const targetGroup = findContainingGroup(
|
|
2616
2875
|
{
|
|
2617
2876
|
x: finalPos.x + (dragNode.width ?? 0) / 2,
|
|
@@ -2621,14 +2880,30 @@ function FlowCanvas({
|
|
|
2621
2880
|
[drag.nodeId, ...drag.descendants.map((d) => d.id)]
|
|
2622
2881
|
);
|
|
2623
2882
|
const nextParentId = targetGroup?.id;
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2883
|
+
if (nextParentId !== dragNode.parentId) {
|
|
2884
|
+
const updated = {
|
|
2885
|
+
...dragNode,
|
|
2886
|
+
position: finalPos,
|
|
2887
|
+
parentId: nextParentId,
|
|
2888
|
+
// Adopting into a container always pins the child with
|
|
2889
|
+
// `extent: 'parent'` so it's clamped from the next drag
|
|
2890
|
+
// on. Detaching clears it.
|
|
2891
|
+
extent: nextParentId ? "parent" : void 0
|
|
2892
|
+
};
|
|
2893
|
+
changes.push(change.node.replace(drag.nodeId, updated));
|
|
2894
|
+
}
|
|
2895
|
+
}
|
|
2896
|
+
if (autoResizeContainersRef.current) {
|
|
2897
|
+
const containerChanges = computeContainerAutoResize(
|
|
2898
|
+
nodesRef.current,
|
|
2899
|
+
// Projected children: apply the position + reparent
|
|
2900
|
+
// changes we just built before measuring bboxes.
|
|
2901
|
+
changes,
|
|
2902
|
+
containerAutoResizePaddingRef.current,
|
|
2903
|
+
containerMinWidthRef.current,
|
|
2904
|
+
containerMinHeightRef.current
|
|
2905
|
+
);
|
|
2906
|
+
for (const c2 of containerChanges) changes.push(c2);
|
|
2632
2907
|
}
|
|
2633
2908
|
onNodesChangeRef.current?.(changes);
|
|
2634
2909
|
}
|
|
@@ -2637,38 +2912,54 @@ function FlowCanvas({
|
|
|
2637
2912
|
}
|
|
2638
2913
|
const c = connRef.current;
|
|
2639
2914
|
if (c && c.pointerId === e.pointerId) {
|
|
2640
|
-
const
|
|
2641
|
-
const
|
|
2915
|
+
const rect = containerRef.current?.getBoundingClientRect();
|
|
2916
|
+
const flowPos = rect ? screenToFlow({ x: e.clientX - rect.left, y: e.clientY - rect.top }, vp) : { x: 0, y: 0 };
|
|
2917
|
+
const snapRadius = 26 / Math.max(0.1, vp.zoom);
|
|
2918
|
+
let bestDesc = null;
|
|
2919
|
+
let bestDist = snapRadius;
|
|
2920
|
+
for (const desc of handleRegistry.all()) {
|
|
2921
|
+
if (desc.nodeId === c.from.nodeId) continue;
|
|
2922
|
+
if (desc.type === c.from.handleType) continue;
|
|
2923
|
+
if (!desc.canEnd) continue;
|
|
2924
|
+
const targetNode = nodesRef.current.find((n) => n.id === desc.nodeId);
|
|
2925
|
+
if (!targetNode || targetNode.hidden) continue;
|
|
2926
|
+
const centre = handleCentre(targetNode, desc.side, desc.index, desc.total);
|
|
2927
|
+
const dist = Math.hypot(centre.x - flowPos.x, centre.y - flowPos.y);
|
|
2928
|
+
if (dist < bestDist) {
|
|
2929
|
+
bestDist = dist;
|
|
2930
|
+
bestDesc = desc;
|
|
2931
|
+
}
|
|
2932
|
+
}
|
|
2642
2933
|
let connection = null;
|
|
2643
2934
|
let connectedTo;
|
|
2644
|
-
if (
|
|
2645
|
-
const
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2935
|
+
if (bestDesc) {
|
|
2936
|
+
const source = c.from.handleType === "source" ? c.from : {
|
|
2937
|
+
nodeId: bestDesc.nodeId,
|
|
2938
|
+
handleId: bestDesc.handleId,
|
|
2939
|
+
handleType: "source"
|
|
2940
|
+
};
|
|
2941
|
+
const target2 = c.from.handleType === "target" ? c.from : {
|
|
2942
|
+
nodeId: bestDesc.nodeId,
|
|
2943
|
+
handleId: bestDesc.handleId,
|
|
2944
|
+
handleType: "target"
|
|
2945
|
+
};
|
|
2946
|
+
connection = {
|
|
2947
|
+
source: source.nodeId,
|
|
2948
|
+
sourceHandle: source.handleId,
|
|
2949
|
+
target: target2.nodeId,
|
|
2950
|
+
targetHandle: target2.handleId
|
|
2951
|
+
};
|
|
2952
|
+
connectedTo = {
|
|
2953
|
+
nodeId: bestDesc.nodeId,
|
|
2954
|
+
handleId: bestDesc.handleId,
|
|
2955
|
+
handleType: bestDesc.type
|
|
2956
|
+
};
|
|
2957
|
+
const validator = isValidConnectionRef.current;
|
|
2958
|
+
if (validator && !validator(connection)) {
|
|
2959
|
+
connection = null;
|
|
2960
|
+
connectedTo = void 0;
|
|
2668
2961
|
}
|
|
2669
2962
|
}
|
|
2670
|
-
const rect = containerRef.current?.getBoundingClientRect();
|
|
2671
|
-
const flowPos = rect ? screenToFlow({ x: e.clientX - rect.left, y: e.clientY - rect.top }, vp) : { x: 0, y: 0 };
|
|
2672
2963
|
const endState = {
|
|
2673
2964
|
cancelled: !connection,
|
|
2674
2965
|
position: { x: e.clientX, y: e.clientY },
|
|
@@ -2701,7 +2992,26 @@ function FlowCanvas({
|
|
|
2701
2992
|
window.removeEventListener("pointercancel", onPointerCancel);
|
|
2702
2993
|
};
|
|
2703
2994
|
}, [store]);
|
|
2704
|
-
|
|
2995
|
+
(0, import_react15.useEffect)(() => {
|
|
2996
|
+
if (!autoResizeContainers || draggingId) return;
|
|
2997
|
+
const resizeChanges = computeContainerAutoResize(
|
|
2998
|
+
nodes,
|
|
2999
|
+
[],
|
|
3000
|
+
containerAutoResizePadding,
|
|
3001
|
+
containerMinWidth,
|
|
3002
|
+
containerMinHeight
|
|
3003
|
+
);
|
|
3004
|
+
if (resizeChanges.length > 0) onNodesChange?.(resizeChanges);
|
|
3005
|
+
}, [
|
|
3006
|
+
nodes,
|
|
3007
|
+
draggingId,
|
|
3008
|
+
autoResizeContainers,
|
|
3009
|
+
containerAutoResizePadding,
|
|
3010
|
+
containerMinWidth,
|
|
3011
|
+
containerMinHeight,
|
|
3012
|
+
onNodesChange
|
|
3013
|
+
]);
|
|
3014
|
+
const panRef = (0, import_react15.useRef)(null);
|
|
2705
3015
|
const onCanvasPointerDown = (e) => {
|
|
2706
3016
|
if (e.button !== 0) return;
|
|
2707
3017
|
const t = e.target;
|
|
@@ -2726,7 +3036,7 @@ function FlowCanvas({
|
|
|
2726
3036
|
moved: false
|
|
2727
3037
|
};
|
|
2728
3038
|
};
|
|
2729
|
-
(0,
|
|
3039
|
+
(0, import_react15.useEffect)(() => {
|
|
2730
3040
|
const onMove = (e) => {
|
|
2731
3041
|
const pan = panRef.current;
|
|
2732
3042
|
if (!pan || pan.pointerId !== e.pointerId) return;
|
|
@@ -2782,7 +3092,7 @@ function FlowCanvas({
|
|
|
2782
3092
|
y: py - (py - viewport.y) * k
|
|
2783
3093
|
});
|
|
2784
3094
|
};
|
|
2785
|
-
const dispatch = (0,
|
|
3095
|
+
const dispatch = (0, import_react15.useCallback)(
|
|
2786
3096
|
(a) => {
|
|
2787
3097
|
if (a.type === "connection/start") {
|
|
2788
3098
|
beginConnection(a.nodeId, a.handleId, a.handleType, a.pointerId, a.clientX, a.clientY);
|
|
@@ -2790,7 +3100,7 @@ function FlowCanvas({
|
|
|
2790
3100
|
},
|
|
2791
3101
|
[beginConnection]
|
|
2792
3102
|
);
|
|
2793
|
-
const reportDimensions = (0,
|
|
3103
|
+
const reportDimensions = (0, import_react15.useCallback)(
|
|
2794
3104
|
(nodeId, width2, height2) => {
|
|
2795
3105
|
const node = nodes.find((n) => n.id === nodeId);
|
|
2796
3106
|
if (!node) return;
|
|
@@ -2799,7 +3109,7 @@ function FlowCanvas({
|
|
|
2799
3109
|
},
|
|
2800
3110
|
[nodes, onNodesChange]
|
|
2801
3111
|
);
|
|
2802
|
-
const toggleNodeCollapseImpl = (0,
|
|
3112
|
+
const toggleNodeCollapseImpl = (0, import_react15.useCallback)(
|
|
2803
3113
|
(nodeId) => {
|
|
2804
3114
|
const node = nodes.find((n) => n.id === nodeId);
|
|
2805
3115
|
if (!node) return;
|
|
@@ -2812,7 +3122,7 @@ function FlowCanvas({
|
|
|
2812
3122
|
},
|
|
2813
3123
|
[nodes, onNodesChange]
|
|
2814
3124
|
);
|
|
2815
|
-
const deleteNodeImpl = (0,
|
|
3125
|
+
const deleteNodeImpl = (0, import_react15.useCallback)(
|
|
2816
3126
|
(nodeId) => {
|
|
2817
3127
|
const incidentEdgeIds = edgesRef.current.filter((e) => e.source === nodeId || e.target === nodeId).map((e) => e.id);
|
|
2818
3128
|
if (incidentEdgeIds.length > 0) {
|
|
@@ -2822,7 +3132,7 @@ function FlowCanvas({
|
|
|
2822
3132
|
},
|
|
2823
3133
|
[onNodesChange, onEdgesChange]
|
|
2824
3134
|
);
|
|
2825
|
-
const instance = (0,
|
|
3135
|
+
const instance = (0, import_react15.useMemo)(
|
|
2826
3136
|
() => ({
|
|
2827
3137
|
// viewport
|
|
2828
3138
|
getViewport: () => viewportRef.current,
|
|
@@ -2963,13 +3273,29 @@ function FlowCanvas({
|
|
|
2963
3273
|
}),
|
|
2964
3274
|
[setViewport, minZoom, maxZoom]
|
|
2965
3275
|
);
|
|
2966
|
-
const initFiredRef = (0,
|
|
2967
|
-
(0,
|
|
3276
|
+
const initFiredRef = (0, import_react15.useRef)(false);
|
|
3277
|
+
(0, import_react15.useEffect)(() => {
|
|
2968
3278
|
if (initFiredRef.current) return;
|
|
2969
3279
|
initFiredRef.current = true;
|
|
2970
3280
|
onInit?.(instance);
|
|
2971
3281
|
}, [instance, onInit]);
|
|
2972
|
-
(0,
|
|
3282
|
+
const fitOnInitFiredRef = (0, import_react15.useRef)(false);
|
|
3283
|
+
(0, import_react15.useEffect)(() => {
|
|
3284
|
+
if (fitOnInitFiredRef.current) return;
|
|
3285
|
+
const opt = fitViewOnInit;
|
|
3286
|
+
const shouldFit = opt === false ? false : opt !== void 0 ? true : !viewportPropProvided;
|
|
3287
|
+
if (!shouldFit) return;
|
|
3288
|
+
if (nodes.length === 0) return;
|
|
3289
|
+
const rect = containerRef.current?.getBoundingClientRect();
|
|
3290
|
+
if (!rect || rect.width === 0 || rect.height === 0) return;
|
|
3291
|
+
fitOnInitFiredRef.current = true;
|
|
3292
|
+
const fitOpts = typeof opt === "object" && opt !== null ? opt : void 0;
|
|
3293
|
+
const raf = requestAnimationFrame(() => {
|
|
3294
|
+
void instance.fitView(fitOpts);
|
|
3295
|
+
});
|
|
3296
|
+
return () => cancelAnimationFrame(raf);
|
|
3297
|
+
}, [fitViewOnInit, viewportPropProvided, nodes.length, instance]);
|
|
3298
|
+
(0, import_react15.useEffect)(() => {
|
|
2973
3299
|
const onKey = (e) => {
|
|
2974
3300
|
if (e.key !== "Backspace" && e.key !== "Delete") return;
|
|
2975
3301
|
const target = e.target;
|
|
@@ -2990,7 +3316,7 @@ function FlowCanvas({
|
|
|
2990
3316
|
window.addEventListener("keydown", onKey);
|
|
2991
3317
|
return () => window.removeEventListener("keydown", onKey);
|
|
2992
3318
|
}, [instance, store]);
|
|
2993
|
-
const bridge = (0,
|
|
3319
|
+
const bridge = (0, import_react15.useMemo)(
|
|
2994
3320
|
() => ({
|
|
2995
3321
|
beginNodeDrag,
|
|
2996
3322
|
selectNode,
|
|
@@ -3010,16 +3336,16 @@ function FlowCanvas({
|
|
|
3010
3336
|
toggleNodeCollapseImpl
|
|
3011
3337
|
]
|
|
3012
3338
|
);
|
|
3013
|
-
const [panGesture, setPanGesture] = (0,
|
|
3339
|
+
const [panGesture, setPanGesture] = (0, import_react15.useState)(false);
|
|
3014
3340
|
const isEmpty = nodes.length === 0 && edges.length === 0;
|
|
3015
3341
|
const isConnecting = conn !== null;
|
|
3016
|
-
const visibleNodes = (0,
|
|
3017
|
-
const visibleEdges = (0,
|
|
3342
|
+
const visibleNodes = (0, import_react15.useMemo)(() => nodes.filter((n) => !n.hidden), [nodes]);
|
|
3343
|
+
const visibleEdges = (0, import_react15.useMemo)(() => {
|
|
3018
3344
|
if (visibleNodes.length === nodes.length) return edges;
|
|
3019
3345
|
const visibleIds = new Set(visibleNodes.map((n) => n.id));
|
|
3020
3346
|
return edges.filter((e) => visibleIds.has(e.source) && visibleIds.has(e.target));
|
|
3021
3347
|
}, [edges, nodes, visibleNodes]);
|
|
3022
|
-
const orderedNodes = (0,
|
|
3348
|
+
const orderedNodes = (0, import_react15.useMemo)(() => {
|
|
3023
3349
|
const isContainer = (n) => n.type === "group" || n.type === "forEach";
|
|
3024
3350
|
const depth = (n) => {
|
|
3025
3351
|
let d = 0;
|
|
@@ -3038,7 +3364,7 @@ function FlowCanvas({
|
|
|
3038
3364
|
containers.sort((a, b) => depth(a) - depth(b));
|
|
3039
3365
|
return [...containers, ...others];
|
|
3040
3366
|
}, [visibleNodes]);
|
|
3041
|
-
return /* @__PURE__ */ (0,
|
|
3367
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(FlowStoreContext.Provider, { value: store, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(FlowInstanceContext.Provider, { value: instance, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(HandleRegistryContext.Provider, { value: handleRegistry, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(FlowDispatchContext.Provider, { value: dispatch, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(FlowNodeBridgeContext.Provider, { value: bridge, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
3042
3368
|
"div",
|
|
3043
3369
|
{
|
|
3044
3370
|
ref: containerRef,
|
|
@@ -3083,7 +3409,7 @@ function FlowCanvas({
|
|
|
3083
3409
|
},
|
|
3084
3410
|
"data-empty": isEmpty ? "true" : void 0,
|
|
3085
3411
|
children: [
|
|
3086
|
-
background !== "none" && /* @__PURE__ */ (0,
|
|
3412
|
+
background !== "none" && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3087
3413
|
"div",
|
|
3088
3414
|
{
|
|
3089
3415
|
className: cn(
|
|
@@ -3097,7 +3423,7 @@ function FlowCanvas({
|
|
|
3097
3423
|
}
|
|
3098
3424
|
}
|
|
3099
3425
|
),
|
|
3100
|
-
/* @__PURE__ */ (0,
|
|
3426
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
3101
3427
|
"div",
|
|
3102
3428
|
{
|
|
3103
3429
|
className: "ods-flow-canvas-v2__viewport",
|
|
@@ -3108,7 +3434,7 @@ function FlowCanvas({
|
|
|
3108
3434
|
transformOrigin: "0 0"
|
|
3109
3435
|
},
|
|
3110
3436
|
children: [
|
|
3111
|
-
/* @__PURE__ */ (0,
|
|
3437
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3112
3438
|
EdgesLayer,
|
|
3113
3439
|
{
|
|
3114
3440
|
edges: visibleEdges,
|
|
@@ -3123,7 +3449,7 @@ function FlowCanvas({
|
|
|
3123
3449
|
orderedNodes.map((node) => {
|
|
3124
3450
|
const Kind = kinds[node.type] ?? kinds.action;
|
|
3125
3451
|
if (!Kind) return null;
|
|
3126
|
-
return /* @__PURE__ */ (0,
|
|
3452
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3127
3453
|
FlowNode,
|
|
3128
3454
|
{
|
|
3129
3455
|
node,
|
|
@@ -3138,7 +3464,7 @@ function FlowCanvas({
|
|
|
3138
3464
|
]
|
|
3139
3465
|
}
|
|
3140
3466
|
),
|
|
3141
|
-
isEmpty && emptyState && /* @__PURE__ */ (0,
|
|
3467
|
+
isEmpty && emptyState && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "ods-flow-canvas-v2__empty", children: emptyState }),
|
|
3142
3468
|
children
|
|
3143
3469
|
]
|
|
3144
3470
|
}
|
|
@@ -3147,7 +3473,69 @@ function FlowCanvas({
|
|
|
3147
3473
|
function onEdgesChangeRef(id, cb) {
|
|
3148
3474
|
cb?.([change.edge.remove(id)]);
|
|
3149
3475
|
}
|
|
3150
|
-
var
|
|
3476
|
+
var CONTAINER_DROP_HEADROOM_W = 220;
|
|
3477
|
+
var CONTAINER_DROP_HEADROOM_H = 2 * 128;
|
|
3478
|
+
function computeContainerAutoResize(nodes, pending, padding, minWidth, minHeight) {
|
|
3479
|
+
const projected = /* @__PURE__ */ new Map();
|
|
3480
|
+
for (const n of nodes) projected.set(n.id, n);
|
|
3481
|
+
for (const c of pending) {
|
|
3482
|
+
if (c.type === "position" && c.position) {
|
|
3483
|
+
const cur = projected.get(c.id);
|
|
3484
|
+
if (cur) projected.set(c.id, { ...cur, position: c.position });
|
|
3485
|
+
} else if (c.type === "replace" && c.item) {
|
|
3486
|
+
projected.set(c.id, { ...projected.get(c.id), ...c.item });
|
|
3487
|
+
} else if (c.type === "add" && c.item) {
|
|
3488
|
+
projected.set(c.item.id, c.item);
|
|
3489
|
+
}
|
|
3490
|
+
}
|
|
3491
|
+
const HEADER = 56;
|
|
3492
|
+
const out = [];
|
|
3493
|
+
for (const parent of projected.values()) {
|
|
3494
|
+
if (parent.type !== "group" && parent.type !== "forEach") continue;
|
|
3495
|
+
const children = [];
|
|
3496
|
+
for (const n of projected.values()) {
|
|
3497
|
+
if (n.parentId === parent.id) children.push(n);
|
|
3498
|
+
}
|
|
3499
|
+
if (children.length === 0) {
|
|
3500
|
+
const curW2 = parent.width ?? 480;
|
|
3501
|
+
const curH2 = parent.height ?? 240;
|
|
3502
|
+
if (curW2 !== minWidth || curH2 !== minHeight) {
|
|
3503
|
+
out.push(change.node.dimensions(parent.id, { width: minWidth, height: minHeight }));
|
|
3504
|
+
}
|
|
3505
|
+
continue;
|
|
3506
|
+
}
|
|
3507
|
+
let minX = Number.POSITIVE_INFINITY;
|
|
3508
|
+
let minY = Number.POSITIVE_INFINITY;
|
|
3509
|
+
let maxX = Number.NEGATIVE_INFINITY;
|
|
3510
|
+
let maxY = Number.NEGATIVE_INFINITY;
|
|
3511
|
+
for (const c of children) {
|
|
3512
|
+
const cw = c.width ?? 240;
|
|
3513
|
+
const ch = c.height ?? 96;
|
|
3514
|
+
if (c.position.x < minX) minX = c.position.x;
|
|
3515
|
+
if (c.position.y < minY) minY = c.position.y;
|
|
3516
|
+
if (c.position.x + cw > maxX) maxX = c.position.x + cw;
|
|
3517
|
+
if (c.position.y + ch > maxY) maxY = c.position.y + ch;
|
|
3518
|
+
}
|
|
3519
|
+
const targetX = minX - padding;
|
|
3520
|
+
const targetY = minY - padding - HEADER;
|
|
3521
|
+
const curW = parent.width ?? 480;
|
|
3522
|
+
const curH = parent.height ?? 240;
|
|
3523
|
+
const fitW = maxX - minX + padding * 2 + CONTAINER_DROP_HEADROOM_W;
|
|
3524
|
+
const fitH = maxY - minY + padding * 2 + HEADER + CONTAINER_DROP_HEADROOM_H;
|
|
3525
|
+
const nextW = Math.max(minWidth, fitW);
|
|
3526
|
+
const nextH = Math.max(minHeight, fitH);
|
|
3527
|
+
const positionDirty = parent.position.x !== targetX || parent.position.y !== targetY;
|
|
3528
|
+
const sizeDirty = curW !== nextW || curH !== nextH;
|
|
3529
|
+
if (positionDirty) {
|
|
3530
|
+
out.push(change.node.position(parent.id, { x: targetX, y: targetY }, false));
|
|
3531
|
+
}
|
|
3532
|
+
if (sizeDirty) {
|
|
3533
|
+
out.push(change.node.dimensions(parent.id, { width: nextW, height: nextH }));
|
|
3534
|
+
}
|
|
3535
|
+
}
|
|
3536
|
+
return out;
|
|
3537
|
+
}
|
|
3538
|
+
var EdgesLayer = (0, import_react15.memo)(function EdgesLayer2({
|
|
3151
3539
|
edges,
|
|
3152
3540
|
nodes,
|
|
3153
3541
|
onSelect,
|
|
@@ -3156,7 +3544,7 @@ var EdgesLayer = (0, import_react14.memo)(function EdgesLayer2({
|
|
|
3156
3544
|
ghost,
|
|
3157
3545
|
handleVersion: _handleVersion
|
|
3158
3546
|
}) {
|
|
3159
|
-
return /* @__PURE__ */ (0,
|
|
3547
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
3160
3548
|
"svg",
|
|
3161
3549
|
{
|
|
3162
3550
|
className: "ods-flow-canvas-v2__edges",
|
|
@@ -3164,7 +3552,7 @@ var EdgesLayer = (0, import_react14.memo)(function EdgesLayer2({
|
|
|
3164
3552
|
width: "100%",
|
|
3165
3553
|
height: "100%",
|
|
3166
3554
|
children: [
|
|
3167
|
-
/* @__PURE__ */ (0,
|
|
3555
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("g", { style: { pointerEvents: "auto" }, children: edges.map((edge) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3168
3556
|
FlowEdge,
|
|
3169
3557
|
{
|
|
3170
3558
|
edge,
|
|
@@ -3176,7 +3564,7 @@ var EdgesLayer = (0, import_react14.memo)(function EdgesLayer2({
|
|
|
3176
3564
|
},
|
|
3177
3565
|
edge.id
|
|
3178
3566
|
)) }),
|
|
3179
|
-
ghost && /* @__PURE__ */ (0,
|
|
3567
|
+
ghost && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3180
3568
|
"path",
|
|
3181
3569
|
{
|
|
3182
3570
|
d: `M ${ghost.start.x} ${ghost.start.y} L ${ghost.end.x} ${ghost.end.y}`,
|
|
@@ -3191,153 +3579,231 @@ var EdgesLayer = (0, import_react14.memo)(function EdgesLayer2({
|
|
|
3191
3579
|
);
|
|
3192
3580
|
});
|
|
3193
3581
|
|
|
3194
|
-
// src/workflow/components/
|
|
3195
|
-
var
|
|
3196
|
-
var
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3582
|
+
// src/workflow/components/FxPanel/FxPanel.tsx
|
|
3583
|
+
var import_react16 = require("react");
|
|
3584
|
+
var import_icons2 = require("@octaviaflow/icons");
|
|
3585
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
3586
|
+
var KIND_GLYPH = {
|
|
3587
|
+
function: "\u0192",
|
|
3588
|
+
variable: "\u2B21"
|
|
3589
|
+
};
|
|
3590
|
+
function FxPanel({
|
|
3591
|
+
categories,
|
|
3592
|
+
title = "FX / IO",
|
|
3593
|
+
hint = /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
3594
|
+
"Drag items into any input field with the ",
|
|
3595
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("strong", { children: "FX" }),
|
|
3596
|
+
" indicator"
|
|
3597
|
+
] }),
|
|
3598
|
+
search: controlledSearch,
|
|
3599
|
+
defaultSearch = "",
|
|
3600
|
+
onSearchChange,
|
|
3601
|
+
expandedCategory: controlledExpanded,
|
|
3602
|
+
defaultExpandedCategory,
|
|
3603
|
+
onExpandedCategoryChange,
|
|
3604
|
+
onClose,
|
|
3605
|
+
onItemDragStart,
|
|
3606
|
+
onItemSelect,
|
|
3607
|
+
width = 292,
|
|
3608
|
+
emptyLabel = "No matches",
|
|
3609
|
+
searchPlaceholder = "Search functions & variables\u2026",
|
|
3610
|
+
className,
|
|
3611
|
+
style
|
|
3207
3612
|
}) {
|
|
3208
|
-
const
|
|
3209
|
-
const
|
|
3210
|
-
const
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
if (!show) return null;
|
|
3214
|
-
const beginResize = (e, corner) => {
|
|
3215
|
-
e.preventDefault();
|
|
3216
|
-
e.stopPropagation();
|
|
3217
|
-
e.target.setPointerCapture(e.pointerId);
|
|
3218
|
-
const w = node.width ?? DEFAULT_NODE_WIDTH;
|
|
3219
|
-
const h = node.height ?? DEFAULT_NODE_HEIGHT;
|
|
3220
|
-
dragRef.current = {
|
|
3221
|
-
pointerId: e.pointerId,
|
|
3222
|
-
corner,
|
|
3223
|
-
startClientX: e.clientX,
|
|
3224
|
-
startClientY: e.clientY,
|
|
3225
|
-
startWidth: w,
|
|
3226
|
-
startHeight: h,
|
|
3227
|
-
startX: node.position.x,
|
|
3228
|
-
startY: node.position.y,
|
|
3229
|
-
aspect: w / Math.max(1, h)
|
|
3230
|
-
};
|
|
3613
|
+
const [internalSearch, setInternalSearch] = (0, import_react16.useState)(defaultSearch);
|
|
3614
|
+
const search = controlledSearch ?? internalSearch;
|
|
3615
|
+
const setSearch = (next) => {
|
|
3616
|
+
if (controlledSearch === void 0) setInternalSearch(next);
|
|
3617
|
+
onSearchChange?.(next);
|
|
3231
3618
|
};
|
|
3232
|
-
const
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
let nextX = drag.startX;
|
|
3240
|
-
let nextY = drag.startY;
|
|
3241
|
-
switch (drag.corner) {
|
|
3242
|
-
case "se":
|
|
3243
|
-
nextW = drag.startWidth + dx;
|
|
3244
|
-
nextH = drag.startHeight + dy;
|
|
3245
|
-
break;
|
|
3246
|
-
case "sw":
|
|
3247
|
-
nextW = drag.startWidth - dx;
|
|
3248
|
-
nextH = drag.startHeight + dy;
|
|
3249
|
-
nextX = drag.startX + dx;
|
|
3250
|
-
break;
|
|
3251
|
-
case "ne":
|
|
3252
|
-
nextW = drag.startWidth + dx;
|
|
3253
|
-
nextH = drag.startHeight - dy;
|
|
3254
|
-
nextY = drag.startY + dy;
|
|
3255
|
-
break;
|
|
3256
|
-
case "nw":
|
|
3257
|
-
nextW = drag.startWidth - dx;
|
|
3258
|
-
nextH = drag.startHeight - dy;
|
|
3259
|
-
nextX = drag.startX + dx;
|
|
3260
|
-
nextY = drag.startY + dy;
|
|
3261
|
-
break;
|
|
3262
|
-
}
|
|
3263
|
-
if (keepAspectRatio) {
|
|
3264
|
-
nextH = nextW / drag.aspect;
|
|
3265
|
-
if (drag.corner === "nw" || drag.corner === "ne") {
|
|
3266
|
-
nextY = drag.startY + (drag.startHeight - nextH);
|
|
3267
|
-
}
|
|
3268
|
-
}
|
|
3269
|
-
nextW = Math.max(minWidth, maxWidth ? Math.min(maxWidth, nextW) : nextW);
|
|
3270
|
-
nextH = Math.max(minHeight, maxHeight ? Math.min(maxHeight, nextH) : nextH);
|
|
3271
|
-
flow.updateNode(node.id, {
|
|
3272
|
-
width: nextW,
|
|
3273
|
-
height: nextH,
|
|
3274
|
-
position: { x: nextX, y: nextY }
|
|
3275
|
-
});
|
|
3276
|
-
onResize?.({ width: nextW, height: nextH });
|
|
3277
|
-
};
|
|
3278
|
-
const onUp = (e) => {
|
|
3279
|
-
if (dragRef.current?.pointerId === e.pointerId) {
|
|
3280
|
-
const cur = flow.getNode(node.id);
|
|
3281
|
-
if (cur) {
|
|
3282
|
-
onResizeEnd?.({
|
|
3283
|
-
width: cur.width ?? DEFAULT_NODE_WIDTH,
|
|
3284
|
-
height: cur.height ?? DEFAULT_NODE_HEIGHT
|
|
3285
|
-
});
|
|
3286
|
-
}
|
|
3287
|
-
dragRef.current = null;
|
|
3288
|
-
}
|
|
3619
|
+
const [internalExpanded, setInternalExpanded] = (0, import_react16.useState)(
|
|
3620
|
+
defaultExpandedCategory !== void 0 ? defaultExpandedCategory : categories.find((c) => c.items.length > 0)?.id ?? null
|
|
3621
|
+
);
|
|
3622
|
+
const expanded = controlledExpanded ?? internalExpanded;
|
|
3623
|
+
const setExpanded = (id) => {
|
|
3624
|
+
if (controlledExpanded === void 0) setInternalExpanded(id);
|
|
3625
|
+
onExpandedCategoryChange?.(id);
|
|
3289
3626
|
};
|
|
3290
|
-
const
|
|
3291
|
-
const
|
|
3292
|
-
const
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3627
|
+
const [draggingId, setDraggingId] = (0, import_react16.useState)(null);
|
|
3628
|
+
const filtered = (0, import_react16.useMemo)(() => {
|
|
3629
|
+
const q = search.trim().toLowerCase();
|
|
3630
|
+
if (!q) return categories;
|
|
3631
|
+
return categories.map((cat) => {
|
|
3632
|
+
if (cat.label.toLowerCase().includes(q)) return cat;
|
|
3633
|
+
const items = cat.items.filter(
|
|
3634
|
+
(it) => it.label.toLowerCase().includes(q) || (it.description?.toLowerCase().includes(q) ?? false)
|
|
3635
|
+
);
|
|
3636
|
+
return { ...cat, items };
|
|
3637
|
+
}).filter((cat) => cat.items.length > 0);
|
|
3638
|
+
}, [categories, search]);
|
|
3639
|
+
const hasResults = filtered.length > 0;
|
|
3640
|
+
const handleDragStart = (item, category) => (e) => {
|
|
3641
|
+
setDraggingId(item.id);
|
|
3642
|
+
if (onItemDragStart) {
|
|
3643
|
+
onItemDragStart(item, category, e);
|
|
3644
|
+
} else {
|
|
3645
|
+
e.dataTransfer.setData("text/plain", item.insertValue);
|
|
3646
|
+
e.dataTransfer.setData("application/x-fx-insert", item.insertValue);
|
|
3647
|
+
e.dataTransfer.setData(
|
|
3648
|
+
"application/x-fx-type",
|
|
3649
|
+
category.kind ?? "function"
|
|
3650
|
+
);
|
|
3651
|
+
e.dataTransfer.effectAllowed = "copy";
|
|
3313
3652
|
}
|
|
3314
3653
|
};
|
|
3315
|
-
return /* @__PURE__ */ (0,
|
|
3316
|
-
"
|
|
3654
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
3655
|
+
"aside",
|
|
3317
3656
|
{
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
|
|
3657
|
+
className: cn("ods-flow-fx-panel", className),
|
|
3658
|
+
style: { width, ...style },
|
|
3659
|
+
"aria-label": typeof title === "string" ? title : "FX / IO",
|
|
3660
|
+
children: [
|
|
3661
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("header", { className: "ods-flow-fx-panel__header", children: [
|
|
3662
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h3", { className: "ods-flow-fx-panel__title", children: title }),
|
|
3663
|
+
onClose && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3664
|
+
"button",
|
|
3665
|
+
{
|
|
3666
|
+
type: "button",
|
|
3667
|
+
className: "ods-flow-fx-panel__close",
|
|
3668
|
+
onClick: onClose,
|
|
3669
|
+
"aria-label": "Close FX panel",
|
|
3670
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_icons2.CloseIcon, { size: "sm" })
|
|
3671
|
+
}
|
|
3672
|
+
)
|
|
3673
|
+
] }),
|
|
3674
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "ods-flow-fx-panel__search", children: [
|
|
3675
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "ods-flow-fx-panel__search-icon", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_icons2.SearchIcon, { size: "sm" }) }),
|
|
3676
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3677
|
+
"input",
|
|
3678
|
+
{
|
|
3679
|
+
type: "text",
|
|
3680
|
+
className: "ods-flow-fx-panel__search-input",
|
|
3681
|
+
placeholder: searchPlaceholder,
|
|
3682
|
+
"aria-label": "Search functions and variables",
|
|
3683
|
+
value: search,
|
|
3684
|
+
onChange: (e) => setSearch(e.target.value)
|
|
3685
|
+
}
|
|
3686
|
+
),
|
|
3687
|
+
search && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3688
|
+
"button",
|
|
3689
|
+
{
|
|
3690
|
+
type: "button",
|
|
3691
|
+
className: "ods-flow-fx-panel__search-clear",
|
|
3692
|
+
onClick: () => setSearch(""),
|
|
3693
|
+
"aria-label": "Clear search",
|
|
3694
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_icons2.CloseIcon, { size: "sm" })
|
|
3695
|
+
}
|
|
3696
|
+
)
|
|
3697
|
+
] }),
|
|
3698
|
+
hint && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "ods-flow-fx-panel__hint", children: hint }),
|
|
3699
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "ods-flow-fx-panel__list", children: [
|
|
3700
|
+
filtered.map((cat) => {
|
|
3701
|
+
const isOpen = expanded === cat.id;
|
|
3702
|
+
const kind = cat.kind ?? "function";
|
|
3703
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "ods-flow-fx-panel__category", children: [
|
|
3704
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
3705
|
+
"button",
|
|
3706
|
+
{
|
|
3707
|
+
type: "button",
|
|
3708
|
+
className: "ods-flow-fx-panel__category-header",
|
|
3709
|
+
"aria-expanded": isOpen,
|
|
3710
|
+
onClick: () => setExpanded(isOpen ? null : cat.id),
|
|
3711
|
+
children: [
|
|
3712
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3713
|
+
import_icons2.ChevronRightIcon,
|
|
3714
|
+
{
|
|
3715
|
+
size: "sm",
|
|
3716
|
+
className: cn(
|
|
3717
|
+
"ods-flow-fx-panel__chevron",
|
|
3718
|
+
isOpen && "ods-flow-fx-panel__chevron--open"
|
|
3719
|
+
)
|
|
3720
|
+
}
|
|
3721
|
+
),
|
|
3722
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
3723
|
+
"span",
|
|
3724
|
+
{
|
|
3725
|
+
className: cn(
|
|
3726
|
+
"ods-flow-fx-panel__badge",
|
|
3727
|
+
`ods-flow-fx-panel__badge--${kind}`
|
|
3728
|
+
),
|
|
3729
|
+
children: [
|
|
3730
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3731
|
+
"span",
|
|
3732
|
+
{
|
|
3733
|
+
className: "ods-flow-fx-panel__badge-glyph",
|
|
3734
|
+
"aria-hidden": "true",
|
|
3735
|
+
children: KIND_GLYPH[kind]
|
|
3736
|
+
}
|
|
3737
|
+
),
|
|
3738
|
+
cat.label
|
|
3739
|
+
]
|
|
3740
|
+
}
|
|
3741
|
+
),
|
|
3742
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "ods-flow-fx-panel__count", children: cat.items.length })
|
|
3743
|
+
]
|
|
3744
|
+
}
|
|
3745
|
+
),
|
|
3746
|
+
isOpen && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "ods-flow-fx-panel__items", children: cat.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
3747
|
+
"div",
|
|
3748
|
+
{
|
|
3749
|
+
className: cn(
|
|
3750
|
+
"ods-flow-fx-panel__item",
|
|
3751
|
+
draggingId === item.id && "ods-flow-fx-panel__item--dragging"
|
|
3752
|
+
),
|
|
3753
|
+
draggable: true,
|
|
3754
|
+
title: item.insertValue,
|
|
3755
|
+
onDragStart: handleDragStart(item, cat),
|
|
3756
|
+
onDragEnd: () => setDraggingId(null),
|
|
3757
|
+
onClick: onItemSelect ? () => onItemSelect(item, cat) : void 0,
|
|
3758
|
+
children: [
|
|
3759
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("code", { className: "ods-flow-fx-panel__item-label", children: item.label }),
|
|
3760
|
+
item.description && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "ods-flow-fx-panel__item-desc", children: item.description })
|
|
3761
|
+
]
|
|
3762
|
+
},
|
|
3763
|
+
item.id
|
|
3764
|
+
)) })
|
|
3765
|
+
] }, cat.id);
|
|
3766
|
+
}),
|
|
3767
|
+
!hasResults && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "ods-flow-fx-panel__empty", children: emptyLabel })
|
|
3768
|
+
] })
|
|
3769
|
+
]
|
|
3770
|
+
}
|
|
3771
|
+
);
|
|
3327
3772
|
}
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
|
|
3773
|
+
|
|
3774
|
+
// src/workflow/components/FxPanel/FxToggleButton.tsx
|
|
3775
|
+
var import_icons3 = require("@octaviaflow/icons");
|
|
3776
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
3777
|
+
function FxToggleButton({
|
|
3778
|
+
active = false,
|
|
3779
|
+
label = "FX",
|
|
3780
|
+
className,
|
|
3781
|
+
type = "button",
|
|
3782
|
+
...rest
|
|
3783
|
+
}) {
|
|
3784
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
|
|
3785
|
+
"button",
|
|
3786
|
+
{
|
|
3787
|
+
...rest,
|
|
3788
|
+
type,
|
|
3789
|
+
className: cn(
|
|
3790
|
+
"ods-flow-fx-toggle",
|
|
3791
|
+
active && "ods-flow-fx-toggle--active",
|
|
3792
|
+
label == null && "ods-flow-fx-toggle--icon-only",
|
|
3793
|
+
className
|
|
3794
|
+
),
|
|
3795
|
+
"aria-pressed": active,
|
|
3796
|
+
title: active ? "Hide FX / IO" : "Show FX / IO",
|
|
3797
|
+
children: [
|
|
3798
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_icons3.FunctionIcon, { size: "sm", className: "ods-flow-fx-toggle__icon" }),
|
|
3799
|
+
label != null && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "ods-flow-fx-toggle__label", children: label })
|
|
3800
|
+
]
|
|
3801
|
+
}
|
|
3802
|
+
);
|
|
3337
3803
|
}
|
|
3338
3804
|
|
|
3339
3805
|
// src/workflow/components/NodeToolbar/NodeToolbar.tsx
|
|
3340
|
-
var
|
|
3806
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
3341
3807
|
function NodeToolbar({
|
|
3342
3808
|
isVisible,
|
|
3343
3809
|
position = "top",
|
|
@@ -3352,7 +3818,7 @@ function NodeToolbar({
|
|
|
3352
3818
|
const show = isVisible ?? node.selected;
|
|
3353
3819
|
if (!show) return null;
|
|
3354
3820
|
const inverseScale = 1 / viewport.zoom;
|
|
3355
|
-
return /* @__PURE__ */ (0,
|
|
3821
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3356
3822
|
"div",
|
|
3357
3823
|
{
|
|
3358
3824
|
className: cn("ods-node-toolbar", `ods-node-toolbar--${position}`, className),
|
|
@@ -3364,7 +3830,7 @@ function NodeToolbar({
|
|
|
3364
3830
|
onPointerDown: (e) => e.stopPropagation(),
|
|
3365
3831
|
onMouseDown: (e) => e.stopPropagation(),
|
|
3366
3832
|
onClick: (e) => e.stopPropagation(),
|
|
3367
|
-
children: /* @__PURE__ */ (0,
|
|
3833
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
3368
3834
|
"div",
|
|
3369
3835
|
{
|
|
3370
3836
|
className: "ods-node-toolbar__inner",
|
|
@@ -3518,6 +3984,8 @@ function toggleGroupCollapse(groupId, nodes) {
|
|
|
3518
3984
|
FlowEdge,
|
|
3519
3985
|
FlowNode,
|
|
3520
3986
|
ForEachNode,
|
|
3987
|
+
FxPanel,
|
|
3988
|
+
FxToggleButton,
|
|
3521
3989
|
GroupNode,
|
|
3522
3990
|
Handle,
|
|
3523
3991
|
HttpRequestNode,
|
|
@@ -3564,6 +4032,7 @@ function toggleGroupCollapse(groupId, nodes) {
|
|
|
3564
4032
|
useNodeData,
|
|
3565
4033
|
useNodes,
|
|
3566
4034
|
useSelection,
|
|
3567
|
-
useViewport
|
|
4035
|
+
useViewport,
|
|
4036
|
+
useViewportOrNull
|
|
3568
4037
|
});
|
|
3569
4038
|
//# sourceMappingURL=workflow.cjs.map
|