@nocobase/flow-engine 2.1.0-beta.22 → 2.1.0-beta.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/lib/components/FieldModelRenderer.js +2 -2
  2. package/lib/components/FlowModelRenderer.d.ts +2 -0
  3. package/lib/components/FlowModelRenderer.js +2 -0
  4. package/lib/components/dnd/gridDragPlanner.d.ts +59 -2
  5. package/lib/components/dnd/gridDragPlanner.js +595 -19
  6. package/lib/components/dnd/index.d.ts +19 -1
  7. package/lib/components/dnd/index.js +243 -23
  8. package/lib/components/settings/wrappers/contextual/DefaultSettingsIcon.js +20 -1
  9. package/lib/components/settings/wrappers/contextual/FlowsFloatContextMenu.d.ts +4 -0
  10. package/lib/components/settings/wrappers/contextual/FlowsFloatContextMenu.js +21 -8
  11. package/lib/components/settings/wrappers/contextual/useFloatToolbarPortal.js +2 -0
  12. package/lib/components/settings/wrappers/contextual/useFloatToolbarVisibility.js +100 -32
  13. package/lib/components/subModel/index.d.ts +1 -0
  14. package/lib/components/subModel/index.js +19 -0
  15. package/lib/components/subModel/utils.d.ts +1 -1
  16. package/lib/data-source/index.d.ts +73 -0
  17. package/lib/data-source/index.js +205 -1
  18. package/lib/flowContext.d.ts +2 -0
  19. package/lib/flowI18n.js +2 -1
  20. package/lib/models/DisplayItemModel.d.ts +1 -1
  21. package/lib/models/EditableItemModel.d.ts +1 -1
  22. package/lib/models/FilterableItemModel.d.ts +1 -1
  23. package/lib/models/flowModel.d.ts +11 -9
  24. package/lib/models/flowModel.js +48 -9
  25. package/lib/provider.js +38 -23
  26. package/package.json +4 -4
  27. package/src/__tests__/provider.test.tsx +24 -2
  28. package/src/components/FieldModelRenderer.tsx +2 -1
  29. package/src/components/FlowModelRenderer.tsx +6 -0
  30. package/src/components/__tests__/dnd.test.ts +44 -0
  31. package/src/components/__tests__/gridDragPlanner.test.ts +426 -5
  32. package/src/components/dnd/__tests__/DndProvider.test.tsx +98 -0
  33. package/src/components/dnd/gridDragPlanner.ts +735 -17
  34. package/src/components/dnd/index.tsx +291 -27
  35. package/src/components/settings/wrappers/contextual/DefaultSettingsIcon.tsx +25 -1
  36. package/src/components/settings/wrappers/contextual/FlowsFloatContextMenu.tsx +24 -5
  37. package/src/components/settings/wrappers/contextual/__tests__/DefaultSettingsIcon.test.tsx +94 -3
  38. package/src/components/settings/wrappers/contextual/__tests__/FlowsFloatContextMenu.test.tsx +171 -2
  39. package/src/components/settings/wrappers/contextual/useFloatToolbarPortal.ts +2 -0
  40. package/src/components/settings/wrappers/contextual/useFloatToolbarVisibility.ts +112 -32
  41. package/src/components/subModel/index.ts +1 -0
  42. package/src/data-source/__tests__/index.test.ts +34 -1
  43. package/src/data-source/index.ts +252 -2
  44. package/src/flowContext.ts +2 -0
  45. package/src/flowI18n.ts +2 -1
  46. package/src/models/DisplayItemModel.tsx +1 -1
  47. package/src/models/EditableItemModel.tsx +1 -1
  48. package/src/models/FilterableItemModel.tsx +1 -1
  49. package/src/models/flowModel.tsx +85 -23
  50. package/src/provider.tsx +41 -25
@@ -7,15 +7,33 @@
7
7
  * For more information, please refer to: https://www.nocobase.com/agreement.
8
8
  */
9
9
  import { DndContextProps } from '@dnd-kit/core';
10
+ import type { Transform } from '@dnd-kit/utilities';
10
11
  import React, { FC } from 'react';
11
12
  import { FlowModel } from '../../models';
