@nocobase/flow-engine 2.1.0-beta.9 → 2.2.0-alpha.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.
Files changed (215) hide show
  1. package/lib/FlowContextProvider.d.ts +5 -1
  2. package/lib/FlowContextProvider.js +9 -2
  3. package/lib/components/FieldModelRenderer.js +2 -2
  4. package/lib/components/FlowModelRenderer.d.ts +3 -1
  5. package/lib/components/FlowModelRenderer.js +12 -6
  6. package/lib/components/FormItem.d.ts +6 -0
  7. package/lib/components/FormItem.js +11 -3
  8. package/lib/components/MobilePopup.js +6 -5
  9. package/lib/components/dnd/gridDragPlanner.d.ts +59 -2
  10. package/lib/components/dnd/gridDragPlanner.js +607 -19
  11. package/lib/components/dnd/index.d.ts +31 -2
  12. package/lib/components/dnd/index.js +244 -23
  13. package/lib/components/settings/wrappers/component/SelectWithTitle.d.ts +2 -1
  14. package/lib/components/settings/wrappers/component/SelectWithTitle.js +14 -12
  15. package/lib/components/settings/wrappers/contextual/DefaultSettingsIcon.d.ts +3 -0
  16. package/lib/components/settings/wrappers/contextual/DefaultSettingsIcon.js +152 -42
  17. package/lib/components/settings/wrappers/contextual/FlowsFloatContextMenu.d.ts +23 -43
  18. package/lib/components/settings/wrappers/contextual/FlowsFloatContextMenu.js +352 -295
  19. package/lib/components/settings/wrappers/contextual/useFloatToolbarPortal.d.ts +36 -0
  20. package/lib/components/settings/wrappers/contextual/useFloatToolbarPortal.js +274 -0
  21. package/lib/components/settings/wrappers/contextual/useFloatToolbarVisibility.d.ts +30 -0
  22. package/lib/components/settings/wrappers/contextual/useFloatToolbarVisibility.js +315 -0
  23. package/lib/components/subModel/AddSubModelButton.js +12 -1
  24. package/lib/components/subModel/LazyDropdown.js +301 -52
  25. package/lib/components/subModel/index.d.ts +1 -0
  26. package/lib/components/subModel/index.js +19 -0
  27. package/lib/components/subModel/utils.d.ts +2 -1
  28. package/lib/components/subModel/utils.js +15 -5
  29. package/lib/components/variables/VariableHybridInput.d.ts +27 -0
  30. package/lib/components/variables/VariableHybridInput.js +499 -0
  31. package/lib/components/variables/index.d.ts +2 -0
  32. package/lib/components/variables/index.js +3 -0
  33. package/lib/data-source/index.d.ts +84 -0
  34. package/lib/data-source/index.js +269 -7
  35. package/lib/executor/FlowExecutor.js +6 -3
  36. package/lib/flow-registry/DetachedFlowRegistry.d.ts +21 -0
  37. package/lib/flow-registry/DetachedFlowRegistry.js +80 -0
  38. package/lib/flow-registry/index.d.ts +1 -0
  39. package/lib/flow-registry/index.js +3 -1
  40. package/lib/flowContext.d.ts +9 -1
  41. package/lib/flowContext.js +77 -6
  42. package/lib/flowEngine.d.ts +136 -4
  43. package/lib/flowEngine.js +429 -51
  44. package/lib/flowI18n.js +2 -1
  45. package/lib/flowSettings.d.ts +14 -6
  46. package/lib/flowSettings.js +34 -6
  47. package/lib/index.d.ts +2 -0
  48. package/lib/index.js +7 -0
  49. package/lib/lazy-helper.d.ts +14 -0
  50. package/lib/lazy-helper.js +71 -0
  51. package/lib/locale/en-US.json +1 -0
  52. package/lib/locale/index.d.ts +2 -0
  53. package/lib/locale/zh-CN.json +1 -0
  54. package/lib/models/DisplayItemModel.d.ts +1 -1
  55. package/lib/models/EditableItemModel.d.ts +1 -1
  56. package/lib/models/FilterableItemModel.d.ts +1 -1
  57. package/lib/models/flowModel.d.ts +13 -10
  58. package/lib/models/flowModel.js +126 -34
  59. package/lib/provider.js +38 -23
  60. package/lib/reactive/observer.js +46 -16
  61. package/lib/runjs-context/contexts/FormJSFieldItemRunJSContext.js +4 -3
  62. package/lib/runjs-context/contexts/JSBlockRunJSContext.js +4 -15
  63. package/lib/runjs-context/contexts/JSColumnRunJSContext.js +5 -2
  64. package/lib/runjs-context/contexts/JSEditableFieldRunJSContext.js +5 -8
  65. package/lib/runjs-context/contexts/JSFieldRunJSContext.js +4 -3
  66. package/lib/runjs-context/contexts/JSItemRunJSContext.js +4 -3
  67. package/lib/runjs-context/contexts/base.js +464 -29
  68. package/lib/runjs-context/contexts/elementDoc.d.ts +11 -0
  69. package/lib/runjs-context/contexts/elementDoc.js +152 -0
  70. package/lib/runjs-context/setup.js +1 -0
  71. package/lib/runjs-context/snippets/index.js +13 -2
  72. package/lib/runjs-context/snippets/scene/detail/set-field-style.snippet.d.ts +11 -0
  73. package/lib/runjs-context/snippets/scene/detail/set-field-style.snippet.js +50 -0
  74. package/lib/runjs-context/snippets/scene/table/set-cell-style.snippet.d.ts +11 -0
  75. package/lib/runjs-context/snippets/scene/table/set-cell-style.snippet.js +54 -0
  76. package/lib/types.d.ts +50 -2
  77. package/lib/types.js +1 -0
  78. package/lib/utils/createCollectionContextMeta.js +6 -2
  79. package/lib/utils/index.d.ts +3 -2
  80. package/lib/utils/index.js +7 -0
  81. package/lib/utils/loadedPageCache.d.ts +24 -0
  82. package/lib/utils/loadedPageCache.js +139 -0
  83. package/lib/utils/parsePathnameToViewParams.d.ts +5 -1
  84. package/lib/utils/parsePathnameToViewParams.js +28 -4
  85. package/lib/utils/randomId.d.ts +39 -0
  86. package/lib/utils/randomId.js +45 -0
  87. package/lib/utils/runjsTemplateCompat.js +1 -1
  88. package/lib/utils/runjsValue.js +41 -11
  89. package/lib/utils/schema-utils.d.ts +7 -1
  90. package/lib/utils/schema-utils.js +19 -0
  91. package/lib/views/FlowView.d.ts +7 -1
  92. package/lib/views/FlowView.js +11 -1
  93. package/lib/views/PageComponent.js +8 -6
  94. package/lib/views/ViewNavigation.d.ts +12 -2
  95. package/lib/views/ViewNavigation.js +28 -9
  96. package/lib/views/createViewMeta.js +114 -50
  97. package/lib/views/inheritLayoutContext.d.ts +10 -0
  98. package/lib/views/inheritLayoutContext.js +50 -0
  99. package/lib/views/runViewBeforeClose.d.ts +10 -0
  100. package/lib/views/runViewBeforeClose.js +45 -0
  101. package/lib/views/useDialog.d.ts +2 -1
  102. package/lib/views/useDialog.js +12 -3
  103. package/lib/views/useDrawer.d.ts +2 -1
  104. package/lib/views/useDrawer.js +12 -3
  105. package/lib/views/usePage.d.ts +5 -11
  106. package/lib/views/usePage.js +304 -144
  107. package/package.json +5 -4
  108. package/src/FlowContextProvider.tsx +9 -1
  109. package/src/__tests__/createViewMeta.popup.test.ts +115 -1
  110. package/src/__tests__/flow-engine.test.ts +166 -0
  111. package/src/__tests__/flowContext.test.ts +105 -1
  112. package/src/__tests__/flowEngine.modelLoaders.test.ts +245 -0
  113. package/src/__tests__/flowEngine.moveModel.test.ts +81 -1
  114. package/src/__tests__/flowEngine.removeModel.test.ts +47 -3
  115. package/src/__tests__/flowSettings.test.ts +94 -15
  116. package/src/__tests__/objectVariable.test.ts +24 -0
  117. package/src/__tests__/provider.test.tsx +24 -2
  118. package/src/__tests__/renderHiddenInConfig.test.tsx +6 -6
  119. package/src/__tests__/runjsContext.test.ts +21 -0
  120. package/src/__tests__/runjsContextImplementations.test.ts +9 -2
  121. package/src/__tests__/runjsContextRuntime.test.ts +2 -0
  122. package/src/__tests__/runjsLocales.test.ts +6 -5
  123. package/src/__tests__/runjsSnippets.test.ts +21 -0
  124. package/src/__tests__/viewScopedFlowEngine.test.ts +136 -3
  125. package/src/components/FieldModelRenderer.tsx +2 -1
  126. package/src/components/FlowModelRenderer.tsx +18 -6
  127. package/src/components/FormItem.tsx +7 -1
  128. package/src/components/MobilePopup.tsx +4 -2
  129. package/src/components/__tests__/FlowModelRenderer.test.tsx +65 -2
  130. package/src/components/__tests__/FormItem.test.tsx +25 -0
  131. package/src/components/__tests__/dnd.test.ts +44 -0
  132. package/src/components/__tests__/flow-model-render-error-fallback.test.tsx +20 -10
  133. package/src/components/__tests__/gridDragPlanner.test.ts +472 -5
  134. package/src/components/dnd/__tests__/DndProvider.test.tsx +98 -0
  135. package/src/components/dnd/gridDragPlanner.ts +750 -17
  136. package/src/components/dnd/index.tsx +305 -28
  137. package/src/components/settings/wrappers/component/SelectWithTitle.tsx +21 -9
  138. package/src/components/settings/wrappers/contextual/DefaultSettingsIcon.tsx +178 -48
  139. package/src/components/settings/wrappers/contextual/FlowsFloatContextMenu.tsx +487 -440
  140. package/src/components/settings/wrappers/contextual/__tests__/DefaultSettingsIcon.test.tsx +344 -8
  141. package/src/components/settings/wrappers/contextual/__tests__/FlowsFloatContextMenu.test.tsx +778 -0
  142. package/src/components/settings/wrappers/contextual/useFloatToolbarPortal.ts +360 -0
  143. package/src/components/settings/wrappers/contextual/useFloatToolbarVisibility.ts +361 -0
  144. package/src/components/subModel/AddSubModelButton.tsx +16 -2
  145. package/src/components/subModel/LazyDropdown.tsx +341 -56
  146. package/src/components/subModel/__tests__/AddSubModelButton.test.tsx +524 -38
  147. package/src/components/subModel/__tests__/utils.test.ts +24 -0
  148. package/src/components/subModel/index.ts +1 -0
  149. package/src/components/subModel/utils.ts +13 -2
  150. package/src/components/variables/VariableHybridInput.tsx +531 -0
  151. package/src/components/variables/index.ts +2 -0
  152. package/src/data-source/__tests__/collection.test.ts +41 -2
  153. package/src/data-source/__tests__/index.test.ts +69 -2
  154. package/src/data-source/index.ts +332 -8
  155. package/src/executor/FlowExecutor.ts +6 -3
  156. package/src/executor/__tests__/flowExecutor.test.ts +57 -0
  157. package/src/flow-registry/DetachedFlowRegistry.ts +46 -0
  158. package/src/flow-registry/__tests__/detachedFlowRegistry.test.ts +47 -0
  159. package/src/flow-registry/index.ts +1 -0
  160. package/src/flowContext.ts +85 -6
  161. package/src/flowEngine.ts +484 -45
  162. package/src/flowI18n.ts +2 -1
  163. package/src/flowSettings.ts +40 -6
  164. package/src/index.ts +2 -0
  165. package/src/lazy-helper.tsx +57 -0
  166. package/src/locale/en-US.json +1 -0
  167. package/src/locale/zh-CN.json +1 -0
  168. package/src/models/DisplayItemModel.tsx +1 -1
  169. package/src/models/EditableItemModel.tsx +1 -1
  170. package/src/models/FilterableItemModel.tsx +1 -1
  171. package/src/models/__tests__/flowEngine.resolveUse.test.ts +0 -15
  172. package/src/models/__tests__/flowModel.test.ts +65 -37
  173. package/src/models/flowModel.tsx +184 -65
  174. package/src/provider.tsx +41 -25
  175. package/src/reactive/__tests__/observer.test.tsx +82 -0
  176. package/src/reactive/observer.tsx +87 -25
  177. package/src/runjs-context/contexts/FormJSFieldItemRunJSContext.ts +4 -3
  178. package/src/runjs-context/contexts/JSBlockRunJSContext.ts +4 -15
  179. package/src/runjs-context/contexts/JSColumnRunJSContext.ts +4 -2
  180. package/src/runjs-context/contexts/JSEditableFieldRunJSContext.ts +5 -9
  181. package/src/runjs-context/contexts/JSFieldRunJSContext.ts +4 -3
  182. package/src/runjs-context/contexts/JSItemRunJSContext.ts +4 -3
  183. package/src/runjs-context/contexts/base.ts +467 -31
  184. package/src/runjs-context/contexts/elementDoc.ts +130 -0
  185. package/src/runjs-context/setup.ts +1 -0
  186. package/src/runjs-context/snippets/index.ts +12 -1
  187. package/src/runjs-context/snippets/scene/detail/set-field-style.snippet.ts +30 -0
  188. package/src/runjs-context/snippets/scene/table/set-cell-style.snippet.ts +34 -0
  189. package/src/types.ts +62 -0
  190. package/src/utils/__tests__/createCollectionContextMeta.test.ts +48 -0
  191. package/src/utils/__tests__/parsePathnameToViewParams.test.ts +21 -0
  192. package/src/utils/__tests__/runjsValue.test.ts +11 -0
  193. package/src/utils/__tests__/utils.test.ts +62 -0
  194. package/src/utils/createCollectionContextMeta.ts +6 -2
  195. package/src/utils/index.ts +5 -1
  196. package/src/utils/loadedPageCache.ts +147 -0
  197. package/src/utils/parsePathnameToViewParams.ts +45 -5
  198. package/src/utils/randomId.ts +48 -0
  199. package/src/utils/runjsTemplateCompat.ts +1 -1
  200. package/src/utils/runjsValue.ts +50 -11
  201. package/src/utils/schema-utils.ts +30 -1
  202. package/src/views/FlowView.tsx +22 -2
  203. package/src/views/PageComponent.tsx +7 -4
  204. package/src/views/ViewNavigation.ts +46 -9
  205. package/src/views/__tests__/FlowView.usePage.test.tsx +243 -3
  206. package/src/views/__tests__/ViewNavigation.test.ts +52 -0
  207. package/src/views/__tests__/inheritLayoutContext.test.ts +53 -0
  208. package/src/views/__tests__/runViewBeforeClose.test.ts +30 -0
  209. package/src/views/__tests__/useDialog.closeDestroy.test.tsx +12 -12
  210. package/src/views/createViewMeta.ts +106 -34
  211. package/src/views/inheritLayoutContext.ts +26 -0
  212. package/src/views/runViewBeforeClose.ts +19 -0
  213. package/src/views/useDialog.tsx +13 -3
  214. package/src/views/useDrawer.tsx +13 -3
  215. package/src/views/usePage.tsx +367 -180
