UNPKG

@nocobase/flow-engine

Version:

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

303 lines (301 loc) 11.3 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 SlateVariableEditor_exports = {}; __export(SlateVariableEditor_exports, { SlateVariableEditor: () => SlateVariableEditor }); module.exports = __toCommonJS(SlateVariableEditor_exports); var import_react = __toESM(require("react")); var import_slate = require("slate"); var import_slate_react = require("slate-react"); var import_slate_history = require("slate-history"); var import_InlineVariableTag = require("./InlineVariableTag"); var import_VariableTrigger = require("./VariableTrigger"); var import_utils = require("./utils"); var import_shared = require("@formily/shared"); const SlateVariableEditor = /* @__PURE__ */ __name(({ value = "", onChange, metaTree, multiline = false, placeholder = "\u8F93\u5165\u6587\u672C\uFF0C\u4F7F\u7528 {{ \u63D2\u5165\u53D8\u91CF", style = {}, ...restProps }) => { const editor = (0, import_react.useMemo)(() => { const e = (0, import_slate_react.withReact)((0, import_slate_history.withHistory)((0, import_slate.createEditor)())); const { isInline, isVoid } = e; e.isInline = (element) => { return element.type === "variable" || element.type === "variable-trigger" ? true : isInline(element); }; e.isVoid = (element) => { return element.type === "variable" || element.type === "variable-trigger" ? true : isVoid(element); }; return e; }, []); const [resolvedMetaTree, setResolvedMetaTree] = import_react.default.useState(null); import_react.default.useEffect(() => { const resolveMetaTree = /* @__PURE__ */ __name(async () => { if (!metaTree) { setResolvedMetaTree(null); return; } try { if (typeof metaTree === "function") { const resolved = await metaTree(); setResolvedMetaTree(resolved); } else { setResolvedMetaTree(metaTree); } } catch (error) { console.warn("Failed to resolve metaTree:", error); setResolvedMetaTree(null); } }, "resolveMetaTree"); resolveMetaTree(); }, [metaTree]); const parseValueToSlate = (0, import_react.useCallback)( (text = "") => { if (!text) { return [ { type: "paragraph", children: [{ text: "" }] } ]; } const variableRegex = /\{\{[^}]+\}\}/g; let lastIndex = 0; let match; const children = []; while ((match = variableRegex.exec(text)) !== null) { if (match.index > lastIndex) { children.push({ text: text.slice(lastIndex, match.index) }); } const variableValue = match[0]; const path = (0, import_utils.parseValueToPath)(variableValue); const contextSelectorItem = void 0; if (path && resolvedMetaTree) { } children.push({ type: "variable", value: variableValue, meta: contextSelectorItem, children: [{ text: "" }] // Slate 要求 void 元素有空文本子节点 }); lastIndex = match.index + match[0].length; } if (lastIndex < text.length) { children.push({ text: text.slice(lastIndex) }); } if (children.length === 0) { children.push({ text: "" }); } return [ { type: "paragraph", children } ]; }, [resolvedMetaTree] ); const initialValue = (0, import_react.useMemo)(() => parseValueToSlate(value || ""), [value, parseValueToSlate]); const slateToText = (0, import_react.useCallback)((nodes) => { return nodes.map((n) => { if (import_slate.Element.isElement(n)) { if (n.type === "variable") { return n.value; } return slateToText(n.children); } return n.text; }).join(""); }, []); const handleChange = (0, import_react.useCallback)( (newValue) => { const text = slateToText(newValue); onChange == null ? void 0 : onChange(text); }, [onChange, slateToText] ); const handleVariableSelectFromTrigger = (0, import_react.useCallback)( (triggerId, value2, item) => { const [triggerMatch] = import_slate.Editor.nodes(editor, { match: /* @__PURE__ */ __name((n) => import_slate.Element.isElement(n) && n.type === "variable-trigger" && n.triggerId === triggerId, "match") }); if (triggerMatch) { const [, triggerPath] = triggerMatch; const variableElement = { type: "variable", value: value2, meta: item, children: [{ text: "" }] }; import_slate.Transforms.setNodes(editor, variableElement, { at: triggerPath }); const nextPoint = import_slate.Editor.after(editor, triggerPath); if (nextPoint) { import_slate.Transforms.select(editor, nextPoint); } import_slate_react.ReactEditor.focus(editor); } }, [editor] ); const handleTriggerClose = (0, import_react.useCallback)( (triggerId) => { const [triggerMatch] = import_slate.Editor.nodes(editor, { match: /* @__PURE__ */ __name((n) => import_slate.Element.isElement(n) && n.type === "variable-trigger" && n.triggerId === triggerId, "match") }); if (triggerMatch) { const [, triggerPath] = triggerMatch; import_slate.Transforms.select(editor, triggerPath); import_slate.Transforms.removeNodes(editor, { at: triggerPath }); import_slate.Transforms.insertText(editor, "{{"); import_slate_react.ReactEditor.focus(editor); } }, [editor] ); const renderElement = (0, import_react.useCallback)( (props) => { switch (props.element.type) { case "variable": return /* @__PURE__ */ import_react.default.createElement(VariableElementComponent, { ...props, metaTree: resolvedMetaTree }); case "variable-trigger": return /* @__PURE__ */ import_react.default.createElement( import_VariableTrigger.VariableTrigger, { ...props, element: props.element, metaTree, onVariableSelect: handleVariableSelectFromTrigger, onTriggerClose: handleTriggerClose } ); default: return /* @__PURE__ */ import_react.default.createElement("p", { ...props.attributes }, props.children); } }, [metaTree, resolvedMetaTree, handleVariableSelectFromTrigger, handleTriggerClose] ); const renderLeaf = (0, import_react.useCallback)((props) => { return /* @__PURE__ */ import_react.default.createElement("span", { ...props.attributes, style: { fontWeight: props.leaf.bold ? "bold" : "normal" } }, props.children); }, []); const handleKeyDown = (0, import_react.useCallback)( (event) => { if (event.key === "{") { const { selection } = editor; if (selection && import_slate.Range.isCollapsed(selection)) { const [start] = import_slate.Range.edges(selection); const beforePoint = import_slate.Editor.before(editor, start); if (beforePoint) { const beforeRange = import_slate.Editor.range(editor, beforePoint, start); const beforeText = import_slate.Editor.string(editor, beforeRange); if (beforeText === "{") { event.preventDefault(); import_slate.Transforms.delete(editor, { at: beforeRange }); const triggerId = (0, import_shared.uid)(); const triggerElement = { type: "variable-trigger", triggerId, children: [{ text: "" }] }; import_slate.Transforms.insertNodes(editor, triggerElement); } } } } }, [editor] ); return /* @__PURE__ */ import_react.default.createElement(import_slate_react.Slate, { editor, initialValue, onChange: handleChange }, /* @__PURE__ */ import_react.default.createElement( import_slate_react.Editable, { renderElement, renderLeaf, placeholder, onKeyDown: handleKeyDown, style: { minHeight: multiline ? 100 : 32, padding: "4px 11px", border: "1px solid #d9d9d9", borderRadius: 6, fontSize: 14, lineHeight: 1.5714285714285714, ...style }, ...restProps } )); }, "SlateVariableEditor"); const VariableElementComponent = /* @__PURE__ */ __name(({ attributes, children, element, metaTree }) => { const variableElement = element; const contextSelectorItem = import_react.default.useMemo(() => { if (variableElement.meta) { return variableElement.meta; } if (metaTree && variableElement.value) { const path = (0, import_utils.parseValueToPath)(variableElement.value); } return null; }, [variableElement.meta, variableElement.value, metaTree]); return /* @__PURE__ */ import_react.default.createElement("span", { ...attributes, contentEditable: false }, /* @__PURE__ */ import_react.default.createElement( import_InlineVariableTag.InlineVariableTag, { value: variableElement.value, metaTreeNode: contextSelectorItem, metaTree, style: { marginLeft: 2, marginRight: 2, verticalAlign: "baseline", display: "inline-block" } } ), children); }, "VariableElementComponent"); // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { SlateVariableEditor });