12
13
  import { PersistOptions } from '../../types';
13
14
  export * from './findModelUidPosition';
14
15
  export * from './gridDragPlanner';
15
16
  export declare const EMPTY_COLUMN_UID = "EMPTY_COLUMN";
17
+ export declare const TOOLBAR_DRAG_ACTIVITY_EVENT = "nb-toolbar-drag-activity";
18
+ type ToolbarDragAnchorPoint = {
19
+ x: number;
20
+ y: number;
21
+ };
22
+ export declare const resolveOverlayAnchorTransform: ({ activeId, active, transform, activeNodeRect, dragAnchorPoint, }: {
23
+ activeId: string | null;
24
+ active: {
25
+ id: string | number;
26
+ } | null | undefined;
27
+ transform: Transform;
28
+ activeNodeRect: {
29
+ top: number;
30
+ left: number;
31
+ } | null;
32
+ dragAnchorPoint: ToolbarDragAnchorPoint | null;
33
+ }) => Transform;
16
34
  export declare const DragHandler: FC<{
17
35
  model: FlowModel;
18
- children: React.ReactNode;
36
+ children?: React.ReactNode;
19
37
  }>;
20
38
  export declare const Droppable: FC<{
21
39
  model: FlowModel<any>;
@@ -41,7 +41,9 @@ __export(dnd_exports, {
41
41
  DndProvider: () => DndProvider,
42
42
  DragHandler: () => DragHandler,
43
43
  Droppable: () => Droppable,
44
- EMPTY_COLUMN_UID: () => EMPTY_COLUMN_UID
44
+ EMPTY_COLUMN_UID: () => EMPTY_COLUMN_UID,
45
+ TOOLBAR_DRAG_ACTIVITY_EVENT: () => TOOLBAR_DRAG_ACTIVITY_EVENT,
46
+ resolveOverlayAnchorTransform: () => resolveOverlayAnchorTransform
45
47
  });
46
48
  module.exports = __toCommonJS(dnd_exports);
47
49
  var import_icons = require("@ant-design/icons");
@@ -52,17 +54,186 @@ var import_provider = require("../../provider");
52
54
  __reExport(dnd_exports, require("./findModelUidPosition"), module.exports);
53
55
  __reExport(dnd_exports, require("./gridDragPlanner"), module.exports);
54
56
  const EMPTY_COLUMN_UID = "EMPTY_COLUMN";
57
+ const TOOLBAR_DRAG_ACTIVITY_EVENT = "nb-toolbar-drag-activity";
58
+ const TOOLBAR_DRAG_ANCHOR_EVENT = "nb-toolbar-drag-anchor";
59
+ const MENU_SUBMENU_POPUP_SELECTOR = ".ant-menu-submenu-popup";
60
+ const resolveOverlayAnchorTransform = /* @__PURE__ */ __name(({
61
+ activeId,
62
+ active,
63
+ transform,
64
+ activeNodeRect,
65
+ dragAnchorPoint
66
+ }) => {
67
+ if (!activeId || (active == null ? void 0 : active.id) !== activeId || !dragAnchorPoint || !activeNodeRect) {
68
+ return transform;
69
+ }
70
+ return {
71
+ ...transform,
72
+ x: transform.x + dragAnchorPoint.x - activeNodeRect.left,
73
+ y: transform.y + dragAnchorPoint.y - activeNodeRect.top
74
+ };
75
+ }, "resolveOverlayAnchorTransform");
76
+ const resolveDraggableHostNode = /* @__PURE__ */ __name((activatorNode) => {
77
+ const ownerDocument = activatorNode == null ? void 0 : activatorNode.ownerDocument;
78
+ const floatToolbarContainer = activatorNode == null ? void 0 : activatorNode.closest(".nb-toolbar-container[data-model-uid]");
79
+ const toolbarModelUid = floatToolbarContainer == null ? void 0 : floatToolbarContainer.getAttribute("data-model-uid");
80
+ if (!ownerDocument || !toolbarModelUid) {
81
+ return activatorNode;
82
+ }
83
+ const matchedHosts = Array.from(
84
+ ownerDocument.querySelectorAll(
85
+ `[data-has-float-menu="true"][data-float-menu-model-uid="${toolbarModelUid}"]`
86
+ )
87
+ );
88
+ const popupRoot = floatToolbarContainer == null ? void 0 : floatToolbarContainer.closest(MENU_SUBMENU_POPUP_SELECTOR);
89
+ if (popupRoot) {
90
+ return matchedHosts.find((hostNode) => hostNode.closest(MENU_SUBMENU_POPUP_SELECTOR) === popupRoot) || activatorNode;
91
+ }
92
+ return matchedHosts.find((hostNode) => !hostNode.closest(MENU_SUBMENU_POPUP_SELECTOR)) || matchedHosts[0] || activatorNode;
93
+ }, "resolveDraggableHostNode");
55
94
  const DragHandler = /* @__PURE__ */ __name(({
56
95
  model,
57
96
  children = /* @__PURE__ */ import_react.default.createElement(import_icons.DragOutlined, null)
58
97
  }) => {
59
- const { attributes, listeners, setNodeRef } = (0, import_core.useDraggable)({ id: model.uid });
98
+ const { attributes, isDragging, listeners, setActivatorNodeRef, setNodeRef } = (0, import_core.useDraggable)({ id: model.uid });
99
+ const dragHandlerRef = (0, import_react.useRef)(null);
100
+ const draggableNodeRef = (0, import_react.useRef)(null);
101
+ const pointerPressCleanupRef = (0, import_react.useRef)(null);
102
+ const isDraggingRef = (0, import_react.useRef)(isDragging);
103
+ const isPointerPressActiveRef = (0, import_react.useRef)(false);
104
+ const isToolbarDragActiveRef = (0, import_react.useRef)(false);
105
+ const syncDraggableNodeRef = (0, import_react.useCallback)(
106
+ (activatorNode) => {
107
+ const nextNode = resolveDraggableHostNode(activatorNode);
108
+ if (draggableNodeRef.current === nextNode) {
109
+ return;
110
+ }
111
+ draggableNodeRef.current = nextNode;
112
+ setNodeRef(nextNode);
113
+ },
114
+ [setNodeRef]
115
+ );
116
+ const setDragHandlerNodeRef = (0, import_react.useCallback)(
117
+ (node) => {
118
+ dragHandlerRef.current = node;
119
+ setActivatorNodeRef(node);
120
+ syncDraggableNodeRef(node);
121
+ },
122
+ [setActivatorNodeRef, syncDraggableNodeRef]
123
+ );
124
+ const dispatchToolbarDragActivity = (0, import_react.useCallback)(
125
+ (active) => {
126
+ var _a;
127
+ const ownerDocument = (_a = dragHandlerRef.current) == null ? void 0 : _a.ownerDocument;
128
+ if (!ownerDocument) {
129
+ return;
130
+ }
131
+ ownerDocument.dispatchEvent(
132
+ new CustomEvent(TOOLBAR_DRAG_ACTIVITY_EVENT, {
133
+ detail: { active, modelUid: model.uid }
134
+ })
135
+ );
136
+ },
137
+ [model.uid]
138
+ );
139
+ const dispatchToolbarDragAnchor = (0, import_react.useCallback)(
140
+ (detail) => {
141
+ var _a;
142
+ const ownerDocument = (_a = dragHandlerRef.current) == null ? void 0 : _a.ownerDocument;
143
+ if (!ownerDocument) {
144
+ return;
145
+ }
146
+ ownerDocument.dispatchEvent(
147
+ new CustomEvent(TOOLBAR_DRAG_ANCHOR_EVENT, {
148
+ detail: { modelUid: model.uid, point: detail.point }
149
+ })
150
+ );
151
+ },
152
+ [model.uid]
153
+ );
154
+ const clearPointerPressListeners = (0, import_react.useCallback)(() => {
155
+ var _a;
156
+ (_a = pointerPressCleanupRef.current) == null ? void 0 : _a.call(pointerPressCleanupRef);
157
+ pointerPressCleanupRef.current = null;
158
+ }, []);
159
+ const syncToolbarDragActivity = (0, import_react.useCallback)(() => {
160
+ const nextActive = isPointerPressActiveRef.current || isDraggingRef.current;
161
+ if (nextActive === isToolbarDragActiveRef.current) {
162
+ return;
163
+ }
164
+ isToolbarDragActiveRef.current = nextActive;
165
+ dispatchToolbarDragActivity(nextActive);
166
+ }, [dispatchToolbarDragActivity]);
167
+ const handlePointerPressEnd = (0, import_react.useCallback)(() => {
168
+ isPointerPressActiveRef.current = false;
169
+ clearPointerPressListeners();
170
+ syncToolbarDragActivity();
171
+ }, [clearPointerPressListeners, syncToolbarDragActivity]);
172
+ const registerPointerPressListeners = (0, import_react.useCallback)(() => {
173
+ var _a;
174
+ const ownerDocument = (_a = dragHandlerRef.current) == null ? void 0 : _a.ownerDocument;
175
+ const ownerWindow = ownerDocument == null ? void 0 : ownerDocument.defaultView;
176
+ if (!ownerDocument) {
177
+ return;
178
+ }
179
+ clearPointerPressListeners();
180
+ const handlePointerEnd = /* @__PURE__ */ __name(() => {
181
+ handlePointerPressEnd();
182
+ }, "handlePointerEnd");
183
+ const handleKeyDown = /* @__PURE__ */ __name((event) => {
184
+ if (event.key === "Escape") {
185
+ handlePointerPressEnd();
186
+ }
187
+ }, "handleKeyDown");
188
+ ownerDocument.addEventListener("pointerup", handlePointerEnd, true);
189
+ ownerDocument.addEventListener("pointercancel", handlePointerEnd, true);
190
+ ownerDocument.addEventListener("keydown", handleKeyDown, true);
191
+ ownerWindow == null ? void 0 : ownerWindow.addEventListener("blur", handlePointerEnd);
192
+ pointerPressCleanupRef.current = () => {
193
+ ownerDocument.removeEventListener("pointerup", handlePointerEnd, true);
194
+ ownerDocument.removeEventListener("pointercancel", handlePointerEnd, true);
195
+ ownerDocument.removeEventListener("keydown", handleKeyDown, true);
196
+ ownerWindow == null ? void 0 : ownerWindow.removeEventListener("blur", handlePointerEnd);
197
+ };
198
+ }, [clearPointerPressListeners, handlePointerPressEnd]);
199
+ (0, import_react.useEffect)(() => {
200
+ syncDraggableNodeRef(dragHandlerRef.current);
201
+ }, [syncDraggableNodeRef]);
202
+ (0, import_react.useEffect)(() => {
203
+ isDraggingRef.current = isDragging;
204
+ syncToolbarDragActivity();
205
+ }, [isDragging, syncToolbarDragActivity]);
206
+ (0, import_react.useEffect)(() => {
207
+ return () => {
208
+ if (isToolbarDragActiveRef.current) {
209
+ dispatchToolbarDragActivity(false);
210
+ }
211
+ isPointerPressActiveRef.current = false;
212
+ isDraggingRef.current = false;
213
+ isToolbarDragActiveRef.current = false;
214
+ clearPointerPressListeners();
215
+ };
216
+ }, [clearPointerPressListeners, dispatchToolbarDragActivity]);
60
217
  return /* @__PURE__ */ import_react.default.createElement(
61
218
  "span",
62
219
  {
63
- ref: setNodeRef,
220
+ ref: setDragHandlerNodeRef,
64
221
  ...listeners,
65
222
  ...attributes,
223
+ onPointerDownCapture: (event) => {
224
+ if (event.button !== 0) {
225
+ return;
226
+ }
227
+ dispatchToolbarDragAnchor({
228
+ point: {
229
+ x: event.clientX,
230
+ y: event.clientY
231
+ }
232
+ });
233
+ isPointerPressActiveRef.current = true;
234
+ syncToolbarDragActivity();
235
+ registerPointerPressListeners();
236
+ },
66
237
  style: {
67
238
  cursor: "grab"
68
239
  }
@@ -104,21 +275,52 @@ const Droppable = /* @__PURE__ */ __name(({ model, children }) => {
104
275
  const DndProvider = /* @__PURE__ */ __name(({
105
276
  persist = true,
106
277
  children,
278
+ onDragStart,
107
279
  onDragEnd,
280
+ onDragCancel,
108
281
  ...restProps
109
282
  }) => {
110
283
  const [activeId, setActiveId] = (0, import_react.useState)(null);
284
+ const [dragAnchorPoint, setDragAnchorPoint] = (0, import_react.useState)(null);
111
285
  const flowEngine = (0, import_provider.useFlowEngine)();
286
+ (0, import_react.useEffect)(() => {
287
+ if (typeof document === "undefined") {
288
+ return;
289
+ }
290
+ const handleToolbarDragAnchor = /* @__PURE__ */ __name((event) => {
291
+ var _a;
292
+ const customEvent = event;
293
+ setDragAnchorPoint(((_a = customEvent.detail) == null ? void 0 : _a.point) || null);
294
+ }, "handleToolbarDragAnchor");
295
+ document.addEventListener(TOOLBAR_DRAG_ANCHOR_EVENT, handleToolbarDragAnchor);
296
+ return () => {
297
+ document.removeEventListener(TOOLBAR_DRAG_ANCHOR_EVENT, handleToolbarDragAnchor);
298
+ };
299
+ }, []);
300
+ const overlayAnchorModifier = (0, import_react.useCallback)(
301
+ ({ active, activeNodeRect, transform }) => {
302
+ const nextTransform = resolveOverlayAnchorTransform({
303
+ activeId,
304
+ active,
305
+ transform,
306
+ activeNodeRect,
307
+ dragAnchorPoint
308
+ });
309
+ return nextTransform;
310
+ },
311
+ [activeId, dragAnchorPoint]
312
+ );
112
313
  return /* @__PURE__ */ import_react.default.createElement(
113
314
  import_core.DndContext,
114
315
  {
316
+ ...restProps,
115
317
  onDragStart: (event) => {
116
- var _a;
117
318
  setActiveId(event.active.id);
118
- (_a = restProps.onDragStart) == null ? void 0 : _a.call(restProps, event);
319
+ onDragStart == null ? void 0 : onDragStart(event);
119
320
  },
120
321
  onDragEnd: (event) => {
121
322
  setActiveId(null);
323
+ setDragAnchorPoint(null);
122
324
  if (!onDragEnd) {
123
325
  if (event.over) {
124
326
  flowEngine.moveModel(event.active.id, event.over.id, { persist });
@@ -127,30 +329,46 @@ const DndProvider = /* @__PURE__ */ __name(({
127
329
  onDragEnd(event);
128
330
  }
129
331
  },
332
+ onDragCancel: (event) => {
333
+ setActiveId(null);
334
+ setDragAnchorPoint(null);
335
+ onDragCancel == null ? void 0 : onDragCancel(event);
336
+ },
130
337
  ...restProps
131
338
  },
132
339
  children,
133
- (0, import_react_dom.createPortal)(
134
- /* @__PURE__ */ import_react.default.createElement(import_core.DragOverlay, { dropAnimation: null, zIndex: 2e3 }, activeId && /* @__PURE__ */ import_react.default.createElement(
135
- "span",
340
+ typeof document !== "undefined" ? (0, import_react_dom.createPortal)(
341
+ /* @__PURE__ */ import_react.default.createElement(
342
+ import_core.DragOverlay,
136
343
  {
137
- style: {
138
- display: "inline-flex",
139
- alignItems: "center",
140
- whiteSpace: "nowrap",
141
- background: "#fff",
142
- border: "1px solid #1890ff",
143
- borderRadius: 4,
144
- padding: "4px 12px",
145
- color: "#1890ff",
146
- // fontSize: 18,
147
- boxShadow: "0 2px 8px rgba(0,0,0,0.15)"
148
- }
344
+ dropAnimation: null,
345
+ modifiers: [overlayAnchorModifier],
346
+ zIndex: 2e3,
347
+ style: { pointerEvents: "none" }
149
348
  },
150
- flowEngine.translate("Dragging")
151
- )),
349
+ activeId && /* @__PURE__ */ import_react.default.createElement(
350
+ "span",
351
+ {
352
+ "data-testid": "flow-drag-preview",
353
+ style: {
354
+ display: "inline-flex",
355
+ alignItems: "center",
356
+ whiteSpace: "nowrap",
357
+ background: "#fff",
358
+ border: "1px solid #1890ff",
359
+ borderRadius: 4,
360
+ padding: "4px 12px",
361
+ color: "#1890ff",
362
+ pointerEvents: "none",
363
+ // fontSize: 18,
364
+ boxShadow: "0 2px 8px rgba(0,0,0,0.15)"
365
+ }
366
+ },
367
+ flowEngine.translate("Dragging")
368
+ )
369
+ ),
152
370
  document.body
153
- )
371
+ ) : null
154
372
  );
155
373
  }, "DndProvider");
156
374
  // Annotate the CommonJS export names for ESM import in node:
@@ -159,6 +377,8 @@ const DndProvider = /* @__PURE__ */ __name(({
159
377
  DragHandler,
160
378
  Droppable,
161
379
  EMPTY_COLUMN_UID,
380
+ TOOLBAR_DRAG_ACTIVITY_EVENT,
381
+ resolveOverlayAnchorTransform,
162
382
  ...require("./findModelUidPosition"),
163
383
  ...require("./gridDragPlanner")
164
384
  });
@@ -49,6 +49,22 @@ var import_utils = require("../../../../utils");
49
49
  var import_hooks = require("../../../../hooks");
50
50
  var import_SwitchWithTitle = require("../component/SwitchWithTitle");
51
51
  var import_SelectWithTitle = require("../component/SelectWithTitle");
52
+ const findExtraMenuItemByKey = /* @__PURE__ */ __name((items, targetKey) => {
53
+ var _a;
54
+ for (const item of items) {
55
+ const itemKey = String((item == null ? void 0 : item.key) ?? "");
56
+ if (itemKey === targetKey) {
57
+ return item;
58
+ }
59
+ if ((_a = item.children) == null ? void 0 : _a.length) {
60
+ const matched = findExtraMenuItemByKey(item.children, targetKey);
61
+ if (matched) {
62
+ return matched;
63
+ }
64
+ }
65
+ }
66
+ return void 0;
67
+ }, "findExtraMenuItemByKey");
52
68
  const walkSubModels = /* @__PURE__ */ __name((rootModel, options, cb) => {
53
69
  const maxDepth = options.maxDepth;
54
70
  const arrayLimit = typeof options.arrayLimit === "number" ? options.arrayLimit : Number.POSITIVE_INFINITY;
@@ -389,7 +405,10 @@ const DefaultSettingsIcon = /* @__PURE__ */ __name(({
389
405
  handleCopyPopupUid(cleanKey);
390
406
  return;
391
407
  }
392
- const extra = extraMenuItems.find((it) => (it == null ? void 0 : it.key) === originalKey || (it == null ? void 0 : it.key) === cleanKey);
408
+ const extra = findExtraMenuItemByKey(extraMenuItems, originalKey) || findExtraMenuItemByKey(extraMenuItems, cleanKey);
409
+ if (extra == null ? void 0 : extra.disabled) {
410
+ return;
411
+ }
393
412
  if (extra == null ? void 0 : extra.onClick) {
394
413
  closeDropdown();
395
414
  extra.onClick();
@@ -43,6 +43,10 @@ interface BaseFloatContextMenuProps {
43
43
  * Extra toolbar items to add to this context menu instance
44
44
  */
45
45
  extraToolbarItems?: ToolbarItemConfig[];
46
+ /**
47
+ * @default true
48
+ */
49
+ showDynamicFlowsEditor?: boolean;
46
50
  /**
47
51
  * @default 'inside'
48
52
  */
@@ -51,7 +51,8 @@ var import__ = require("../../../..");
51
51
  var import_reactive = require("../../../../reactive");
52
52
  var import_useFloatToolbarPortal = require("./useFloatToolbarPortal");
53
53
  var import_useFloatToolbarVisibility = require("./useFloatToolbarVisibility");
54
- const TOOLBAR_Z_INDEX = 999;
54
+ const TOOLBAR_ITEM_WIDTH = 19;
55
+ const DEFAULT_POPUP_BASE_Z_INDEX = 1e3;
55
56
  const getFloatMenuInstanceId = /* @__PURE__ */ __name((model) => {
56
57
  if (!model) {
57
58
  return "";
@@ -74,9 +75,10 @@ const toolbarPositionClassNames = {
74
75
  const toolbarContainerStyles = /* @__PURE__ */ __name(({
75
76
  showBackground,
76
77
  showBorder,
77
- ctx
78
+ ctx,
79
+ toolbarZIndex
78
80
  }) => import_css.css`
79
- z-index: ${TOOLBAR_Z_INDEX};
81
+ z-index: ${toolbarZIndex};
80
82
  opacity: 0;
81
83
  pointer-events: none;
82
84
  overflow: visible;
@@ -254,12 +256,15 @@ const detectButtonInDOM = /* @__PURE__ */ __name((container) => {
254
256
  }
255
257
  return false;
256
258
  }, "detectButtonInDOM");
257
- const renderToolbarItems = /* @__PURE__ */ __name((model, modelInstanceId, showDeleteButton, showCopyUidButton, flowEngine, settingsMenuLevel, extraToolbarItems, onSettingsMenuOpenChange, getPopupContainer) => {
259
+ const renderToolbarItems = /* @__PURE__ */ __name((model, modelInstanceId, showDeleteButton, showCopyUidButton, flowEngine, settingsMenuLevel, extraToolbarItems, showDynamicFlowsEditor = true, onSettingsMenuOpenChange, getPopupContainer) => {
258
260
  var _a, _b;
259
261
  const toolbarItems = ((_b = (_a = flowEngine == null ? void 0 : flowEngine.flowSettings) == null ? void 0 : _a.getToolbarItems) == null ? void 0 : _b.call(_a)) || [];
260
262
  const allToolbarItems = [...toolbarItems, ...extraToolbarItems || []];
261
263
  allToolbarItems.sort((a, b) => (a.sort || 0) - (b.sort || 0)).reverse();
262
264
  return allToolbarItems.filter((itemConfig) => {
265
+ if (itemConfig.key === "dynamic-flows-editor" && showDynamicFlowsEditor === false) {
266
+ return false;
267
+ }
263
268
  return itemConfig.visible ? itemConfig.visible(model) : true;
264
269
  }).map((itemConfig) => {
265
270
  const ItemComponent = itemConfig.component;
@@ -285,21 +290,23 @@ const buildToolbarContainerClassName = /* @__PURE__ */ __name(({
285
290
  showBackground,
286
291
  showBorder,
287
292
  ctx,
293
+ toolbarZIndex,
288
294
  portalRenderSnapshot,
289
295
  isToolbarVisible,
290
296
  className
291
297
  }) => [
292
- toolbarContainerStyles({ showBackground, showBorder, ctx }),
298
+ toolbarContainerStyles({ showBackground, showBorder, ctx, toolbarZIndex }),
293
299
  "nb-toolbar-portal",
294
300
  (portalRenderSnapshot == null ? void 0 : portalRenderSnapshot.positioningMode) === "absolute" ? "nb-toolbar-portal-absolute" : "nb-toolbar-portal-fixed",
295
301
  isToolbarVisible ? "nb-toolbar-visible" : "",
296
302
  (className == null ? void 0 : className.includes("nb-in-template")) ? "nb-in-template" : ""
297
303
  ].filter(Boolean).join(" "), "buildToolbarContainerClassName");
298
- const buildToolbarContainerStyle = /* @__PURE__ */ __name((portalRect, toolbarStyle) => ({
304
+ const buildToolbarContainerStyle = /* @__PURE__ */ __name((portalRect, toolbarStyle, toolbarItemCount = 0) => ({
299
305
  top: `${portalRect.top}px`,
300
306
  left: `${portalRect.left}px`,
301
307
  width: `${portalRect.width}px`,
302
308
  height: `${portalRect.height}px`,
309
+ minWidth: toolbarItemCount ? `${TOOLBAR_ITEM_WIDTH * toolbarItemCount}px` : void 0,
303
310
  ...(0, import_useFloatToolbarPortal.omitToolbarPortalInsetStyle)(toolbarStyle)
304
311
  }), "buildToolbarContainerStyle");
305
312
  const isModelByIdProps = /* @__PURE__ */ __name((props) => {
@@ -392,9 +399,11 @@ const FlowsFloatContextMenuWithModel = (0, import_reactive.observer)(
392
399
  showDragHandle = false,
393
400
  settingsMenuLevel,
394
401
  extraToolbarItems,
402
+ showDynamicFlowsEditor = true,
395
403
  toolbarStyle,
396
404
  toolbarPosition = "inside"
397
405
  }) => {
406
+ var _a;
398
407
  const [hasButton, setHasButton] = (0, import_react.useState)(false);
399
408
  const containerRef = (0, import_react.useRef)(null);
400
409
  const toolbarContainerRef = (0, import_react.useRef)(null);
@@ -447,6 +456,7 @@ const FlowsFloatContextMenuWithModel = (0, import_reactive.observer)(
447
456
  flowEngine,
448
457
  settingsMenuLevel,
449
458
  extraToolbarItems,
459
+ showDynamicFlowsEditor,
450
460
  handleSettingsMenuOpenChange,
451
461
  getPopupContainer
452
462
  ) : [],
@@ -458,7 +468,8 @@ const FlowsFloatContextMenuWithModel = (0, import_reactive.observer)(
458
468
  model,
459
469
  settingsMenuLevel,
460
470
  showCopyUidButton,
461
- showDeleteButton
471
+ showDeleteButton,
472
+ showDynamicFlowsEditor
462
473
  ]
463
474
  );
464
475
  (0, import_react.useEffect)(() => {
@@ -488,15 +499,17 @@ const FlowsFloatContextMenuWithModel = (0, import_reactive.observer)(
488
499
  if (!enabled || !children) {
489
500
  return /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, children);
490
501
  }
502
+ const toolbarZIndex = (((_a = model.context.themeToken) == null ? void 0 : _a.zIndexPopupBase) || DEFAULT_POPUP_BASE_Z_INDEX) + 1;
491
503
  const toolbarContainerClassName = buildToolbarContainerClassName({
492
504
  showBackground,
493
505
  showBorder,
494
506
  ctx: model.context,
507
+ toolbarZIndex,
495
508
  portalRenderSnapshot,
496
509
  isToolbarVisible,
497
510
  className
498
511
  });
499
- const toolbarContainerStyle = buildToolbarContainerStyle(portalRect, toolbarStyle);
512
+ const toolbarContainerStyle = buildToolbarContainerStyle(portalRect, toolbarStyle, toolbarItems.length);
500
513
  const toolbarNode = shouldRenderToolbar ? /* @__PURE__ */ import_react.default.createElement(
501
514
  "div",
502
515
  {
@@ -33,6 +33,7 @@ __export(useFloatToolbarPortal_exports, {
33
33
  module.exports = __toCommonJS(useFloatToolbarPortal_exports);
34
34
  var import_react = require("react");
35
35
  const APP_CONTAINER_SELECTOR = "#nocobase-app-container";
36
+ const MENU_SUBMENU_POPUP_SELECTOR = ".ant-menu-submenu-popup";
36
37
  const DRAWER_CONTENT_WRAPPER_SELECTOR = ".ant-drawer-content-wrapper";
37
38
  const DRAWER_CONTENT_SELECTOR = ".ant-drawer-content";
38
39
  const DRAWER_ROOT_SELECTOR = ".ant-drawer-root";
@@ -52,6 +53,7 @@ const createAbsolutePortalHostConfig = /* @__PURE__ */ __name((element) => ({
52
53
  positioningMode: "absolute"
53
54
  }), "createAbsolutePortalHostConfig");
54
55
  const popupPortalHostResolvers = [
56
+ (hostEl) => getClosestElement(hostEl, MENU_SUBMENU_POPUP_SELECTOR),
55
57
  (hostEl) => getClosestElement(hostEl, DRAWER_CONTENT_WRAPPER_SELECTOR),
56
58
  (hostEl) => getClosestElement(hostEl, MODAL_WRAP_SELECTOR),
57
59
  (hostEl) => getClosestElement(hostEl, MODAL_SELECTOR),