UNPKG

@nocobase/flow-engine

Version:

A standalone flow engine for NocoBase, managing workflows, models, and actions.

232 lines (230 loc) 9.73 kB
/** * This file is part of the NocoBase (R) project. * Copyright (c) 2020-2024 NocoBase Co., Ltd. * Authors: NocoBase Team. * * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License. * For more information, please refer to: https://www.nocobase.com/agreement. */ var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var FlowsContextMenu_exports = {}; __export(FlowsContextMenu_exports, { FlowsContextMenu: () => FlowsContextMenu }); module.exports = __toCommonJS(FlowsContextMenu_exports); var import_icons = require("@ant-design/icons"); var import_react = require("@formily/react"); var import_antd = require("antd"); var import_react2 = __toESM(require("react")); var import_flowContext = require("../../../../flowContext"); var import_hooks = require("../../../../hooks"); var import_utils = require("../../../../utils"); var import_StepSettingsDialog = require("./StepSettingsDialog"); const isModelByIdProps = /* @__PURE__ */ __name((props) => { return "uid" in props && "modelClassName" in props && Boolean(props.uid) && Boolean(props.modelClassName); }, "isModelByIdProps"); const FlowsContextMenu = /* @__PURE__ */ __name((props) => { if (isModelByIdProps(props)) { return /* @__PURE__ */ import_react2.default.createElement(FlowsContextMenuWithModelById, { ...props }); } else { return /* @__PURE__ */ import_react2.default.createElement(FlowsContextMenuWithModel, { ...props }); } }, "FlowsContextMenu"); const FlowsContextMenuWithModel = (0, import_react.observer)( ({ model, children, enabled = true, position = "right", showDeleteButton = true }) => { const t = (0, import_utils.getT)(model); const handleMenuClick = (0, import_react2.useCallback)( ({ key }) => { var _a; if (key === "delete") { import_antd.Modal.confirm({ title: t("Confirm delete"), icon: /* @__PURE__ */ import_react2.default.createElement(import_icons.ExclamationCircleOutlined, null), content: t("Are you sure you want to delete this item? This action cannot be undone."), okText: t("Confirm Delete"), okType: "danger", cancelText: t("Cancel"), zIndex: 999999, onOk() { try { model.dispatchEvent("remove"); } catch (error) { console.error(t("Delete operation failed"), ":", error); import_antd.Modal.error({ title: t("Delete failed"), content: t("Delete operation failed, please check the console for details.") }); } } }); } else { const [flowKey, stepKey] = key.split(":"); try { const flow = model.getFlow(flowKey); const step = (_a = flow == null ? void 0 : flow.steps) == null ? void 0 : _a[stepKey]; if (!flow || !step) { console.error(`Flow ${flowKey} or step ${stepKey} not found`); return; } const ctx = new import_flowContext.FlowRuntimeContext(model, flowKey, "settings"); (0, import_utils.setupRuntimeContextSteps)(ctx, flow.steps, model, flowKey); ctx.defineProperty("currentStep", { value: step }); (0, import_StepSettingsDialog.openStepSettingsDialog)({ model, flowKey, stepKey, ctx }); } catch (error) { console.log("\u914D\u7F6E\u5F39\u7A97\u5DF2\u53D6\u6D88\u6216\u51FA\u9519:", error); } } }, [model] ); if (!model) { return /* @__PURE__ */ import_react2.default.createElement(import_antd.Alert, { message: "\u63D0\u4F9B\u7684\u6A21\u578B\u65E0\u6548", type: "error" }); } if (!enabled || !children) { return /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, children); } const getConfigurableFlowsAndSteps = (0, import_react2.useCallback)(() => { try { const flows = model.getFlows(); const flowsArray = Array.from(flows.values()); return flowsArray.map((flow) => { const configurableSteps = Object.entries(flow.steps).map(([stepKey, stepDefinition]) => { var _a, _b; const actionStep = stepDefinition; if (actionStep.hideInSettings) { return null; } const stepUiSchema = actionStep.uiSchema || {}; let actionUiSchema = {}; if (actionStep.use) { const action = (_b = (_a = model.flowEngine) == null ? void 0 : _a.getAction) == null ? void 0 : _b.call(_a, actionStep.use); if (action && action.uiSchema) { actionUiSchema = action.uiSchema; } } const mergedUiSchema = { ...actionUiSchema }; Object.entries(stepUiSchema).forEach(([fieldKey, schema]) => { if (mergedUiSchema[fieldKey]) { mergedUiSchema[fieldKey] = { ...mergedUiSchema[fieldKey], ...schema }; } else { mergedUiSchema[fieldKey] = schema; } }); if (Object.keys(mergedUiSchema).length === 0) { return null; } return { stepKey, step: actionStep, uiSchema: mergedUiSchema, title: actionStep.title || stepKey }; }).filter(Boolean); return configurableSteps.length > 0 ? { flow, steps: configurableSteps } : null; }).filter(Boolean); } catch (error) { console.warn("[FlowsContextMenu] \u83B7\u53D6\u53EF\u914D\u7F6Eflows\u5931\u8D25:", error); return []; } }, [model]); const configurableFlowsAndSteps = getConfigurableFlowsAndSteps(); if (configurableFlowsAndSteps.length === 0 && !showDeleteButton) { return /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, children); } const menuItems = []; if (configurableFlowsAndSteps.length > 0) { configurableFlowsAndSteps.forEach(({ flow, steps }) => { menuItems.push({ key: `flow-group-${flow.key}`, label: flow.title || flow.key, type: "group" }); steps.forEach((stepInfo) => { menuItems.push({ key: `${flow.key}:${stepInfo.stepKey}`, icon: /* @__PURE__ */ import_react2.default.createElement(import_icons.SettingOutlined, null), label: stepInfo.title }); }); }); } if (showDeleteButton) { if (configurableFlowsAndSteps.length > 0) { menuItems.push({ type: "divider" }); } menuItems.push({ key: "delete", icon: /* @__PURE__ */ import_react2.default.createElement(import_icons.DeleteOutlined, null), label: "\u5220\u9664" }); } return /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, /* @__PURE__ */ import_react2.default.createElement( import_antd.Dropdown, { menu: { items: menuItems, onClick: handleMenuClick }, trigger: ["contextMenu"], placement: position === "left" ? "bottomLeft" : "bottomRight" }, /* @__PURE__ */ import_react2.default.createElement("div", { style: { display: "inline-block", width: "100%" } }, children) )); } ); const FlowsContextMenuWithModelById = (0, import_react.observer)( ({ uid, modelClassName, children, enabled = true, position = "right", showDeleteButton = true }) => { const model = (0, import_hooks.useFlowModelById)(uid, modelClassName); if (!model) { return /* @__PURE__ */ import_react2.default.createElement(import_antd.Alert, { message: `\u672A\u627E\u5230ID\u4E3A ${uid} \u7684\u6A21\u578B`, type: "error" }); } return /* @__PURE__ */ import_react2.default.createElement( FlowsContextMenuWithModel, { model, enabled, position, showDeleteButton }, children ); } ); // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { FlowsContextMenu });