@nocobase/flow-engine 2.1.0-beta.9 → 2.1.1
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/lib/FlowContextProvider.d.ts +5 -1
- package/lib/FlowContextProvider.js +9 -2
- package/lib/components/FieldModelRenderer.js +2 -2
- package/lib/components/FlowModelRenderer.d.ts +3 -1
- package/lib/components/FlowModelRenderer.js +12 -6
- package/lib/components/FormItem.d.ts +6 -0
- package/lib/components/FormItem.js +11 -3
- package/lib/components/MobilePopup.js +6 -5
- package/lib/components/dnd/gridDragPlanner.d.ts +59 -2
- package/lib/components/dnd/gridDragPlanner.js +607 -19
- package/lib/components/dnd/index.d.ts +31 -2
- package/lib/components/dnd/index.js +244 -23
- package/lib/components/settings/wrappers/component/SelectWithTitle.d.ts +2 -1
- package/lib/components/settings/wrappers/component/SelectWithTitle.js +14 -12
- package/lib/components/settings/wrappers/contextual/DefaultSettingsIcon.d.ts +3 -0
- package/lib/components/settings/wrappers/contextual/DefaultSettingsIcon.js +152 -42
- package/lib/components/settings/wrappers/contextual/FlowsFloatContextMenu.d.ts +23 -43
- package/lib/components/settings/wrappers/contextual/FlowsFloatContextMenu.js +352 -295
- package/lib/components/settings/wrappers/contextual/useFloatToolbarPortal.d.ts +36 -0
- package/lib/components/settings/wrappers/contextual/useFloatToolbarPortal.js +274 -0
- package/lib/components/settings/wrappers/contextual/useFloatToolbarVisibility.d.ts +30 -0
- package/lib/components/settings/wrappers/contextual/useFloatToolbarVisibility.js +315 -0
- package/lib/components/subModel/AddSubModelButton.js +12 -1
- package/lib/components/subModel/LazyDropdown.js +301 -52
- package/lib/components/subModel/index.d.ts +1 -0
- package/lib/components/subModel/index.js +19 -0
- package/lib/components/subModel/utils.d.ts +2 -1
- package/lib/components/subModel/utils.js +15 -5
- package/lib/components/variables/VariableHybridInput.d.ts +27 -0
- package/lib/components/variables/VariableHybridInput.js +499 -0
- package/lib/components/variables/index.d.ts +2 -0
- package/lib/components/variables/index.js +3 -0
- package/lib/data-source/index.d.ts +84 -0
- package/lib/data-source/index.js +269 -7
- package/lib/executor/FlowExecutor.js +6 -3
- package/lib/flow-registry/DetachedFlowRegistry.d.ts +21 -0
- package/lib/flow-registry/DetachedFlowRegistry.js +80 -0
- package/lib/flow-registry/index.d.ts +1 -0
- package/lib/flow-registry/index.js +3 -1
- package/lib/flowContext.d.ts +9 -1
- package/lib/flowContext.js +77 -6
- package/lib/flowEngine.d.ts +136 -4
- package/lib/flowEngine.js +429 -51
- package/lib/flowI18n.js +2 -1
- package/lib/flowSettings.d.ts +14 -6
- package/lib/flowSettings.js +34 -6
- package/lib/index.d.ts +2 -0
- package/lib/index.js +7 -0
- package/lib/lazy-helper.d.ts +14 -0
- package/lib/lazy-helper.js +71 -0
- package/lib/locale/en-US.json +1 -0
- package/lib/locale/index.d.ts +2 -0
- package/lib/locale/zh-CN.json +1 -0
- package/lib/models/DisplayItemModel.d.ts +1 -1
- package/lib/models/EditableItemModel.d.ts +1 -1
- package/lib/models/FilterableItemModel.d.ts +1 -1
- package/lib/models/flowModel.d.ts +13 -10
- package/lib/models/flowModel.js +126 -34
- package/lib/provider.js +38 -23
- package/lib/reactive/observer.js +46 -16
- package/lib/runjs-context/contexts/FormJSFieldItemRunJSContext.js +4 -3
- package/lib/runjs-context/contexts/JSBlockRunJSContext.js +4 -15
- package/lib/runjs-context/contexts/JSColumnRunJSContext.js +5 -2
- package/lib/runjs-context/contexts/JSEditableFieldRunJSContext.js +5 -8
- package/lib/runjs-context/contexts/JSFieldRunJSContext.js +4 -3
- package/lib/runjs-context/contexts/JSItemRunJSContext.js +4 -3
- package/lib/runjs-context/contexts/base.js +464 -29
- package/lib/runjs-context/contexts/elementDoc.d.ts +11 -0
- package/lib/runjs-context/contexts/elementDoc.js +152 -0
- package/lib/runjs-context/setup.js +1 -0
- package/lib/runjs-context/snippets/index.js +13 -2
- package/lib/runjs-context/snippets/scene/detail/set-field-style.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/detail/set-field-style.snippet.js +50 -0
- package/lib/runjs-context/snippets/scene/table/set-cell-style.snippet.d.ts +11 -0
- package/lib/runjs-context/snippets/scene/table/set-cell-style.snippet.js +54 -0
- package/lib/types.d.ts +50 -2
- package/lib/types.js +1 -0
- package/lib/utils/createCollectionContextMeta.js +6 -2
- package/lib/utils/index.d.ts +3 -2
- package/lib/utils/index.js +7 -0
- package/lib/utils/loadedPageCache.d.ts +24 -0
- package/lib/utils/loadedPageCache.js +139 -0
- package/lib/utils/parsePathnameToViewParams.d.ts +5 -1
- package/lib/utils/parsePathnameToViewParams.js +28 -4
- package/lib/utils/randomId.d.ts +39 -0
- package/lib/utils/randomId.js +45 -0
- package/lib/utils/runjsTemplateCompat.js +1 -1
- package/lib/utils/runjsValue.js +41 -11
- package/lib/utils/schema-utils.d.ts +7 -1
- package/lib/utils/schema-utils.js +19 -0
- package/lib/views/FlowView.d.ts +7 -1
- package/lib/views/FlowView.js +11 -1
- package/lib/views/PageComponent.js +8 -6
- package/lib/views/ViewNavigation.d.ts +12 -2
- package/lib/views/ViewNavigation.js +28 -9
- package/lib/views/createViewMeta.js +114 -50
- package/lib/views/inheritLayoutContext.d.ts +10 -0
- package/lib/views/inheritLayoutContext.js +50 -0
- package/lib/views/runViewBeforeClose.d.ts +10 -0
- package/lib/views/runViewBeforeClose.js +45 -0
- package/lib/views/useDialog.d.ts +2 -1
- package/lib/views/useDialog.js +12 -3
- package/lib/views/useDrawer.d.ts +2 -1
- package/lib/views/useDrawer.js +12 -3
- package/lib/views/usePage.d.ts +5 -11
- package/lib/views/usePage.js +304 -144
- package/package.json +5 -4
- package/src/FlowContextProvider.tsx +9 -1
- package/src/__tests__/createViewMeta.popup.test.ts +115 -1
- package/src/__tests__/flow-engine.test.ts +166 -0
- package/src/__tests__/flowContext.test.ts +105 -1
- package/src/__tests__/flowEngine.modelLoaders.test.ts +245 -0
- package/src/__tests__/flowEngine.moveModel.test.ts +81 -1
- package/src/__tests__/flowEngine.removeModel.test.ts +47 -3
- package/src/__tests__/flowSettings.test.ts +94 -15
- package/src/__tests__/objectVariable.test.ts +24 -0
- package/src/__tests__/provider.test.tsx +24 -2
- package/src/__tests__/renderHiddenInConfig.test.tsx +6 -6
- package/src/__tests__/runjsContext.test.ts +21 -0
- package/src/__tests__/runjsContextImplementations.test.ts +9 -2
- package/src/__tests__/runjsContextRuntime.test.ts +2 -0
- package/src/__tests__/runjsLocales.test.ts +6 -5
- package/src/__tests__/runjsSnippets.test.ts +21 -0
- package/src/__tests__/viewScopedFlowEngine.test.ts +136 -3
- package/src/components/FieldModelRenderer.tsx +2 -1
- package/src/components/FlowModelRenderer.tsx +18 -6
- package/src/components/FormItem.tsx +7 -1
- package/src/components/MobilePopup.tsx +4 -2
- package/src/components/__tests__/FlowModelRenderer.test.tsx +65 -2
- package/src/components/__tests__/FormItem.test.tsx +25 -0
- package/src/components/__tests__/dnd.test.ts +44 -0
- package/src/components/__tests__/flow-model-render-error-fallback.test.tsx +20 -10
- package/src/components/__tests__/gridDragPlanner.test.ts +472 -5
- package/src/components/dnd/__tests__/DndProvider.test.tsx +98 -0
- package/src/components/dnd/gridDragPlanner.ts +750 -17
- package/src/components/dnd/index.tsx +305 -28
- package/src/components/settings/wrappers/component/SelectWithTitle.tsx +21 -9
- package/src/components/settings/wrappers/contextual/DefaultSettingsIcon.tsx +178 -48
- package/src/components/settings/wrappers/contextual/FlowsFloatContextMenu.tsx +487 -440
- package/src/components/settings/wrappers/contextual/__tests__/DefaultSettingsIcon.test.tsx +344 -8
- package/src/components/settings/wrappers/contextual/__tests__/FlowsFloatContextMenu.test.tsx +778 -0
- package/src/components/settings/wrappers/contextual/useFloatToolbarPortal.ts +360 -0
- package/src/components/settings/wrappers/contextual/useFloatToolbarVisibility.ts +361 -0
- package/src/components/subModel/AddSubModelButton.tsx +16 -2
- package/src/components/subModel/LazyDropdown.tsx +341 -56
- package/src/components/subModel/__tests__/AddSubModelButton.test.tsx +524 -38
- package/src/components/subModel/__tests__/utils.test.ts +24 -0
- package/src/components/subModel/index.ts +1 -0
- package/src/components/subModel/utils.ts +13 -2
- package/src/components/variables/VariableHybridInput.tsx +531 -0
- package/src/components/variables/index.ts +2 -0
- package/src/data-source/__tests__/collection.test.ts +41 -2
- package/src/data-source/__tests__/index.test.ts +69 -2
- package/src/data-source/index.ts +332 -8
- package/src/executor/FlowExecutor.ts +6 -3
- package/src/executor/__tests__/flowExecutor.test.ts +57 -0
- package/src/flow-registry/DetachedFlowRegistry.ts +46 -0
- package/src/flow-registry/__tests__/detachedFlowRegistry.test.ts +47 -0
- package/src/flow-registry/index.ts +1 -0
- package/src/flowContext.ts +85 -6
- package/src/flowEngine.ts +484 -45
- package/src/flowI18n.ts +2 -1
- package/src/flowSettings.ts +40 -6
- package/src/index.ts +2 -0
- package/src/lazy-helper.tsx +57 -0
- package/src/locale/en-US.json +1 -0
- package/src/locale/zh-CN.json +1 -0
- package/src/models/DisplayItemModel.tsx +1 -1
- package/src/models/EditableItemModel.tsx +1 -1
- package/src/models/FilterableItemModel.tsx +1 -1
- package/src/models/__tests__/flowEngine.resolveUse.test.ts +0 -15
- package/src/models/__tests__/flowModel.test.ts +65 -37
- package/src/models/flowModel.tsx +184 -65
- package/src/provider.tsx +41 -25
- package/src/reactive/__tests__/observer.test.tsx +82 -0
- package/src/reactive/observer.tsx +87 -25
- package/src/runjs-context/contexts/FormJSFieldItemRunJSContext.ts +4 -3
- package/src/runjs-context/contexts/JSBlockRunJSContext.ts +4 -15
- package/src/runjs-context/contexts/JSColumnRunJSContext.ts +4 -2
- package/src/runjs-context/contexts/JSEditableFieldRunJSContext.ts +5 -9
- package/src/runjs-context/contexts/JSFieldRunJSContext.ts +4 -3
- package/src/runjs-context/contexts/JSItemRunJSContext.ts +4 -3
- package/src/runjs-context/contexts/base.ts +467 -31
- package/src/runjs-context/contexts/elementDoc.ts +130 -0
- package/src/runjs-context/setup.ts +1 -0
- package/src/runjs-context/snippets/index.ts +12 -1
- package/src/runjs-context/snippets/scene/detail/set-field-style.snippet.ts +30 -0
- package/src/runjs-context/snippets/scene/table/set-cell-style.snippet.ts +34 -0
- package/src/types.ts +62 -0
- package/src/utils/__tests__/createCollectionContextMeta.test.ts +48 -0
- package/src/utils/__tests__/parsePathnameToViewParams.test.ts +21 -0
- package/src/utils/__tests__/runjsValue.test.ts +11 -0
- package/src/utils/__tests__/utils.test.ts +62 -0
- package/src/utils/createCollectionContextMeta.ts +6 -2
- package/src/utils/index.ts +5 -1
- package/src/utils/loadedPageCache.ts +147 -0
- package/src/utils/parsePathnameToViewParams.ts +45 -5
- package/src/utils/randomId.ts +48 -0
- package/src/utils/runjsTemplateCompat.ts +1 -1
- package/src/utils/runjsValue.ts +50 -11
- package/src/utils/schema-utils.ts +30 -1
- package/src/views/FlowView.tsx +22 -2
- package/src/views/PageComponent.tsx +7 -4
- package/src/views/ViewNavigation.ts +46 -9
- package/src/views/__tests__/FlowView.usePage.test.tsx +243 -3
- package/src/views/__tests__/ViewNavigation.test.ts +52 -0
- package/src/views/__tests__/inheritLayoutContext.test.ts +53 -0
- package/src/views/__tests__/runViewBeforeClose.test.ts +30 -0
- package/src/views/__tests__/useDialog.closeDestroy.test.tsx +12 -12
- package/src/views/createViewMeta.ts +106 -34
- package/src/views/inheritLayoutContext.ts +26 -0
- package/src/views/runViewBeforeClose.ts +19 -0
- package/src/views/useDialog.tsx +13 -3
- package/src/views/useDrawer.tsx +13 -3
- package/src/views/usePage.tsx +367 -180
|
@@ -41,6 +41,7 @@ __export(DefaultSettingsIcon_exports, {
|
|
|
41
41
|
});
|
|
42
42
|
module.exports = __toCommonJS(DefaultSettingsIcon_exports);
|
|
43
43
|
var import_icons = require("@ant-design/icons");
|
|
44
|
+
var import_css = require("@emotion/css");
|
|
44
45
|
var import_antd = require("antd");
|
|
45
46
|
var import_react = __toESM(require("react"));
|
|
46
47
|
var import_models = require("../../../../models");
|
|
@@ -48,6 +49,22 @@ var import_utils = require("../../../../utils");
|
|
|
48
49
|
var import_hooks = require("../../../../hooks");
|
|
49
50
|
var import_SwitchWithTitle = require("../component/SwitchWithTitle");
|
|
50
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");
|
|
51
68
|
const walkSubModels = /* @__PURE__ */ __name((rootModel, options, cb) => {
|
|
52
69
|
const maxDepth = options.maxDepth;
|
|
53
70
|
const arrayLimit = typeof options.arrayLimit === "number" ? options.arrayLimit : Number.POSITIVE_INFINITY;
|
|
@@ -149,13 +166,39 @@ const MenuLabelItem = /* @__PURE__ */ __name(({ title, uiMode, itemProps }) => {
|
|
|
149
166
|
}
|
|
150
167
|
return /* @__PURE__ */ import_react.default.createElement("span", { style: { display: "inline-flex", alignItems: "center", gap: 6 } }, content, /* @__PURE__ */ import_react.default.createElement(import_antd.Tooltip, { title: disabledReason, placement: "right", destroyTooltipOnHide: true }, /* @__PURE__ */ import_react.default.createElement(import_icons.QuestionCircleOutlined, { style: { color: disabledIconColor } })));
|
|
151
168
|
}, "MenuLabelItem");
|
|
169
|
+
const TOOLBAR_ICONS_SELECTOR = ".nb-toolbar-container-icons";
|
|
170
|
+
const TOOLBAR_CONTAINER_SELECTOR = ".nb-toolbar-container";
|
|
171
|
+
const TOOLBAR_DROPDOWN_OVERLAY_CLASS = import_css.css`
|
|
172
|
+
width: max-content;
|
|
173
|
+
min-width: max-content;
|
|
174
|
+
|
|
175
|
+
.ant-dropdown-menu {
|
|
176
|
+
width: max-content;
|
|
177
|
+
min-width: max-content;
|
|
178
|
+
}
|
|
179
|
+
`;
|
|
180
|
+
const getToolbarPopupContainer = /* @__PURE__ */ __name((triggerNode) => {
|
|
181
|
+
if (!triggerNode) {
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
return triggerNode.closest(TOOLBAR_ICONS_SELECTOR) || triggerNode.closest(TOOLBAR_CONTAINER_SELECTOR);
|
|
185
|
+
}, "getToolbarPopupContainer");
|
|
186
|
+
const removeExtraMenuItemClickHandlers = /* @__PURE__ */ __name((item) => {
|
|
187
|
+
const { onClick: _onClick, children, ...rest } = item;
|
|
188
|
+
return {
|
|
189
|
+
...rest,
|
|
190
|
+
children: (children == null ? void 0 : children.length) ? children.map(removeExtraMenuItemClickHandlers) : void 0
|
|
191
|
+
};
|
|
192
|
+
}, "removeExtraMenuItemClickHandlers");
|
|
152
193
|
const DefaultSettingsIcon = /* @__PURE__ */ __name(({
|
|
153
194
|
model,
|
|
154
195
|
showDeleteButton = true,
|
|
155
196
|
showCopyUidButton = true,
|
|
156
197
|
menuLevels = 1,
|
|
157
198
|
// 默认一级菜单
|
|
158
|
-
flattenSubMenus = true
|
|
199
|
+
flattenSubMenus = true,
|
|
200
|
+
onDropdownVisibleChange,
|
|
201
|
+
getPopupContainer
|
|
159
202
|
}) => {
|
|
160
203
|
const { message } = import_antd.App.useApp();
|
|
161
204
|
const t = (0, import_react.useMemo)(() => (0, import_utils.getT)(model), [model]);
|
|
@@ -164,41 +207,70 @@ const DefaultSettingsIcon = /* @__PURE__ */ __name(({
|
|
|
164
207
|
const [visible, setVisible] = (0, import_react.useState)(false);
|
|
165
208
|
const [refreshTick, setRefreshTick] = (0, import_react.useState)(0);
|
|
166
209
|
const [extraMenuItems, setExtraMenuItems] = (0, import_react.useState)([]);
|
|
210
|
+
const [extraMenuItemsLoaded, setExtraMenuItemsLoaded] = (0, import_react.useState)(false);
|
|
167
211
|
const [configurableFlowsAndSteps, setConfigurableFlowsAndSteps] = (0, import_react.useState)([]);
|
|
168
212
|
const [isLoading, setIsLoading] = (0, import_react.useState)(true);
|
|
213
|
+
const commonExtras = (0, import_react.useMemo)(
|
|
214
|
+
() => extraMenuItems.filter((it) => it.group === "common-actions").sort((a, b) => (a.sort ?? 0) - (b.sort ?? 0)),
|
|
215
|
+
[extraMenuItems]
|
|
216
|
+
);
|
|
217
|
+
const hasCommonActions = showCopyUidButton || showDeleteButton || commonExtras.length > 0;
|
|
218
|
+
const shouldDeferConfigLoading = flattenSubMenus && menuLevels > 1 && hasCommonActions;
|
|
219
|
+
const shouldWaitForCommonActionProbe = flattenSubMenus && menuLevels > 1 && !showCopyUidButton && !showDeleteButton && !extraMenuItemsLoaded;
|
|
220
|
+
const canRenderIcon = hasCommonActions || !isLoading && configurableFlowsAndSteps.length > 0;
|
|
169
221
|
const closeDropdown = (0, import_react.useCallback)(() => {
|
|
170
222
|
setVisible(false);
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
223
|
+
onDropdownVisibleChange == null ? void 0 : onDropdownVisibleChange(false);
|
|
224
|
+
}, [onDropdownVisibleChange]);
|
|
225
|
+
const resolvePopupContainer = (0, import_react.useCallback)(
|
|
226
|
+
(triggerNode) => {
|
|
227
|
+
return getToolbarPopupContainer(triggerNode) || (getPopupContainer == null ? void 0 : getPopupContainer(triggerNode)) || (triggerNode == null ? void 0 : triggerNode.parentElement) || document.body;
|
|
228
|
+
},
|
|
229
|
+
[getPopupContainer]
|
|
230
|
+
);
|
|
231
|
+
const handleOpenChange = (0, import_react.useCallback)(
|
|
232
|
+
(nextOpen, info) => {
|
|
233
|
+
if (info.source === "trigger" || nextOpen) {
|
|
234
|
+
(0, import_react.startTransition)(() => {
|
|
235
|
+
setVisible(nextOpen);
|
|
236
|
+
});
|
|
237
|
+
onDropdownVisibleChange == null ? void 0 : onDropdownVisibleChange(nextOpen);
|
|
238
|
+
}
|
|
239
|
+
},
|
|
240
|
+
[onDropdownVisibleChange]
|
|
241
|
+
);
|
|
242
|
+
(0, import_react.useEffect)(() => {
|
|
243
|
+
return () => {
|
|
244
|
+
onDropdownVisibleChange == null ? void 0 : onDropdownVisibleChange(false);
|
|
245
|
+
};
|
|
246
|
+
}, [onDropdownVisibleChange]);
|
|
179
247
|
const dropdownMaxHeight = (0, import_hooks.useNiceDropdownMaxHeight)([visible]);
|
|
180
248
|
(0, import_react.useEffect)(() => {
|
|
181
249
|
let mounted = true;
|
|
182
250
|
const loadExtras = /* @__PURE__ */ __name(async () => {
|
|
183
251
|
var _a;
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
modelsToProcess
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
252
|
+
setExtraMenuItemsLoaded(false);
|
|
253
|
+
try {
|
|
254
|
+
const allExtras = [];
|
|
255
|
+
const modelsToProcess = [];
|
|
256
|
+
walkSubModels(model, { maxDepth: menuLevels, arrayLimit: 50, mode: "stack" }, (targetModel, { modelKey }) => {
|
|
257
|
+
modelsToProcess.push({ model: targetModel, modelKey });
|
|
258
|
+
});
|
|
259
|
+
for (const { model: targetModel, modelKey } of modelsToProcess) {
|
|
260
|
+
const Cls = targetModel.constructor;
|
|
261
|
+
const extras = await ((_a = Cls.getExtraMenuItems) == null ? void 0 : _a.call(Cls, targetModel, t));
|
|
262
|
+
if (extras == null ? void 0 : extras.length) {
|
|
263
|
+
allExtras.push(
|
|
264
|
+
...extras.map((item) => ({
|
|
265
|
+
...item,
|
|
266
|
+
key: modelKey ? `${modelKey}:${item.key}` : item.key
|
|
267
|
+
}))
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
if (!mounted) {
|
|
272
|
+
return;
|
|
199
273
|
}
|
|
200
|
-
}
|
|
201
|
-
if (mounted) {
|
|
202
274
|
const seen = /* @__PURE__ */ new Set();
|
|
203
275
|
const dedupedExtras = allExtras.filter((item) => {
|
|
204
276
|
if (seen.has(`${item.key}`)) {
|
|
@@ -208,15 +280,22 @@ const DefaultSettingsIcon = /* @__PURE__ */ __name(({
|
|
|
208
280
|
return true;
|
|
209
281
|
});
|
|
210
282
|
setExtraMenuItems(dedupedExtras);
|
|
283
|
+
} catch (error) {
|
|
284
|
+
console.error("Failed to load extra menu items:", error);
|
|
285
|
+
if (mounted) {
|
|
286
|
+
setExtraMenuItems([]);
|
|
287
|
+
}
|
|
288
|
+
} finally {
|
|
289
|
+
if (mounted) {
|
|
290
|
+
setExtraMenuItemsLoaded(true);
|
|
291
|
+
}
|
|
211
292
|
}
|
|
212
293
|
}, "loadExtras");
|
|
213
|
-
|
|
214
|
-
loadExtras();
|
|
215
|
-
}
|
|
294
|
+
loadExtras();
|
|
216
295
|
return () => {
|
|
217
296
|
mounted = false;
|
|
218
297
|
};
|
|
219
|
-
}, [model, menuLevels, t, refreshTick
|
|
298
|
+
}, [model, menuLevels, t, refreshTick]);
|
|
220
299
|
const copyUidToClipboard = (0, import_react.useCallback)(
|
|
221
300
|
async (uid) => {
|
|
222
301
|
var _a;
|
|
@@ -353,7 +432,10 @@ const DefaultSettingsIcon = /* @__PURE__ */ __name(({
|
|
|
353
432
|
handleCopyPopupUid(cleanKey);
|
|
354
433
|
return;
|
|
355
434
|
}
|
|
356
|
-
const extra = extraMenuItems
|
|
435
|
+
const extra = findExtraMenuItemByKey(extraMenuItems, originalKey) || findExtraMenuItemByKey(extraMenuItems, cleanKey);
|
|
436
|
+
if (extra == null ? void 0 : extra.disabled) {
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
357
439
|
if (extra == null ? void 0 : extra.onClick) {
|
|
358
440
|
closeDropdown();
|
|
359
441
|
extra.onClick();
|
|
@@ -458,7 +540,7 @@ const DefaultSettingsIcon = /* @__PURE__ */ __name(({
|
|
|
458
540
|
return [];
|
|
459
541
|
}
|
|
460
542
|
},
|
|
461
|
-
[]
|
|
543
|
+
[t]
|
|
462
544
|
);
|
|
463
545
|
const getConfigurableFlowsAndSteps = (0, import_react.useCallback)(async () => {
|
|
464
546
|
const result = [];
|
|
@@ -496,20 +578,47 @@ const DefaultSettingsIcon = /* @__PURE__ */ __name(({
|
|
|
496
578
|
};
|
|
497
579
|
}, [model, menuLevels, refreshTick]);
|
|
498
580
|
(0, import_react.useEffect)(() => {
|
|
581
|
+
let mounted = true;
|
|
499
582
|
const loadConfigurableFlowsAndSteps = /* @__PURE__ */ __name(async () => {
|
|
500
583
|
setIsLoading(true);
|
|
584
|
+
if (shouldDeferConfigLoading) {
|
|
585
|
+
setConfigurableFlowsAndSteps([]);
|
|
586
|
+
}
|
|
501
587
|
try {
|
|
502
588
|
const flows = await getConfigurableFlowsAndSteps();
|
|
503
|
-
|
|
589
|
+
if (mounted) {
|
|
590
|
+
setConfigurableFlowsAndSteps(flows);
|
|
591
|
+
}
|
|
504
592
|
} catch (error) {
|
|
505
593
|
console.error("Failed to load configurable flows and steps:", error);
|
|
506
|
-
|
|
594
|
+
if (mounted) {
|
|
595
|
+
setConfigurableFlowsAndSteps([]);
|
|
596
|
+
}
|
|
507
597
|
} finally {
|
|
508
|
-
|
|
598
|
+
if (mounted) {
|
|
599
|
+
setIsLoading(false);
|
|
600
|
+
}
|
|
509
601
|
}
|
|
510
602
|
}, "loadConfigurableFlowsAndSteps");
|
|
603
|
+
if (shouldWaitForCommonActionProbe) {
|
|
604
|
+
setConfigurableFlowsAndSteps([]);
|
|
605
|
+
setIsLoading(false);
|
|
606
|
+
return () => {
|
|
607
|
+
mounted = false;
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
if (!visible && shouldDeferConfigLoading) {
|
|
611
|
+
setConfigurableFlowsAndSteps([]);
|
|
612
|
+
setIsLoading(false);
|
|
613
|
+
return () => {
|
|
614
|
+
mounted = false;
|
|
615
|
+
};
|
|
616
|
+
}
|
|
511
617
|
loadConfigurableFlowsAndSteps();
|
|
512
|
-
|
|
618
|
+
return () => {
|
|
619
|
+
mounted = false;
|
|
620
|
+
};
|
|
621
|
+
}, [getConfigurableFlowsAndSteps, refreshTick, shouldDeferConfigLoading, shouldWaitForCommonActionProbe, visible]);
|
|
513
622
|
const menuItems = (0, import_react.useMemo)(() => {
|
|
514
623
|
const items = [];
|
|
515
624
|
const keyCounter = /* @__PURE__ */ new Map();
|
|
@@ -634,16 +743,15 @@ const DefaultSettingsIcon = /* @__PURE__ */ __name(({
|
|
|
634
743
|
}
|
|
635
744
|
}
|
|
636
745
|
return items;
|
|
637
|
-
}, [configurableFlowsAndSteps, disabledIconColor, flattenSubMenus, t]);
|
|
746
|
+
}, [configurableFlowsAndSteps, disabledIconColor, flattenSubMenus, message, model, t]);
|
|
638
747
|
const finalMenuItems = (0, import_react.useMemo)(() => {
|
|
639
748
|
const items = [...menuItems];
|
|
640
|
-
const commonExtras = extraMenuItems.filter((it) => it.group === "common-actions").sort((a, b) => (a.sort ?? 0) - (b.sort ?? 0));
|
|
641
749
|
if (showCopyUidButton || showDeleteButton || commonExtras.length > 0) {
|
|
642
750
|
items.push({
|
|
643
751
|
type: "divider"
|
|
644
752
|
});
|
|
645
753
|
if (commonExtras.length > 0) {
|
|
646
|
-
items.push(...commonExtras);
|
|
754
|
+
items.push(...commonExtras.map(removeExtraMenuItemClickHandlers));
|
|
647
755
|
}
|
|
648
756
|
if (showCopyUidButton && model.uid) {
|
|
649
757
|
items.push({
|
|
@@ -659,9 +767,8 @@ const DefaultSettingsIcon = /* @__PURE__ */ __name(({
|
|
|
659
767
|
}
|
|
660
768
|
}
|
|
661
769
|
return items;
|
|
662
|
-
}, [menuItems, showCopyUidButton, showDeleteButton, model.uid, model.destroy, t
|
|
663
|
-
|
|
664
|
-
if (isLoading || configurableFlowsAndSteps.length === 0 && !showDeleteButton && !showCopyUidButton && !hasExtras) {
|
|
770
|
+
}, [menuItems, showCopyUidButton, showDeleteButton, commonExtras, model.uid, model.destroy, t]);
|
|
771
|
+
if (!canRenderIcon) {
|
|
665
772
|
return null;
|
|
666
773
|
}
|
|
667
774
|
if (!model || !model.uid) {
|
|
@@ -671,6 +778,9 @@ const DefaultSettingsIcon = /* @__PURE__ */ __name(({
|
|
|
671
778
|
return /* @__PURE__ */ import_react.default.createElement(
|
|
672
779
|
import_antd.Dropdown,
|
|
673
780
|
{
|
|
781
|
+
getPopupContainer: resolvePopupContainer,
|
|
782
|
+
overlayClassName: TOOLBAR_DROPDOWN_OVERLAY_CLASS,
|
|
783
|
+
overlayStyle: { width: "max-content", minWidth: "max-content" },
|
|
674
784
|
onOpenChange: handleOpenChange,
|
|
675
785
|
open: visible,
|
|
676
786
|
menu: {
|
|
@@ -9,13 +9,14 @@
|
|
|
9
9
|
import React from 'react';
|
|
10
10
|
import { FlowModel } from '../../../../models';
|
|
11
11
|
import { ToolbarItemConfig } from '../../../../types';
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
type ToolbarPosition = 'inside' | 'above' | 'below';
|
|
13
|
+
interface BaseFloatContextMenuProps {
|
|
14
14
|
children?: React.ReactNode;
|
|
15
15
|
enabled?: boolean;
|
|
16
16
|
showDeleteButton?: boolean;
|
|
17
17
|
showCopyUidButton?: boolean;
|
|
18
18
|
containerStyle?: React.CSSProperties;
|
|
19
|
+
/** 自定义工具栏样式,`top/left/right/bottom` 会作为 portal overlay 的 inset 使用。 */
|
|
19
20
|
toolbarStyle?: React.CSSProperties;
|
|
20
21
|
className?: string;
|
|
21
22
|
/**
|
|
@@ -42,68 +43,47 @@ interface ModelProvidedProps {
|
|
|
42
43
|
* Extra toolbar items to add to this context menu instance
|
|
43
44
|
*/
|
|
44
45
|
extraToolbarItems?: ToolbarItemConfig[];
|
|
45
|
-
/**
|
|
46
|
-
* @default 'inside'
|
|
47
|
-
*/
|
|
48
|
-
toolbarPosition?: 'inside' | 'above' | 'below';
|
|
49
|
-
}
|
|
50
|
-
interface ModelByIdProps {
|
|
51
|
-
uid: string;
|
|
52
|
-
modelClassName: string;
|
|
53
|
-
children?: React.ReactNode;
|
|
54
|
-
enabled?: boolean;
|
|
55
|
-
showDeleteButton?: boolean;
|
|
56
|
-
showCopyUidButton?: boolean;
|
|
57
|
-
containerStyle?: React.CSSProperties;
|
|
58
|
-
className?: string;
|
|
59
46
|
/**
|
|
60
47
|
* @default true
|
|
61
48
|
*/
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* @default true
|
|
65
|
-
*/
|
|
66
|
-
showBackground?: boolean;
|
|
67
|
-
/**
|
|
68
|
-
* @default false
|
|
69
|
-
*/
|
|
70
|
-
showTitle?: boolean;
|
|
71
|
-
/**
|
|
72
|
-
* Settings menu levels: 1=current model only (default), 2=include sub-models
|
|
73
|
-
*/
|
|
74
|
-
settingsMenuLevel?: number;
|
|
75
|
-
/**
|
|
76
|
-
* Extra toolbar items to add to this context menu instance
|
|
77
|
-
*/
|
|
78
|
-
extraToolbarItems?: ToolbarItemConfig[];
|
|
49
|
+
showDynamicFlowsEditor?: boolean;
|
|
79
50
|
/**
|
|
80
51
|
* @default 'inside'
|
|
81
52
|
*/
|
|
82
|
-
toolbarPosition?:
|
|
53
|
+
toolbarPosition?: ToolbarPosition;
|
|
54
|
+
}
|
|
55
|
+
interface ModelProvidedProps extends BaseFloatContextMenuProps {
|
|
56
|
+
model: FlowModel<any>;
|
|
57
|
+
}
|
|
58
|
+
interface ModelByIdProps extends BaseFloatContextMenuProps {
|
|
59
|
+
uid: string;
|
|
60
|
+
modelClassName: string;
|
|
83
61
|
}
|
|
84
62
|
type FlowsFloatContextMenuProps = ModelProvidedProps | ModelByIdProps;
|
|
85
63
|
/**
|
|
86
|
-
* FlowsFloatContextMenu组件 -
|
|
64
|
+
* FlowsFloatContextMenu组件 - 悬浮配置工具栏组件
|
|
87
65
|
*
|
|
88
66
|
* 功能特性:
|
|
89
67
|
* - 鼠标悬浮显示右上角配置图标
|
|
90
68
|
* - 点击图标显示配置菜单
|
|
91
69
|
* - 支持删除功能
|
|
92
70
|
* - Wrapper 模式支持
|
|
93
|
-
* -
|
|
94
|
-
* -
|
|
71
|
+
* - 使用 portal overlay 避免被宿主或祖先裁剪
|
|
72
|
+
* - 设置菜单与工具栏共享同一个 popup 容器
|
|
95
73
|
*
|
|
96
74
|
* 支持两种使用方式:
|
|
97
|
-
* 1. 直接提供model:
|
|
98
|
-
* 2. 通过uid和modelClassName获取model:
|
|
75
|
+
* 1. 直接提供 model: `<FlowsFloatContextMenu model={myModel}>{children}</FlowsFloatContextMenu>`
|
|
76
|
+
* 2. 通过 uid 和 modelClassName 获取 model:
|
|
77
|
+
* `<FlowsFloatContextMenu uid="model1" modelClassName="MyModel">{children}</FlowsFloatContextMenu>`
|
|
99
78
|
*
|
|
100
79
|
* @param props.children 子组件,必须提供
|
|
101
|
-
* @param props.enabled 是否启用悬浮菜单,默认为true
|
|
102
|
-
* @param props.showDeleteButton 是否显示删除按钮,默认为true
|
|
103
|
-
* @param props.showCopyUidButton 是否显示复制UID按钮,默认为true
|
|
80
|
+
* @param props.enabled 是否启用悬浮菜单,默认为 true
|
|
81
|
+
* @param props.showDeleteButton 是否显示删除按钮,默认为 true
|
|
82
|
+
* @param props.showCopyUidButton 是否显示复制 UID 按钮,默认为 true
|
|
104
83
|
* @param props.containerStyle 容器自定义样式
|
|
84
|
+
* @param props.toolbarStyle 工具栏自定义样式;`top/left/right/bottom` 会作为 portal overlay 的 inset 使用
|
|
105
85
|
* @param props.className 容器自定义类名
|
|
106
|
-
* @param props.showTitle 是否在边框左上角显示模型title,默认为false
|
|
86
|
+
* @param props.showTitle 是否在边框左上角显示模型 title,默认为 false
|
|
107
87
|
* @param props.settingsMenuLevel 设置菜单层级:1=仅当前模型(默认),2=包含子模型
|
|
108
88
|
* @param props.extraToolbarItems 额外的工具栏项目,仅应用于此实例
|
|
109
89
|
*/
|