UNPKG

@nocobase/flow-engine

Version:

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

200 lines (198 loc) 8.6 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 useDialog_exports = {}; __export(useDialog_exports, { useDialog: () => useDialog }); module.exports = __toCommonJS(useDialog_exports); var React = __toESM(require("react")); var import_dompurify = __toESM(require("dompurify")); var import__ = require(".."); var import_flowContext = require("../flowContext"); var import_FlowContextProvider = require("../FlowContextProvider"); var import_createViewMeta = require("./createViewMeta"); var import_DialogComponent = __toESM(require("./DialogComponent")); var import_usePatchElement = __toESM(require("./usePatchElement")); var import_provider = require("../provider"); var import_ViewScopedFlowEngine = require("../ViewScopedFlowEngine"); let uuid = 0; function useDialog() { const holderRef = React.useRef(null); const open = /* @__PURE__ */ __name((config, flowContext) => { var _a, _b; uuid += 1; const dialogRef = React.createRef(); let closeFunc; let resolvePromise; const promise = new Promise((resolve) => { resolvePromise = resolve; }); let currentFooter = null; let currentHeader = null; const FooterComponent = /* @__PURE__ */ __name(({ children, ...props }) => { React.useEffect(() => { var _a2; currentFooter = children; (_a2 = dialogRef.current) == null ? void 0 : _a2.setFooter(children); return () => { var _a3; currentFooter = null; (_a3 = dialogRef.current) == null ? void 0 : _a3.setFooter(null); }; }, [children]); return null; }, "FooterComponent"); const HeaderComponent = /* @__PURE__ */ __name(({ ...props }) => { React.useEffect(() => { var _a2; currentHeader = props; (_a2 = dialogRef.current) == null ? void 0 : _a2.setHeader(props); return () => { var _a3; currentHeader = null; (_a3 = dialogRef.current) == null ? void 0 : _a3.setHeader(null); }; }, [props]); return null; }, "HeaderComponent"); const currentDialog = { type: "dialog", inputArgs: config.inputArgs || {}, preventClose: !!config.preventClose, destroy: /* @__PURE__ */ __name(() => { var _a2; return (_a2 = dialogRef.current) == null ? void 0 : _a2.destroy(); }, "destroy"), update: /* @__PURE__ */ __name((newConfig) => { var _a2; return (_a2 = dialogRef.current) == null ? void 0 : _a2.update(newConfig); }, "update"), close: /* @__PURE__ */ __name((result, force) => { var _a2; if (config.preventClose && !force) { return; } (_a2 = dialogRef.current) == null ? void 0 : _a2.destroy(); closeFunc == null ? void 0 : closeFunc(); resolvePromise == null ? void 0 : resolvePromise(result); }, "close"), Footer: FooterComponent, Header: HeaderComponent, setFooter: /* @__PURE__ */ __name((footer) => { var _a2; currentFooter = footer; (_a2 = dialogRef.current) == null ? void 0 : _a2.setFooter(footer); }, "setFooter"), setHeader: /* @__PURE__ */ __name((header) => { var _a2; currentHeader = header; (_a2 = dialogRef.current) == null ? void 0 : _a2.setHeader(header); }, "setHeader"), navigation: (_a = config.inputArgs) == null ? void 0 : _a.navigation }; const ctx = new import_flowContext.FlowContext(); ctx.defineProperty("view", { get: /* @__PURE__ */ __name(() => currentDialog, "get"), meta: (0, import_createViewMeta.createViewMeta)(ctx, () => currentDialog), resolveOnServer: /* @__PURE__ */ __name((p) => p === "record" || p.startsWith("record."), "resolveOnServer") }); const scopedEngine = (0, import_ViewScopedFlowEngine.createViewScopedEngine)(flowContext.engine); ctx.defineProperty("engine", { value: scopedEngine }); ctx.addDelegate(scopedEngine.context); if (config.inheritContext !== false) { ctx.addDelegate(flowContext); } else { ctx.addDelegate(flowContext.engine.context); } const DialogWithContext = (0, import__.observer)( () => { var _a2, _b2, _c, _d; const mountedRef = React.useRef(false); const rawContent = typeof config.content === "function" ? config.content(currentDialog, ctx) : config.content; const content = typeof rawContent === "string" ? /* @__PURE__ */ React.createElement("div", { dangerouslySetInnerHTML: { __html: import_dompurify.default.sanitize(rawContent) } }) : rawContent; React.useEffect(() => { var _a3; (_a3 = config.onOpen) == null ? void 0 : _a3.call(config, currentDialog, ctx); }, []); if (((_b2 = (_a2 = config.inputArgs) == null ? void 0 : _a2.hidden) == null ? void 0 : _b2.value) && !mountedRef.current) { return null; } mountedRef.current = true; return /* @__PURE__ */ React.createElement( import_DialogComponent.default, { className: "nb-dialog-overflow-hidden", key: `dialog-${uuid}`, ref: dialogRef, hidden: (_d = (_c = config.inputArgs) == null ? void 0 : _c.hidden) == null ? void 0 : _d.value, ...config, footer: currentFooter, header: currentHeader, afterClose: () => { var _a3; closeFunc == null ? void 0 : closeFunc(); (_a3 = config.onClose) == null ? void 0 : _a3.call(config); resolvePromise == null ? void 0 : resolvePromise(config.result); scopedEngine.unlinkFromStack(); } }, content ); }, { displayName: "DialogWithContext" } ); const dialog = /* @__PURE__ */ React.createElement(import_provider.FlowEngineProvider, { engine: scopedEngine }, /* @__PURE__ */ React.createElement(import_FlowContextProvider.FlowViewContextProvider, { context: ctx }, /* @__PURE__ */ React.createElement(DialogWithContext, null))); closeFunc = (_b = holderRef.current) == null ? void 0 : _b.patchElement(dialog); return Object.assign(promise, currentDialog); }, "open"); const api = React.useMemo(() => ({ open }), []); const ElementsHolder = React.memo( React.forwardRef((props, ref) => { const [elements, patchElement] = (0, import_usePatchElement.default)(); React.useImperativeHandle(ref, () => ({ patchElement }), [patchElement]); return /* @__PURE__ */ React.createElement(React.Fragment, null, elements); }) ); return [api, /* @__PURE__ */ React.createElement(ElementsHolder, { key: "dialog-holder", ref: holderRef })]; } __name(useDialog, "useDialog"); // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { useDialog });