@nocobase/flow-engine
Version:
A standalone flow engine for NocoBase, managing workflows, models, and actions.
226 lines (224 loc) • 8.48 kB
JavaScript
/**
* 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 FlowsDropdownButton_exports = {};
__export(FlowsDropdownButton_exports, {
FlowsDropdownButton: () => FlowsDropdownButton
});
module.exports = __toCommonJS(FlowsDropdownButton_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_hooks = require("../../../../hooks");
const isModelByIdProps = /* @__PURE__ */ __name((props) => {
return "uid" in props && "modelClassName" in props && Boolean(props.uid) && Boolean(props.modelClassName);
}, "isModelByIdProps");
const FlowsDropdownButton = /* @__PURE__ */ __name((props) => {
if (isModelByIdProps(props)) {
const { uid, modelClassName, ...restProps } = props;
return /* @__PURE__ */ import_react2.default.createElement(FlowsDropdownButtonWithModelById, { uid, modelClassName, ...restProps });
} else {
const { model, ...restProps } = props;
return /* @__PURE__ */ import_react2.default.createElement(FlowsDropdownButtonWithModel, { model, ...restProps });
}
}, "FlowsDropdownButton");
const FlowsDropdownButtonWithModel = (0, import_react.observer)(
({
model,
text = "\u6D41\u7A0B\u914D\u7F6E",
icon = /* @__PURE__ */ import_react2.default.createElement(import_icons.SettingOutlined, null),
size = "middle",
type = "default",
disabled = false,
showDropdownIcon = true,
onClick,
style,
className
}) => {
const handleClick = /* @__PURE__ */ __name(() => {
onClick == null ? void 0 : onClick();
}, "handleClick");
const handleMenuClick = (0, import_react2.useCallback)(
({ key }) => {
const [flowKey, stepKey] = key.split(":");
try {
model.openFlowSettings({
flowKey,
stepKey
});
} 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" });
}
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("[FlowsDropdownButton] \u83B7\u53D6\u53EF\u914D\u7F6Eflows\u5931\u8D25:", error);
return [];
}
}, [model]);
const configurableFlowsAndSteps = getConfigurableFlowsAndSteps();
const buildMenuItems = /* @__PURE__ */ __name(() => {
const items = [];
configurableFlowsAndSteps.forEach(({ flow, steps }) => {
items.push({
key: `flow-group-${flow.key}`,
label: flow.title || flow.key,
type: "group"
});
steps.forEach((stepInfo) => {
items.push({
key: `${flow.key}:${stepInfo.stepKey}`,
icon: /* @__PURE__ */ import_react2.default.createElement(import_icons.SettingOutlined, null),
label: stepInfo.title
});
});
});
return items;
}, "buildMenuItems");
const menuItems = buildMenuItems();
const button = /* @__PURE__ */ import_react2.default.createElement(
import_antd.Button,
{
type,
size,
disabled,
icon,
onClick: handleClick,
style,
className
},
/* @__PURE__ */ import_react2.default.createElement(import_antd.Space, null, text, showDropdownIcon && /* @__PURE__ */ import_react2.default.createElement(import_icons.DownOutlined, null))
);
if (configurableFlowsAndSteps.length === 0) {
return button;
}
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: ["click"],
placement: "bottomRight"
},
button
));
}
);
const FlowsDropdownButtonWithModelById = (0, import_react.observer)(
({
uid,
modelClassName,
text = "\u6D41\u7A0B\u914D\u7F6E",
icon = /* @__PURE__ */ import_react2.default.createElement(import_icons.SettingOutlined, null),
size = "middle",
type = "default",
disabled = false,
showDropdownIcon = true,
onClick,
style,
className
}) => {
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(
FlowsDropdownButtonWithModel,
{
model,
text,
icon,
size,
type,
disabled,
showDropdownIcon,
onClick,
style,
className
}
);
}
);
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
FlowsDropdownButton
});