@@ -0,0 +1,499 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ var __create = Object.create;
11
+ var __defProp = Object.defineProperty;
12
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
13
+ var __getOwnPropNames = Object.getOwnPropertyNames;
14
+ var __getProtoOf = Object.getPrototypeOf;
15
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
16
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
17
+ var __export = (target, all) => {
18
+ for (var name in all)
19
+ __defProp(target, name, { get: all[name], enumerable: true });
20
+ };
21
+ var __copyProps = (to, from, except, desc) => {
22
+ if (from && typeof from === "object" || typeof from === "function") {
23
+ for (let key of __getOwnPropNames(from))
24
+ if (!__hasOwnProp.call(to, key) && key !== except)
25
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
26
+ }
27
+ return to;
28
+ };
29
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
30
+ // If the importer is in node compatibility mode or this is not an ESM
31
+ // file that has been converted to a CommonJS file using a Babel-
32
+ // compatible transform (i.e. "__esModule" has not been set), then set
33
+ // "default" to the CommonJS "module.exports" for node compatibility.
34
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
35
+ mod
36
+ ));
37
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
38
+ var VariableHybridInput_exports = {};
39
+ __export(VariableHybridInput_exports, {
40
+ VariableHybridInput: () => VariableHybridInput
41
+ });
42
+ module.exports = __toCommonJS(VariableHybridInput_exports);
43
+ var import_css = require("@emotion/css");
44
+ var import_antd = require("antd");
45
+ var import_react = __toESM(require("react"));
46
+ var import_FlowContextProvider = require("../../FlowContextProvider");
47
+ var import_FlowContextSelector = require("../FlowContextSelector");
48
+ var import_useResolvedMetaTree = require("./useResolvedMetaTree");
49
+ var import_utils = require("./utils");
50
+ const DEFAULT_VARIABLE_REGEXP = /\{\{\s*([^{}]+?)\s*\}\}/g;
51
+ const TAG_CLASS = "nb-variable-tag";
52
+ function reactNodeToPlainText(node) {
53
+ if (node == null || typeof node === "boolean") return "";
54
+ if (typeof node === "string" || typeof node === "number") return String(node);
55
+ if (Array.isArray(node)) return node.map(reactNodeToPlainText).join("");
56
+ if ((0, import_react.isValidElement)(node)) return reactNodeToPlainText(node.props.children);
57
+ return "";
58
+ }
59
+ __name(reactNodeToPlainText, "reactNodeToPlainText");
60
+ function escapeHtml(value) {
61
+ return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
62
+ }
63
+ __name(escapeHtml, "escapeHtml");
64
+ function getDomValue(element) {
65
+ const out = [];
66
+ for (const node of Array.from(element.childNodes)) {
67
+ if (node instanceof HTMLElement && node.dataset.variable) {
68
+ out.push(node.dataset.variable);
69
+ } else {
70
+ out.push(node.textContent || "");
71
+ }
72
+ }
73
+ return out.join("");
74
+ }
75
+ __name(getDomValue, "getDomValue");
76
+ function createTagHTML(variable, label) {
77
+ return `<span class="${TAG_CLASS}" contenteditable="false" data-variable="${escapeHtml(
78
+ variable
79
+ )}" title="${escapeHtml(label)}">${escapeHtml(label)}</span>`;
80
+ }
81
+ __name(createTagHTML, "createTagHTML");
82
+ function normalizeVariableKey(value) {
83
+ return value.replace(/^\{\{\s*/, "").replace(/\s*\}\}$/, "").trim();
84
+ }
85
+ __name(normalizeVariableKey, "normalizeVariableKey");
86
+ function renderHTML(value, labelMap, regExp) {
87
+ const re = new RegExp(regExp.source, regExp.flags.includes("g") ? regExp.flags : `${regExp.flags}g`);
88
+ return escapeHtml(value || "").replace(re, (matched) => {
89
+ const label = labelMap.get(normalizeVariableKey(matched)) || matched;
90
+ return createTagHTML(matched, label);
91
+ });
92
+ }
93
+ __name(renderHTML, "renderHTML");
94
+ function buildLabelMap(nodes, ctxT, converters) {
95
+ const map = /* @__PURE__ */ new Map();
96
+ function walk(items = [], parentTitles = []) {
97
+ var _a;
98
+ for (const item of items) {
99
+ const titlePart = reactNodeToPlainText(item.title || item.name);
100
+ const titles = [...parentTitles, titlePart];
101
+ const value = ((_a = converters == null ? void 0 : converters.formatPathToValue) == null ? void 0 : _a.call(converters, item)) ?? (0, import_utils.formatPathToValue)(item);
102
+ if (value) {
103
+ map.set(normalizeVariableKey(value), titles.map(ctxT).join("/"));
104
+ }
105
+ if (Array.isArray(item.children)) {
106
+ walk(item.children, titles);
107
+ }
108
+ }
109
+ }
110
+ __name(walk, "walk");
111
+ walk(nodes);
112
+ return map;
113
+ }
114
+ __name(buildLabelMap, "buildLabelMap");
115
+ function pasteHTML(container, html, indexes) {
116
+ var _a;
117
+ const selection = (_a = window.getSelection) == null ? void 0 : _a.call(window);
118
+ const range = (selection == null ? void 0 : selection.rangeCount) ? selection.getRangeAt(0) : null;
119
+ if (!range) return;
120
+ if (indexes) {
121
+ const children = Array.from(container.childNodes);
122
+ if (indexes[0] === -1) {
123
+ if (indexes[1] && children[indexes[1] - 1]) {
124
+ range.setStartAfter(children[indexes[1] - 1]);
125
+ } else {
126
+ range.setStart(container, 0);
127
+ }
128
+ } else {
129
+ range.setStart(children[indexes[0]], indexes[1]);
130
+ }
131
+ if (indexes[2] === -1) {
132
+ if (indexes[3] && children[indexes[3] - 1]) {
133
+ range.setEndAfter(children[indexes[3] - 1]);
134
+ } else {
135
+ range.setEnd(container, 0);
136
+ }
137
+ } else {
138
+ range.setEnd(children[indexes[2]], indexes[3]);
139
+ }
140
+ }
141
+ const wrapper = document.createElement("div");
142
+ wrapper.innerHTML = html;
143
+ const fragment = document.createDocumentFragment();
144
+ let lastNode = null;
145
+ while (wrapper.firstChild) {
146
+ lastNode = fragment.appendChild(wrapper.firstChild);
147
+ }
148
+ range.deleteContents();
149
+ range.insertNode(fragment);
150
+ if (lastNode) {
151
+ const next = new Range();
152
+ next.setStartAfter(lastNode);
153
+ next.collapse(true);
154
+ selection == null ? void 0 : selection.removeAllRanges();
155
+ selection == null ? void 0 : selection.addRange(next);
156
+ }
157
+ }
158
+ __name(pasteHTML, "pasteHTML");
159
+ function getSingleEndRange(nodes, index, offset) {
160
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
161
+ if (index === -1) {
162
+ let realIndex2 = offset;
163
+ let collapseFlag = false;
164
+ if (realIndex2 && ((_a = nodes[realIndex2 - 1]) == null ? void 0 : _a.nodeName) === "#text" && ((_b = nodes[realIndex2]) == null ? void 0 : _b.nodeName) === "#text") {
165
+ collapseFlag = true;
166
+ }
167
+ let textOffset2 = 0;
168
+ for (let i = offset - 1; i >= 0; i -= 1) {
169
+ if (collapseFlag) {
170
+ if (((_c = nodes[i]) == null ? void 0 : _c.nodeName) === "#text") {
171
+ textOffset2 += ((_d = nodes[i].textContent) == null ? void 0 : _d.length) || 0;
172
+ } else {
173
+ collapseFlag = false;
174
+ }
175
+ }
176
+ if (((_e = nodes[i]) == null ? void 0 : _e.nodeName) === "#text" && ((_f = nodes[i + 1]) == null ? void 0 : _f.nodeName) === "#text") {
177
+ realIndex2 -= 1;
178
+ }
179
+ }
180
+ return textOffset2 ? [realIndex2, textOffset2] : [-1, realIndex2];
181
+ }
182
+ let realIndex = 0;
183
+ let textOffset = 0;
184
+ for (let i = 0; i < index + 1; i += 1) {
185
+ if (((_g = nodes[i]) == null ? void 0 : _g.nodeName) === "#text") {
186
+ if (i !== index && nodes[i + 1] && ((_h = nodes[i + 1]) == null ? void 0 : _h.nodeName) !== "#text") {
187
+ realIndex += 1;
188
+ }
189
+ textOffset += i === index ? offset : ((_i = nodes[i].textContent) == null ? void 0 : _i.length) || 0;
190
+ } else {
191
+ realIndex += 1;
192
+ textOffset = 0;
193
+ }
194
+ }
195
+ return [realIndex, textOffset];
196
+ }
197
+ __name(getSingleEndRange, "getSingleEndRange");
198
+ function getCurrentRange(element) {
199
+ var _a;
200
+ const selection = (_a = window.getSelection) == null ? void 0 : _a.call(window);
201
+ const range = (selection == null ? void 0 : selection.rangeCount) ? selection.getRangeAt(0) : null;
202
+ if (!range || !element.contains(range.commonAncestorContainer)) {
203
+ return [-1, 0, -1, 0];
204
+ }
205
+ const nodes = Array.from(element.childNodes);
206
+ if (!nodes.length) return [-1, 0, -1, 0];
207
+ const startIndex = range.startContainer === element ? -1 : nodes.indexOf(range.startContainer);
208
+ const endIndex = range.endContainer === element ? -1 : nodes.indexOf(range.endContainer);
209
+ return [
210
+ ...getSingleEndRange(nodes, startIndex, range.startOffset),
211
+ ...getSingleEndRange(nodes, endIndex, range.endOffset)
212
+ ];
213
+ }
214
+ __name(getCurrentRange, "getCurrentRange");
215
+ const VariableHybridInputComponent = /* @__PURE__ */ __name((props) => {
216
+ const { addonBefore, className, converters, disabled, metaTree, onChange, placeholder, style } = props;
217
+ const { token } = import_antd.theme.useToken();
218
+ const ctx = (0, import_FlowContextProvider.useFlowContext)();
219
+ const { resolvedMetaTree } = (0, import_useResolvedMetaTree.useResolvedMetaTree)(metaTree);
220
+ const inputRef = (0, import_react.useRef)(null);
221
+ const [isComposing, setIsComposing] = (0, import_react.useState)(false);
222
+ const [changed, setChanged] = (0, import_react.useState)(false);
223
+ const [range, setRange] = (0, import_react.useState)([-1, 0, -1, 0]);
224
+ const value = typeof props.value === "string" ? props.value : props.value == null ? "" : String(props.value);
225
+ const variableRegExp = (converters == null ? void 0 : converters.variableRegExp) ?? DEFAULT_VARIABLE_REGEXP;
226
+ const labelMap = (0, import_react.useMemo)(
227
+ () => buildLabelMap(resolvedMetaTree, ctx.t, converters),
228
+ [resolvedMetaTree, ctx, converters]
229
+ );
230
+ const [html, setHtml] = (0, import_react.useState)(() => renderHTML(value, labelMap, variableRegExp));
231
+ const emitChange = (0, import_react.useCallback)(
232
+ (target) => {
233
+ onChange == null ? void 0 : onChange(getDomValue(target).trim());
234
+ },
235
+ [onChange]
236
+ );
237
+ (0, import_react.useEffect)(() => {
238
+ setHtml(renderHTML(value, labelMap, variableRegExp));
239
+ if (!changed) {
240
+ setRange([-1, 0, -1, 0]);
241
+ }
242
+ }, [value, labelMap]);
243
+ (0, import_react.useEffect)(() => {
244
+ var _a;
245
+ const element = inputRef.current;
246
+ if (!element) return;
247
+ if (document.activeElement !== element) return;
248
+ const nextRange = new Range();
249
+ if (changed) {
250
+ if (range.join() === "-1,0,-1,0") return;
251
+ const selection = (_a = window.getSelection) == null ? void 0 : _a.call(window);
252
+ if (!selection) return;
253
+ try {
254
+ const children = Array.from(element.childNodes);
255
+ if (children.length) {
256
+ if (range[0] === -1) {
257
+ if (range[1]) nextRange.setStartAfter(children[range[1] - 1]);
258
+ } else {
259
+ nextRange.setStart(children[range[0]], range[1]);
260
+ }
261
+ if (range[2] === -1) {
262
+ if (range[3]) nextRange.setEndAfter(children[range[3] - 1]);
263
+ } else {
264
+ nextRange.setEnd(children[range[2]], range[3]);
265
+ }
266
+ }
267
+ nextRange.collapse(true);
268
+ selection.removeAllRanges();
269
+ selection.addRange(nextRange);
270
+ } catch {
271
+ }
272
+ } else {
273
+ const { lastChild } = element;
274
+ if (lastChild) {
275
+ nextRange.setStartAfter(lastChild);
276
+ nextRange.setEndAfter(lastChild);
277
+ const nodes = Array.from(element.childNodes);
278
+ const idx = nodes.indexOf(lastChild);
279
+ const startIndex = nextRange.startContainer === element ? -1 : idx;
280
+ const endIndex = nextRange.startContainer === element ? -1 : idx;
281
+ setRange([startIndex, nextRange.startOffset, endIndex, nextRange.endOffset]);
282
+ }
283
+ }
284
+ }, [changed, html, range]);
285
+ const insertVariable = (0, import_react.useCallback)(
286
+ (variable, meta) => {
287
+ const current = inputRef.current;
288
+ if (!current || !variable) return;
289
+ const label = labelMap.get(normalizeVariableKey(variable)) || (meta ? [...meta.parentTitles || [], reactNodeToPlainText(meta.title || meta.name)].map(ctx.t).join("/") : variable);
290
+ current.focus();
291
+ pasteHTML(current, createTagHTML(variable, label), range);
292
+ setChanged(true);
293
+ setRange(getCurrentRange(current));
294
+ emitChange(current);
295
+ },
296
+ [labelMap, range, emitChange, ctx]
297
+ );
298
+ const handleSelectorChange = (0, import_react.useCallback)(
299
+ (next, meta) => {
300
+ if (!next) return;
301
+ insertVariable(next, meta);
302
+ },
303
+ [insertVariable]
304
+ );
305
+ const handleInput = (0, import_react.useCallback)(
306
+ ({ currentTarget }) => {
307
+ if (isComposing) return;
308
+ setChanged(true);
309
+ setRange(getCurrentRange(currentTarget));
310
+ emitChange(currentTarget);
311
+ },
312
+ [emitChange, isComposing]
313
+ );
314
+ const handleBlur = (0, import_react.useCallback)(({ currentTarget }) => {
315
+ setRange(getCurrentRange(currentTarget));
316
+ }, []);
317
+ const handleKeyDown = (0, import_react.useCallback)((event) => {
318
+ if (event.key === "Enter") {
319
+ event.preventDefault();
320
+ }
321
+ }, []);
322
+ const handlePaste = (0, import_react.useCallback)(
323
+ (event) => {
324
+ event.preventDefault();
325
+ const text = event.clipboardData.getData("text/plain").replace(/\n/g, " ");
326
+ if (!text) return;
327
+ setChanged(true);
328
+ pasteHTML(event.currentTarget, escapeHtml(text));
329
+ setRange(getCurrentRange(event.currentTarget));
330
+ emitChange(event.currentTarget);
331
+ },
332
+ [emitChange]
333
+ );
334
+ const handleCompositionStart = (0, import_react.useCallback)(() => setIsComposing(true), []);
335
+ const handleCompositionEnd = (0, import_react.useCallback)(
336
+ ({ currentTarget }) => {
337
+ setIsComposing(false);
338
+ setChanged(true);
339
+ setRange(getCurrentRange(currentTarget));
340
+ emitChange(currentTarget);
341
+ },
342
+ [emitChange]
343
+ );
344
+ const wrapperClassName = (0, import_react.useMemo)(
345
+ () => import_css.css`
346
+ display: flex;
347
+ width: 100%;
348
+ min-width: 0;
349
+
350
+ &.ant-space-compact {
351
+ display: flex;
352
+ }
353
+
354
+ /* The trigger button from FlowContextSelector sits at the right end.
355
+ Flatten its left corners so it shares the border with the editor. */
356
+ > .ant-btn {
357
+ flex-shrink: 0;
358
+ border-top-left-radius: 0;
359
+ border-bottom-left-radius: 0;
360
+ margin-left: -${token.lineWidth}px;
361
+ }
362
+
363
+ > .ant-btn:hover,
364
+ > .ant-btn:focus {
365
+ z-index: 2;
366
+ }
367
+ `,
368
+ [token.lineWidth]
369
+ );
370
+ const addonClassName = (0, import_react.useMemo)(
371
+ () => import_css.css`
372
+ display: inline-flex;
373
+ align-items: center;
374
+ padding: 0 ${token.paddingSM}px;
375
+ background: ${token.colorFillTertiary};
376
+ border: ${token.lineWidth}px ${token.lineType} ${token.colorBorder};
377
+ border-right: 0;
378
+ border-radius: ${token.borderRadius}px 0 0 ${token.borderRadius}px;
379
+ color: ${token.colorText};
380
+ font-size: ${token.fontSize}px;
381
+ line-height: 1;
382
+ white-space: nowrap;
383
+ `,
384
+ [token]
385
+ );
386
+ const editorClassName = (0, import_react.useMemo)(() => {
387
+ const verticalPad = Math.max(
388
+ 0,
389
+ (token.controlHeight - Math.round(token.lineHeight * token.fontSize)) / 2 - token.lineWidth
390
+ );
391
+ return import_css.css`
392
+ flex: 1 1 auto;
393
+ min-width: 0;
394
+ min-height: ${token.controlHeight}px;
395
+ padding: ${verticalPad}px ${token.paddingSM}px;
396
+ overflow: hidden;
397
+ white-space: pre-wrap;
398
+ word-break: break-word;
399
+ line-height: ${token.lineHeight};
400
+ font-size: ${token.fontSize}px;
401
+ color: ${token.colorText};
402
+ background: ${token.colorBgContainer};
403
+ border: ${token.lineWidth}px ${token.lineType} ${token.colorBorder};
404
+ /* Right corners are always flat because the X picker button is glued to the right side. */
405
+ border-radius: ${addonBefore ? "0" : `${token.borderRadius}px 0 0 ${token.borderRadius}px`};
406
+ cursor: text;
407
+ transition: all ${token.motionDurationMid};
408
+ outline: none;
409
+
410
+ &:hover {
411
+ border-color: ${token.colorPrimaryHover};
412
+ z-index: 1;
413
+ }
414
+
415
+ &:focus,
416
+ &:focus-visible {
417
+ border-color: ${token.colorPrimary};
418
+ box-shadow: 0 0 0 ${token.controlOutlineWidth}px ${token.controlOutline};
419
+ z-index: 1;
420
+ }
421
+
422
+ &[data-placeholder]:empty::before {
423
+ content: attr(data-placeholder);
424
+ color: ${token.colorTextPlaceholder};
425
+ pointer-events: none;
426
+ }
427
+
428
+ .${TAG_CLASS} {
429
+ /* inline lets long tag content wrap naturally across lines, mirroring v1. */
430
+ display: inline;
431
+ margin: 0 ${token.marginXXS}px;
432
+ padding: ${token.paddingXXS}px ${token.paddingXS}px;
433
+ font-size: ${token.fontSizeSM}px;
434
+ line-height: ${token.lineHeightSM};
435
+ color: ${token.colorPrimaryText};
436
+ background: ${token.colorPrimaryBg};
437
+ border: ${token.lineWidth}px ${token.lineType} ${token.colorPrimaryBorder};
438
+ border-radius: ${token.borderRadiusSM}px;
439
+ vertical-align: baseline;
440
+ user-select: none;
441
+ cursor: default;
442
+ }
443
+
444
+ &.is-disabled {
445
+ background: ${token.colorBgContainerDisabled};
446
+ color: ${token.colorTextDisabled};
447
+ border-color: ${token.colorBorder};
448
+ cursor: not-allowed;
449
+
450
+ &:hover {
451
+ border-color: ${token.colorBorder};
452
+ }
453
+
454
+ .${TAG_CLASS} {
455
+ color: ${token.colorTextDisabled};
456
+ background: ${token.colorFillTertiary};
457
+ border-color: ${token.colorBorder};
458
+ }
459
+ }
460
+ `;
461
+ }, [token, addonBefore]);
462
+ return /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement(import_antd.Space.Compact, { className: (0, import_css.cx)("nb-variable-hybrid-input", wrapperClassName, className), style }, addonBefore != null && /* @__PURE__ */ import_react.default.createElement("span", { className: addonClassName }, addonBefore), /* @__PURE__ */ import_react.default.createElement(
463
+ "div",
464
+ {
465
+ ref: inputRef,
466
+ role: "textbox",
467
+ "aria-label": "textbox",
468
+ className: (0, import_css.cx)(editorClassName, {
469
+ "is-disabled": disabled
470
+ }),
471
+ contentEditable: !disabled,
472
+ "data-placeholder": placeholder,
473
+ onInput: handleInput,
474
+ onBlur: handleBlur,
475
+ onKeyDown: handleKeyDown,
476
+ onPaste: handlePaste,
477
+ onCompositionStart: handleCompositionStart,
478
+ onCompositionEnd: handleCompositionEnd,
479
+ dangerouslySetInnerHTML: { __html: html }
480
+ }
481
+ ), /* @__PURE__ */ import_react.default.createElement(
482
+ import_FlowContextSelector.FlowContextSelector,
483
+ {
484
+ metaTree,
485
+ disabled,
486
+ parseValueToPath: (converters == null ? void 0 : converters.parseValueToPath) ?? import_utils.parseValueToPath,
487
+ formatPathToValue: (item) => {
488
+ var _a;
489
+ return ((_a = converters == null ? void 0 : converters.formatPathToValue) == null ? void 0 : _a.call(converters, item)) || (0, import_utils.formatPathToValue)(item);
490
+ },
491
+ onChange: handleSelectorChange
492
+ }
493
+ )));
494
+ }, "VariableHybridInputComponent");
495
+ const VariableHybridInput = import_react.default.memo(VariableHybridInputComponent);
496
+ // Annotate the CommonJS export names for ESM import in node:
497
+ 0 && (module.exports = {
498
+ VariableHybridInput
499
+ });
@@ -7,6 +7,8 @@
7
7
  * For more information, please refer to: https://www.nocobase.com/agreement.
8
8
  */
9
9
  export { VariableInput } from './VariableInput';
10
+ export { VariableHybridInput } from './VariableHybridInput';
11
+ export type { VariableHybridInputProps, VariableHybridInputConverters } from './VariableHybridInput';
10
12
  export { SlateVariableEditor } from './SlateVariableEditor';
11
13
  export { VariableTag } from './VariableTag';
12
14
  export { InlineVariableTag } from './InlineVariableTag';
@@ -29,12 +29,14 @@ var variables_exports = {};
29
29
  __export(variables_exports, {
30
30
  InlineVariableTag: () => import_InlineVariableTag.InlineVariableTag,
31
31
  SlateVariableEditor: () => import_SlateVariableEditor.SlateVariableEditor,
32
+ VariableHybridInput: () => import_VariableHybridInput.VariableHybridInput,
32
33
  VariableInput: () => import_VariableInput.VariableInput,
33
34
  VariableTag: () => import_VariableTag.VariableTag,
34
35
  useResolvedMetaTree: () => import_useResolvedMetaTree.useResolvedMetaTree
35
36
  });
36
37
  module.exports = __toCommonJS(variables_exports);
37
38
  var import_VariableInput = require("./VariableInput");
39
+ var import_VariableHybridInput = require("./VariableHybridInput");
38
40
  var import_SlateVariableEditor = require("./SlateVariableEditor");
39
41
  var import_VariableTag = require("./VariableTag");
40
42
  var import_InlineVariableTag = require("./InlineVariableTag");
@@ -45,6 +47,7 @@ __reExport(variables_exports, require("./utils"), module.exports);
45
47
  0 && (module.exports = {
46
48
  InlineVariableTag,
47
49
  SlateVariableEditor,
50
+ VariableHybridInput,
48
51
  VariableInput,
49
52
  VariableTag,
50
53
  useResolvedMetaTree,
@@ -15,11 +15,58 @@ export interface DataSourceOptions extends Record<string, any> {
15
15
  description?: string;
16
16
  [key: string]: any;
17
17
  }
18
+ export type DataSourceRequester = (options: Record<string, any>) => Promise<any>;
19
+ export interface DataSourceLoadResult {
20
+ collections?: CollectionOptions[];
21
+ dataSources?: Array<DataSourceOptions & {
22
+ collections?: CollectionOptions[];
23
+ }>;
24
+ }
25
+ export type DataSourceLoader = (context: {
26
+ key: string;
27
+ manager: DataSourceManager;
28
+ }) => Promise<DataSourceLoadResult>;
18
29
  export declare class DataSourceManager {
19
30
  dataSources: Map<string, DataSource>;
20
31
  flowEngine: FlowEngine;
32
+ requester?: DataSourceRequester;
33
+ collectionFieldInterfaceManager?: {
34
+ addFieldInterfaces?: (fieldInterfaceClasses?: any[]) => void;
35
+ addFieldInterfaceGroups?: (groups: Record<string, {
36
+ label: string;
37
+ order?: number;
38
+ }>) => void;
39
+ addFieldInterfaceComponentOption?: (name: string, option: any) => void;
40
+ addFieldInterfaceOperator?: (name: string, operator: any) => void;
41
+ registerFieldFilterOperator?: (operator: any) => void;
42
+ registerFieldFilterOperatorGroup?: (name: string, operators?: any[]) => void;
43
+ addFieldFilterOperatorsToGroup?: (name: string, operators?: any[]) => void;
44
+ getFieldInterface?: (name: string) => any;
45
+ registerFieldInterfaceConfigure?: (options: unknown) => void;
46
+ getFieldInterfaceConfigure?: (name: string, collectionInfo?: unknown) => unknown;
47
+ getFieldInterfaceConfigureProperties?: (name: string, collectionInfo?: any) => Record<string, any>;
48
+ };
49
+ loaders: Map<string, DataSourceLoader>;
50
+ loadedKeys: Set<string>;
51
+ loadingKeys: Set<string>;
52
+ loadErrors: Map<string, Error>;
53
+ loadingPromise: Promise<void> | null;
21
54
  constructor();
22
55
  setFlowEngine(flowEngine: FlowEngine): void;
56
+ setRequester(requester?: DataSourceRequester): void;
57
+ setCollectionFieldInterfaceManager(manager: DataSourceManager['collectionFieldInterfaceManager']): void;
58
+ addFieldInterfaces(fieldInterfaceClasses?: any[]): void;
59
+ addFieldInterfaceGroups(groups: Record<string, {
60
+ label: string;
61
+ order?: number;
62
+ }>): void;
63
+ addFieldInterfaceComponentOption(name: string, option: any): void;
64
+ addFieldInterfaceOperator(name: string, operator: any): void;
65
+ registerFieldFilterOperator(operator: any): void;
66
+ registerFieldFilterOperatorGroup(name: string, operators?: any[]): void;
67
+ addFieldFilterOperatorsToGroup(name: string, operators?: any[]): void;
68
+ registerLoader(key: string, loader: DataSourceLoader): void;
69
+ removeLoader(key: string): void;
23
70
  addDataSource(ds: DataSource | DataSourceOptions): void;
24
71
  upsertDataSource(ds: DataSource | DataSourceOptions): void;
25
72
  removeDataSource(key: string): void;
@@ -28,7 +75,32 @@ export declare class DataSourceManager {
28
75
  getDataSource(key: string): DataSource | undefined;
29
76
  getCollection(dataSourceKey: string, collectionName: string): Collection | undefined;
30
77
  getCollectionField(fieldPathWithDataSource: string): CollectionField;
78
+ ensureLoaded(options?: {
79
+ force?: boolean;
80
+ keys?: string[];
81
+ }): Promise<void>;
82
+ reload(options?: {
83
+ keys?: string[];
84
+ }): Promise<void>;
85
+ reloadDataSource(key: string): Promise<void>;
86
+ protected resolveLoadKeys(requestedKeys?: string[]): string[];
87
+ protected getApp(): {
88
+ eventBus?: EventTarget;
89
+ };
90
+ protected dispatchDataSourceEvent(type: 'dataSource:loaded' | 'dataSource:loadFailed', detail: {
91
+ dataSourceKey: string;
92
+ initial: boolean;
93
+ error?: Error;
94
+ }): void;
95
+ protected setDataSourceState(key: string, options: Partial<Pick<DataSourceOptions, 'status' | 'errorMessage'>> & Record<string, any>): void;
96
+ protected applyDataSourceLoadResult(key: string, result: DataSourceLoadResult): void;
97
+ protected loadKey(key: string, options: {
98
+ initial: boolean;
99
+ force: boolean;
100
+ }): Promise<void>;
31
101
  }
102
+ export type CollectionFieldInterfaceDataSourceManager = Pick<DataSourceManager, 'collectionFieldInterfaceManager'>;
103
+ export declare function getCollectionFieldInterface(interfaceName: string | undefined, ...dataSourceManagers: Array<CollectionFieldInterfaceDataSourceManager | null | undefined>): any;
32
104
  export declare class DataSource {
33
105
  dataSourceManager: DataSourceManager;
34
106
  collectionManager: CollectionManager;
@@ -38,6 +110,8 @@ export declare class DataSource {
38
110
  get displayName(): any;
39
111
  get key(): any;
40
112
  get name(): any;
113
+ get status(): any;
114
+ get errorMessage(): any;
41
115
  setDataSourceManager(dataSourceManager: DataSourceManager): void;
42
116
  getCollections(): Collection[];
43
117
  getCollection(name: string): Collection | undefined;
@@ -52,9 +126,14 @@ export declare class DataSource {
52
126
  upsertCollections(collections: CollectionOptions[], options?: {
53
127
  clearFields?: boolean;
54
128
  }): void;
129
+ setCollections(collections: CollectionOptions[], options?: {
130
+ clearFields?: boolean;
131
+ }): void;
55
132
  removeCollection(name: string): void;
56
133
  clearCollections(): void;
57
134
  setOptions(newOptions?: any): void;
135
+ patchOptions(newOptions?: any): void;
136
+ reload(): Promise<void>;
58
137
  getCollectionField(fieldPath: string): CollectionField;
59
138
  }
60
139
  export interface CollectionOptions {
@@ -72,6 +151,7 @@ export declare class CollectionManager {
72
151
  notSupportView?: string[];
73
152
  };
74
153
  constructor(dataSource: DataSource);
154
+ protected resetCaches(): void;
75
155
  get flowEngine(): FlowEngine;
76
156
  addCollection(collection: Collection | CollectionOptions): void;
77
157
  removeCollection(name: string): void;
@@ -82,6 +162,9 @@ export declare class CollectionManager {
82
162
  upsertCollections(collections: CollectionOptions[], options?: {
83
163
  clearFields?: boolean;
84
164
  }): void;
165
+ setCollections(collections: CollectionOptions[], options?: {
166
+ clearFields?: boolean;
167
+ }): void;
85
168
  sortCollectionsByInherits(collections: CollectionOptions[]): CollectionOptions[];
86
169
  getCollection(name: string): Collection | undefined;
87
170
  getCollections(): Collection[];
@@ -116,6 +199,7 @@ export declare class Collection {
116
199
  setOptions(newOptions?: any, options?: {
117
200
  clearFields?: boolean;
118
201
  }): void;
202
+ setOption(key: string, value: any): void;
119
203
  getFields(): CollectionField[];
120
204
  getToOneAssociationFields(): CollectionField[];
121
205
  getAssociationFields(types?: any[]): CollectionField[];