@nocobase/flow-engine 2.2.0-alpha.1 → 2.2.0-alpha.3
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.
- package/lib/JSRunner.d.ts +1 -0
- package/lib/JSRunner.js +110 -20
- package/lib/components/FieldModelRenderer.js +44 -31
- package/lib/components/FlowContextSelector.js +27 -5
- package/lib/components/MobilePopup.style.js +16 -5
- package/lib/components/dnd/index.js +9 -2
- package/lib/components/settings/wrappers/contextual/FlowsFloatContextMenu.js +86 -32
- package/lib/components/settings/wrappers/contextual/useFloatToolbarVisibility.js +20 -0
- package/lib/components/variables/VariableHybridInput.d.ts +8 -0
- package/lib/components/variables/VariableHybridInput.js +128 -12
- package/lib/components/variables/VariableInput.js +2 -1
- package/lib/components/variables/types.d.ts +18 -0
- package/lib/flowContext.d.ts +1 -1
- package/lib/flowContext.js +87 -36
- package/lib/flowI18n.js +3 -3
- package/lib/flowSettings.d.ts +5 -1
- package/lib/flowSettings.js +70 -0
- package/lib/locale/en-US.json +1 -0
- package/lib/locale/index.d.ts +2 -0
- package/lib/locale/zh-CN.json +1 -0
- package/lib/resources/apiResource.js +2 -1
- package/lib/resources/baseRecordResource.js +6 -17
- package/lib/resources/multiRecordResource.js +13 -3
- package/lib/resources/singleRecordResource.js +7 -2
- package/lib/runjs-context/helpers.js +12 -5
- package/lib/types.d.ts +12 -0
- package/lib/utils/dataSourceDirty.d.ts +20 -0
- package/lib/utils/dataSourceDirty.js +139 -0
- package/lib/utils/dirtyAwareApiClient.d.ts +11 -0
- package/lib/utils/dirtyAwareApiClient.js +378 -0
- package/lib/utils/index.d.ts +1 -1
- package/lib/utils/index.js +11 -11
- package/lib/utils/openViewRouteState.d.ts +28 -0
- package/lib/utils/openViewRouteState.js +125 -0
- package/lib/utils/parsePathnameToViewParams.d.ts +3 -0
- package/lib/utils/parsePathnameToViewParams.js +18 -1
- package/lib/utils/resolveRunJSObjectValues.js +3 -2
- package/lib/utils/runjsModuleLoader.js +0 -30
- package/lib/views/ViewNavigation.js +5 -0
- package/package.json +4 -4
- package/src/JSRunner.ts +112 -25
- package/src/__tests__/JSRunner.test.ts +4 -5
- package/src/__tests__/flowContext.test.ts +131 -0
- package/src/__tests__/flowEngine.dataSourceDirty.test.ts +51 -0
- package/src/__tests__/flowI18n.test.ts +11 -0
- package/src/__tests__/flowModel.openView.navigation.test.ts +28 -0
- package/src/__tests__/flowSettings.test.ts +72 -0
- package/src/__tests__/runjsRuntimeFeatures.test.ts +15 -2
- package/src/components/FieldModelRenderer.tsx +50 -36
- package/src/components/FlowContextSelector.tsx +36 -4
- package/src/components/MobilePopup.style.ts +22 -6
- package/src/components/__tests__/FieldModelRenderer.test.tsx +165 -0
- package/src/components/__tests__/MobilePopup.style.test.tsx +103 -0
- package/src/components/dnd/index.tsx +11 -2
- package/src/components/settings/wrappers/contextual/FlowsFloatContextMenu.tsx +105 -35
- package/src/components/settings/wrappers/contextual/__tests__/FlowsFloatContextMenu.test.tsx +381 -12
- package/src/components/settings/wrappers/contextual/useFloatToolbarVisibility.ts +28 -0
- package/src/components/variables/VariableHybridInput.tsx +166 -9
- package/src/components/variables/VariableInput.tsx +2 -1
- package/src/components/variables/__tests__/FlowContextSelector.test.tsx +23 -3
- package/src/components/variables/__tests__/VariableHybridInput.test.tsx +178 -0
- package/src/components/variables/__tests__/VariableInput.test.tsx +51 -5
- package/src/components/variables/types.ts +18 -0
- package/src/flowContext.ts +100 -33
- package/src/flowI18n.ts +8 -3
- package/src/flowSettings.ts +85 -1
- package/src/locale/en-US.json +1 -0
- package/src/locale/zh-CN.json +1 -0
- package/src/resources/apiResource.ts +2 -1
- package/src/resources/baseRecordResource.ts +6 -23
- package/src/resources/multiRecordResource.ts +13 -3
- package/src/resources/singleRecordResource.ts +6 -1
- package/src/runjs-context/helpers.ts +12 -6
- package/src/types.ts +14 -0
- package/src/utils/__tests__/dirtyAwareApiClient.test.ts +392 -0
- package/src/utils/__tests__/openViewRouteState.test.ts +40 -0
- package/src/utils/__tests__/parsePathnameToViewParams.test.ts +36 -0
- package/src/utils/dataSourceDirty.ts +126 -0
- package/src/utils/dirtyAwareApiClient.ts +430 -0
- package/src/utils/index.ts +10 -9
- package/src/utils/openViewRouteState.ts +107 -0
- package/src/utils/parsePathnameToViewParams.ts +23 -1
- package/src/utils/resolveRunJSObjectValues.ts +5 -2
- package/src/utils/runjsModuleLoader.ts +0 -32
- package/src/views/ViewNavigation.ts +6 -1
- package/src/views/__tests__/ViewNavigation.test.ts +15 -0
- package/lib/utils/safeGlobals.d.ts +0 -28
- package/lib/utils/safeGlobals.js +0 -367
- package/src/utils/__tests__/runjsRequireAsyncAutoWhitelist.test.ts +0 -38
- package/src/utils/__tests__/safeGlobals.test.ts +0 -106
- package/src/utils/safeGlobals.ts +0 -406
|
@@ -42,6 +42,7 @@ __export(VariableHybridInput_exports, {
|
|
|
42
42
|
module.exports = __toCommonJS(VariableHybridInput_exports);
|
|
43
43
|
var import_css = require("@emotion/css");
|
|
44
44
|
var import_antd = require("antd");
|
|
45
|
+
var import_context = require("antd/es/form/context");
|
|
45
46
|
var import_react = __toESM(require("react"));
|
|
46
47
|
var import_FlowContextProvider = require("../../FlowContextProvider");
|
|
47
48
|
var import_FlowContextSelector = require("../FlowContextSelector");
|
|
@@ -83,14 +84,28 @@ function normalizeVariableKey(value) {
|
|
|
83
84
|
return value.replace(/^\{\{\s*/, "").replace(/\s*\}\}$/, "").trim();
|
|
84
85
|
}
|
|
85
86
|
__name(normalizeVariableKey, "normalizeVariableKey");
|
|
86
|
-
function renderHTML(value,
|
|
87
|
+
function renderHTML(value, regExp, resolveLabel) {
|
|
87
88
|
const re = new RegExp(regExp.source, regExp.flags.includes("g") ? regExp.flags : `${regExp.flags}g`);
|
|
88
89
|
return escapeHtml(value || "").replace(re, (matched) => {
|
|
89
|
-
const label =
|
|
90
|
+
const label = resolveLabel(matched) || matched;
|
|
90
91
|
return createTagHTML(matched, label);
|
|
91
92
|
});
|
|
92
93
|
}
|
|
93
94
|
__name(renderHTML, "renderHTML");
|
|
95
|
+
function resolveTitlesByPath(roots, path, ctxT) {
|
|
96
|
+
if (!roots || !path || !path.length) return void 0;
|
|
97
|
+
const titles = [];
|
|
98
|
+
let nodes = roots;
|
|
99
|
+
for (const segment of path) {
|
|
100
|
+
if (!nodes) return void 0;
|
|
101
|
+
const matched = nodes.find((node) => node.name === segment);
|
|
102
|
+
if (!matched) return void 0;
|
|
103
|
+
titles.push(reactNodeToPlainText(matched.title || matched.name));
|
|
104
|
+
nodes = Array.isArray(matched.children) ? matched.children : void 0;
|
|
105
|
+
}
|
|
106
|
+
return titles.map(ctxT).join("/");
|
|
107
|
+
}
|
|
108
|
+
__name(resolveTitlesByPath, "resolveTitlesByPath");
|
|
94
109
|
function buildLabelMap(nodes, ctxT, converters) {
|
|
95
110
|
const map = /* @__PURE__ */ new Map();
|
|
96
111
|
function walk(items = [], parentTitles = []) {
|
|
@@ -112,6 +127,34 @@ function buildLabelMap(nodes, ctxT, converters) {
|
|
|
112
127
|
return map;
|
|
113
128
|
}
|
|
114
129
|
__name(buildLabelMap, "buildLabelMap");
|
|
130
|
+
function collectReferencePaths(value, regExp, parseValueToPath) {
|
|
131
|
+
const re = new RegExp(regExp.source, regExp.flags.includes("g") ? regExp.flags : `${regExp.flags}g`);
|
|
132
|
+
const paths = [];
|
|
133
|
+
for (const matched of value.match(re) ?? []) {
|
|
134
|
+
const path = parseValueToPath(matched);
|
|
135
|
+
if (path && path.length) {
|
|
136
|
+
paths.push(path);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return paths;
|
|
140
|
+
}
|
|
141
|
+
__name(collectReferencePaths, "collectReferencePaths");
|
|
142
|
+
async function preloadReferencePath(path, roots) {
|
|
143
|
+
let nodes = roots;
|
|
144
|
+
let didLoad = false;
|
|
145
|
+
for (const segment of path) {
|
|
146
|
+
if (!nodes) break;
|
|
147
|
+
const matched = nodes.find((node) => node.name === segment);
|
|
148
|
+
if (!matched) break;
|
|
149
|
+
if (typeof matched.children === "function") {
|
|
150
|
+
matched.children = await (0, import_utils.loadMetaTreeChildren)(matched);
|
|
151
|
+
didLoad = true;
|
|
152
|
+
}
|
|
153
|
+
nodes = Array.isArray(matched.children) ? matched.children : void 0;
|
|
154
|
+
}
|
|
155
|
+
return didLoad;
|
|
156
|
+
}
|
|
157
|
+
__name(preloadReferencePath, "preloadReferencePath");
|
|
115
158
|
function pasteHTML(container, html, indexes) {
|
|
116
159
|
var _a;
|
|
117
160
|
const selection = (_a = window.getSelection) == null ? void 0 : _a.call(window);
|
|
@@ -213,21 +256,64 @@ function getCurrentRange(element) {
|
|
|
213
256
|
}
|
|
214
257
|
__name(getCurrentRange, "getCurrentRange");
|
|
215
258
|
const VariableHybridInputComponent = /* @__PURE__ */ __name((props) => {
|
|
259
|
+
var _a;
|
|
216
260
|
const { addonBefore, className, converters, disabled, metaTree, onChange, placeholder, style } = props;
|
|
217
261
|
const { token } = import_antd.theme.useToken();
|
|
218
262
|
const ctx = (0, import_FlowContextProvider.useFlowContext)();
|
|
219
263
|
const { resolvedMetaTree } = (0, import_useResolvedMetaTree.useResolvedMetaTree)(metaTree);
|
|
264
|
+
const formItemStatus = (_a = (0, import_react.useContext)(import_context.FormItemInputContext)) == null ? void 0 : _a.status;
|
|
265
|
+
const effectiveStatus = props.status ?? formItemStatus;
|
|
220
266
|
const inputRef = (0, import_react.useRef)(null);
|
|
221
267
|
const [isComposing, setIsComposing] = (0, import_react.useState)(false);
|
|
222
268
|
const [changed, setChanged] = (0, import_react.useState)(false);
|
|
223
269
|
const [range, setRange] = (0, import_react.useState)([-1, 0, -1, 0]);
|
|
224
270
|
const value = typeof props.value === "string" ? props.value : props.value == null ? "" : String(props.value);
|
|
225
271
|
const variableRegExp = (converters == null ? void 0 : converters.variableRegExp) ?? DEFAULT_VARIABLE_REGEXP;
|
|
272
|
+
const parseValueToPath = (converters == null ? void 0 : converters.parseValueToPath) ?? import_utils.parseValueToPath;
|
|
273
|
+
const [loadedFlag, setLoadedFlag] = (0, import_react.useState)(0);
|
|
274
|
+
(0, import_react.useEffect)(() => {
|
|
275
|
+
if (!value || !Array.isArray(resolvedMetaTree) || !resolvedMetaTree.length) {
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
const paths = collectReferencePaths(value, variableRegExp, parseValueToPath);
|
|
279
|
+
if (!paths.length) {
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
let cancelled = false;
|
|
283
|
+
const run = /* @__PURE__ */ __name(async () => {
|
|
284
|
+
let didLoad = false;
|
|
285
|
+
for (const path of paths) {
|
|
286
|
+
const loaded = await preloadReferencePath(path, resolvedMetaTree);
|
|
287
|
+
if (cancelled) return;
|
|
288
|
+
didLoad = didLoad || loaded;
|
|
289
|
+
}
|
|
290
|
+
if (didLoad && !cancelled) {
|
|
291
|
+
setLoadedFlag((prev) => prev + 1);
|
|
292
|
+
}
|
|
293
|
+
}, "run");
|
|
294
|
+
run();
|
|
295
|
+
return () => {
|
|
296
|
+
cancelled = true;
|
|
297
|
+
};
|
|
298
|
+
}, [value, resolvedMetaTree, variableRegExp, parseValueToPath]);
|
|
226
299
|
const labelMap = (0, import_react.useMemo)(
|
|
227
300
|
() => buildLabelMap(resolvedMetaTree, ctx.t, converters),
|
|
228
|
-
|
|
301
|
+
// `loadedFlag` is read so the map recomputes after a lazy level resolves.
|
|
302
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
303
|
+
[resolvedMetaTree, ctx, converters, loadedFlag]
|
|
304
|
+
);
|
|
305
|
+
const resolveLabel = (0, import_react.useCallback)(
|
|
306
|
+
(matched) => {
|
|
307
|
+
const mapped = labelMap.get(normalizeVariableKey(matched));
|
|
308
|
+
if (mapped) return mapped;
|
|
309
|
+
const path = parseValueToPath(matched);
|
|
310
|
+
return resolveTitlesByPath(resolvedMetaTree, path, ctx.t);
|
|
311
|
+
},
|
|
312
|
+
// `loadedFlag` is read so a resolved lazy level re-creates this callback and re-renders the tags. `ctx` carries the translation fn.
|
|
313
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
314
|
+
[labelMap, parseValueToPath, resolvedMetaTree, ctx, loadedFlag]
|
|
229
315
|
);
|
|
230
|
-
const [html, setHtml] = (0, import_react.useState)(() => renderHTML(value,
|
|
316
|
+
const [html, setHtml] = (0, import_react.useState)(() => renderHTML(value, variableRegExp, resolveLabel));
|
|
231
317
|
const emitChange = (0, import_react.useCallback)(
|
|
232
318
|
(target) => {
|
|
233
319
|
onChange == null ? void 0 : onChange(getDomValue(target).trim());
|
|
@@ -235,20 +321,20 @@ const VariableHybridInputComponent = /* @__PURE__ */ __name((props) => {
|
|
|
235
321
|
[onChange]
|
|
236
322
|
);
|
|
237
323
|
(0, import_react.useEffect)(() => {
|
|
238
|
-
setHtml(renderHTML(value,
|
|
324
|
+
setHtml(renderHTML(value, variableRegExp, resolveLabel));
|
|
239
325
|
if (!changed) {
|
|
240
326
|
setRange([-1, 0, -1, 0]);
|
|
241
327
|
}
|
|
242
|
-
}, [value,
|
|
328
|
+
}, [value, resolveLabel]);
|
|
243
329
|
(0, import_react.useEffect)(() => {
|
|
244
|
-
var
|
|
330
|
+
var _a2;
|
|
245
331
|
const element = inputRef.current;
|
|
246
332
|
if (!element) return;
|
|
247
333
|
if (document.activeElement !== element) return;
|
|
248
334
|
const nextRange = new Range();
|
|
249
335
|
if (changed) {
|
|
250
336
|
if (range.join() === "-1,0,-1,0") return;
|
|
251
|
-
const selection = (
|
|
337
|
+
const selection = (_a2 = window.getSelection) == null ? void 0 : _a2.call(window);
|
|
252
338
|
if (!selection) return;
|
|
253
339
|
try {
|
|
254
340
|
const children = Array.from(element.childNodes);
|
|
@@ -457,6 +543,34 @@ const VariableHybridInputComponent = /* @__PURE__ */ __name((props) => {
|
|
|
457
543
|
border-color: ${token.colorBorder};
|
|
458
544
|
}
|
|
459
545
|
}
|
|
546
|
+
|
|
547
|
+
&.is-error {
|
|
548
|
+
border-color: ${token.colorError};
|
|
549
|
+
|
|
550
|
+
&:hover {
|
|
551
|
+
border-color: ${token.colorErrorBorderHover};
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
&:focus,
|
|
555
|
+
&:focus-visible {
|
|
556
|
+
border-color: ${token.colorError};
|
|
557
|
+
box-shadow: 0 0 0 ${token.controlOutlineWidth}px ${token.colorErrorOutline};
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
&.is-warning {
|
|
562
|
+
border-color: ${token.colorWarning};
|
|
563
|
+
|
|
564
|
+
&:hover {
|
|
565
|
+
border-color: ${token.colorWarningBorderHover};
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
&:focus,
|
|
569
|
+
&:focus-visible {
|
|
570
|
+
border-color: ${token.colorWarning};
|
|
571
|
+
box-shadow: 0 0 0 ${token.controlOutlineWidth}px ${token.colorWarningOutline};
|
|
572
|
+
}
|
|
573
|
+
}
|
|
460
574
|
`;
|
|
461
575
|
}, [token, addonBefore]);
|
|
462
576
|
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(
|
|
@@ -466,7 +580,9 @@ const VariableHybridInputComponent = /* @__PURE__ */ __name((props) => {
|
|
|
466
580
|
role: "textbox",
|
|
467
581
|
"aria-label": "textbox",
|
|
468
582
|
className: (0, import_css.cx)(editorClassName, {
|
|
469
|
-
"is-disabled": disabled
|
|
583
|
+
"is-disabled": disabled,
|
|
584
|
+
"is-error": effectiveStatus === "error",
|
|
585
|
+
"is-warning": effectiveStatus === "warning"
|
|
470
586
|
}),
|
|
471
587
|
contentEditable: !disabled,
|
|
472
588
|
"data-placeholder": placeholder,
|
|
@@ -483,10 +599,10 @@ const VariableHybridInputComponent = /* @__PURE__ */ __name((props) => {
|
|
|
483
599
|
{
|
|
484
600
|
metaTree,
|
|
485
601
|
disabled,
|
|
486
|
-
parseValueToPath
|
|
602
|
+
parseValueToPath,
|
|
487
603
|
formatPathToValue: (item) => {
|
|
488
|
-
var
|
|
489
|
-
return ((
|
|
604
|
+
var _a2;
|
|
605
|
+
return ((_a2 = converters == null ? void 0 : converters.formatPathToValue) == null ? void 0 : _a2.call(converters, item)) || (0, import_utils.formatPathToValue)(item);
|
|
490
606
|
},
|
|
491
607
|
onChange: handleSelectorChange
|
|
492
608
|
}
|
|
@@ -188,7 +188,7 @@ const VariableInputComponent = /* @__PURE__ */ __name(({
|
|
|
188
188
|
}
|
|
189
189
|
}, "restoreFromValue");
|
|
190
190
|
restoreFromValue();
|
|
191
|
-
}, [resolvedMetaTree, innerValue, resolvePathFromValue, currentMetaTreeNode]);
|
|
191
|
+
}, [resolvedMetaTree, innerValue, resolvePathFromValue, currentMetaTreeNode, value]);
|
|
192
192
|
const ValueComponent = (0, import_react.useMemo)(() => {
|
|
193
193
|
const Component = renderInputComponent == null ? void 0 : renderInputComponent(resolvedMetaTreeNode);
|
|
194
194
|
const CustomComponent = resolvedMetaTreeNode == null ? void 0 : resolvedMetaTreeNode.render;
|
|
@@ -325,6 +325,7 @@ const VariableInputComponent = /* @__PURE__ */ __name(({
|
|
|
325
325
|
{
|
|
326
326
|
metaTree: resolvedMetaTree,
|
|
327
327
|
value: innerValue,
|
|
328
|
+
active: (0, import_utils.isVariableValue)(innerValue),
|
|
328
329
|
onChange: handleVariableSelect,
|
|
329
330
|
parseValueToPath: resolvePathFromValue,
|
|
330
331
|
formatPathToValue: resolveValueFromPath,
|
|
@@ -13,12 +13,30 @@ export interface FlowContextSelectorProps extends Omit<CascaderProps<ContextSele
|
|
|
13
13
|
value?: string;
|
|
14
14
|
onChange?: (value: string, metaTreeNode?: MetaTreeNode) => void;
|
|
15
15
|
children?: CascaderProps<ContextSelectorItem>['children'];
|
|
16
|
+
/**
|
|
17
|
+
* Controls whether the default `x` trigger button is rendered as active
|
|
18
|
+
* (`type="primary"`). When omitted, the selector falls back to its parsed
|
|
19
|
+
* `value` path (`true` iff a valid variable path is currently selected).
|
|
20
|
+
*
|
|
21
|
+
* Use this when callers intentionally feed synthetic paths such as
|
|
22
|
+
* `['constant']` / `['null']` into the cascader to keep menu state aligned,
|
|
23
|
+
* but only want real variable references to show the blue active button.
|
|
24
|
+
*/
|
|
25
|
+
active?: boolean;
|
|
16
26
|
metaTree?: MetaTreeNode[] | (() => MetaTreeNode[] | Promise<MetaTreeNode[]>);
|
|
17
27
|
parseValueToPath?: (value: string) => string[] | undefined;
|
|
18
28
|
formatPathToValue?: (item: MetaTreeNode) => string;
|
|
19
29
|
open?: boolean;
|
|
20
30
|
onlyLeafSelectable?: boolean;
|
|
21
31
|
ignoreFieldNames?: string[];
|
|
32
|
+
/**
|
|
33
|
+
* Footer rendered at the bottom of the dropdown. Defaults to a muted
|
|
34
|
+
* "Double click to choose entire object" hint when non-leaf selection is
|
|
35
|
+
* allowed (`onlyLeafSelectable` is false) — since double-clicking a non-leaf
|
|
36
|
+
* node selects the whole object. Pass an explicit node to override, or `null`
|
|
37
|
+
* to hide it.
|
|
38
|
+
*/
|
|
39
|
+
dropdownFooter?: React.ReactNode;
|
|
22
40
|
}
|
|
23
41
|
export interface ContextSelectorItem {
|
|
24
42
|
label: React.ReactNode;
|
package/lib/flowContext.d.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
9
|
import { ISchema } from '@formily/json-schema';
|
|
10
|
-
import { APIClient, RequestOptions } from '@nocobase/sdk';
|
|
10
|
+
import type { APIClient, RequestOptions } from '@nocobase/sdk';
|
|
11
11
|
import type { Router } from '@remix-run/router';
|
|
12
12
|
import { MessageInstance } from 'antd/es/message/interface';
|
|
13
13
|
import type { HookAPI } from 'antd/es/modal/useModal';
|
package/lib/flowContext.js
CHANGED
|
@@ -75,6 +75,7 @@ var import_utils = require("./utils");
|
|
|
75
75
|
var import_exceptions = require("./utils/exceptions");
|
|
76
76
|
var import_params_resolvers = require("./utils/params-resolvers");
|
|
77
77
|
var import_serverContextParams = require("./utils/serverContextParams");
|
|
78
|
+
var import_dirtyAwareApiClient = require("./utils/dirtyAwareApiClient");
|
|
78
79
|
var import_variablesParams = require("./utils/variablesParams");
|
|
79
80
|
var import_registry = require("./runjs-context/registry");
|
|
80
81
|
var import_createEphemeralContext = require("./utils/createEphemeralContext");
|
|
@@ -1899,15 +1900,16 @@ const _FlowContext = class _FlowContext {
|
|
|
1899
1900
|
const options = this._props[key];
|
|
1900
1901
|
if (!options) return void 0;
|
|
1901
1902
|
if ("value" in options) {
|
|
1902
|
-
return options.value;
|
|
1903
|
+
return key === "api" ? (0, import_dirtyAwareApiClient.getDirtyAwareApiClient)(options.value, currentContext) : options.value;
|
|
1903
1904
|
}
|
|
1904
1905
|
if (options.get) {
|
|
1905
1906
|
if (options.cache === false) {
|
|
1906
|
-
|
|
1907
|
+
const value = options.get(currentContext);
|
|
1908
|
+
return key === "api" ? (0, import_dirtyAwareApiClient.getDirtyAwareApiClient)(value, currentContext) : value;
|
|
1907
1909
|
}
|
|
1908
1910
|
const cacheKey = options.observable ? "_observableCache" : "_cache";
|
|
1909
1911
|
if (key in this[cacheKey]) {
|
|
1910
|
-
return this[cacheKey][key];
|
|
1912
|
+
return key === "api" ? (0, import_dirtyAwareApiClient.getDirtyAwareApiClient)(this[cacheKey][key], currentContext) : this[cacheKey][key];
|
|
1911
1913
|
}
|
|
1912
1914
|
if (this._pending[key]) return this._pending[key];
|
|
1913
1915
|
const result = options.get(this.createProxy());
|
|
@@ -1917,7 +1919,7 @@ const _FlowContext = class _FlowContext {
|
|
|
1917
1919
|
(v) => {
|
|
1918
1920
|
this[cacheKey][key] = v;
|
|
1919
1921
|
delete this._pending[key];
|
|
1920
|
-
return v;
|
|
1922
|
+
return key === "api" ? (0, import_dirtyAwareApiClient.getDirtyAwareApiClient)(v, currentContext) : v;
|
|
1921
1923
|
},
|
|
1922
1924
|
(err) => {
|
|
1923
1925
|
delete this._pending[key];
|
|
@@ -1927,7 +1929,7 @@ const _FlowContext = class _FlowContext {
|
|
|
1927
1929
|
return this._pending[key];
|
|
1928
1930
|
}
|
|
1929
1931
|
this[cacheKey][key] = result;
|
|
1930
|
-
return result;
|
|
1932
|
+
return key === "api" ? (0, import_dirtyAwareApiClient.getDirtyAwareApiClient)(result, currentContext) : result;
|
|
1931
1933
|
}
|
|
1932
1934
|
return void 0;
|
|
1933
1935
|
}
|
|
@@ -2251,7 +2253,7 @@ const _BaseFlowEngineContext = class _BaseFlowEngineContext extends FlowContext
|
|
|
2251
2253
|
this.defineMethod("getModel", (modelName, searchInPreviousEngines) => {
|
|
2252
2254
|
return this.engine.getModel(modelName, searchInPreviousEngines);
|
|
2253
2255
|
});
|
|
2254
|
-
this.defineMethod("request", (options)
|
|
2256
|
+
this.defineMethod("request", function(options) {
|
|
2255
2257
|
const app = this.app;
|
|
2256
2258
|
if (typeof (options == null ? void 0 : options.url) === "string" && shouldBypassApiClient(options.url, app)) {
|
|
2257
2259
|
return import_axios.default.request(options);
|
|
@@ -2294,6 +2296,36 @@ const _BaseFlowModelContext = class _BaseFlowModelContext extends BaseFlowEngine
|
|
|
2294
2296
|
};
|
|
2295
2297
|
__name(_BaseFlowModelContext, "BaseFlowModelContext");
|
|
2296
2298
|
let BaseFlowModelContext = _BaseFlowModelContext;
|
|
2299
|
+
const OPEN_VIEW_INHERITED_INPUT_ARG_KEYS = [
|
|
2300
|
+
"dataSourceKey",
|
|
2301
|
+
"collectionName",
|
|
2302
|
+
"associationName",
|
|
2303
|
+
"filterByTk",
|
|
2304
|
+
"sourceId",
|
|
2305
|
+
"tabUid"
|
|
2306
|
+
];
|
|
2307
|
+
function pickDefinedKeys(source, keys) {
|
|
2308
|
+
const res = {};
|
|
2309
|
+
for (const key of keys) {
|
|
2310
|
+
if (typeof (source == null ? void 0 : source[key]) !== "undefined") {
|
|
2311
|
+
res[key] = source[key];
|
|
2312
|
+
}
|
|
2313
|
+
}
|
|
2314
|
+
return res;
|
|
2315
|
+
}
|
|
2316
|
+
__name(pickDefinedKeys, "pickDefinedKeys");
|
|
2317
|
+
function pickDefinedOpenViewInputArgs(source) {
|
|
2318
|
+
return pickDefinedKeys(source, OPEN_VIEW_INHERITED_INPUT_ARG_KEYS);
|
|
2319
|
+
}
|
|
2320
|
+
__name(pickDefinedOpenViewInputArgs, "pickDefinedOpenViewInputArgs");
|
|
2321
|
+
function applyDefinedDefaults(target, defaults) {
|
|
2322
|
+
for (const [key, value] of Object.entries(defaults)) {
|
|
2323
|
+
if (typeof target[key] === "undefined") {
|
|
2324
|
+
target[key] = value;
|
|
2325
|
+
}
|
|
2326
|
+
}
|
|
2327
|
+
}
|
|
2328
|
+
__name(applyDefinedDefaults, "applyDefinedDefaults");
|
|
2297
2329
|
const _FlowEngineContext = class _FlowEngineContext extends BaseFlowEngineContext {
|
|
2298
2330
|
// public dataSourceManager: DataSourceManager;
|
|
2299
2331
|
constructor(engine) {
|
|
@@ -2525,8 +2557,16 @@ const _FlowEngineContext = class _FlowEngineContext extends BaseFlowEngineContex
|
|
|
2525
2557
|
});
|
|
2526
2558
|
this.defineProperty("role", {
|
|
2527
2559
|
get: /* @__PURE__ */ __name(() => {
|
|
2528
|
-
var _a, _b;
|
|
2529
|
-
|
|
2560
|
+
var _a, _b, _c;
|
|
2561
|
+
const currentRole = (_b = (_a = this.api) == null ? void 0 : _a.auth) == null ? void 0 : _b.role;
|
|
2562
|
+
if (currentRole !== "__union__") {
|
|
2563
|
+
return currentRole;
|
|
2564
|
+
}
|
|
2565
|
+
const roles = (_c = this.user) == null ? void 0 : _c.roles;
|
|
2566
|
+
if (!Array.isArray(roles)) {
|
|
2567
|
+
return [];
|
|
2568
|
+
}
|
|
2569
|
+
return roles.map((role) => role == null ? void 0 : role.name).filter((name) => !!name);
|
|
2530
2570
|
}, "get"),
|
|
2531
2571
|
cache: false,
|
|
2532
2572
|
// 注意:使用惰性 meta 工厂,避免在 i18n 尚未注入时提前求值导致无法翻译
|
|
@@ -2680,7 +2720,17 @@ const _FlowEngineContext = class _FlowEngineContext extends BaseFlowEngineContex
|
|
|
2680
2720
|
doc = {};
|
|
2681
2721
|
}
|
|
2682
2722
|
const deprecatedCtx = createRunJSDeprecationProxy(runCtx, { doc });
|
|
2683
|
-
const
|
|
2723
|
+
const browserGlobals = {};
|
|
2724
|
+
if (typeof window !== "undefined") {
|
|
2725
|
+
browserGlobals.window = window;
|
|
2726
|
+
if (typeof navigator !== "undefined") {
|
|
2727
|
+
browserGlobals.navigator = navigator;
|
|
2728
|
+
}
|
|
2729
|
+
}
|
|
2730
|
+
if (typeof document !== "undefined") {
|
|
2731
|
+
browserGlobals.document = document;
|
|
2732
|
+
}
|
|
2733
|
+
const globals = { ctx: deprecatedCtx, ...browserGlobals, ...(options == null ? void 0 : options.globals) || {} };
|
|
2684
2734
|
const { timeoutMs } = options || {};
|
|
2685
2735
|
return new import_JSRunner.JSRunner({ globals, timeoutMs });
|
|
2686
2736
|
});
|
|
@@ -2791,23 +2841,19 @@ const _FlowModelContext = class _FlowModelContext extends BaseFlowModelContext {
|
|
|
2791
2841
|
}
|
|
2792
2842
|
});
|
|
2793
2843
|
this.defineMethod("openView", async function(uid, options) {
|
|
2794
|
-
var _a, _b, _c, _d
|
|
2795
|
-
const
|
|
2844
|
+
var _a, _b, _c, _d;
|
|
2845
|
+
const inheritedInputArgs = {
|
|
2846
|
+
...typeof ((_a = this.model) == null ? void 0 : _a["getInputArgs"]) === "function" ? pickDefinedOpenViewInputArgs(this.model["getInputArgs"]()) : {},
|
|
2847
|
+
...pickDefinedOpenViewInputArgs(this.inputArgs)
|
|
2848
|
+
};
|
|
2849
|
+
const opts = { ...options || {} };
|
|
2850
|
+
applyDefinedDefaults(opts, inheritedInputArgs);
|
|
2796
2851
|
if (opts.defineProperties || opts.defineMethods) {
|
|
2797
2852
|
opts.navigation = false;
|
|
2798
2853
|
}
|
|
2799
2854
|
let model2 = null;
|
|
2800
2855
|
model2 = await this.engine.loadModel({ uid });
|
|
2801
2856
|
if (!model2) {
|
|
2802
|
-
const pickDefined = /* @__PURE__ */ __name((src, keys) => {
|
|
2803
|
-
const res = {};
|
|
2804
|
-
for (const k of keys) {
|
|
2805
|
-
if (typeof (src == null ? void 0 : src[k]) !== "undefined") {
|
|
2806
|
-
res[k] = src[k];
|
|
2807
|
-
}
|
|
2808
|
-
}
|
|
2809
|
-
return res;
|
|
2810
|
-
}, "pickDefined");
|
|
2811
2857
|
model2 = this.engine.createModel({
|
|
2812
2858
|
uid,
|
|
2813
2859
|
// 注意: 新建的 model 应该使用 ${parentModel.uid}-xxx 形式的 uid
|
|
@@ -2819,7 +2865,7 @@ const _FlowModelContext = class _FlowModelContext extends BaseFlowModelContext {
|
|
|
2819
2865
|
popupSettings: {
|
|
2820
2866
|
openView: {
|
|
2821
2867
|
// 仅在创建时持久化一份默认配置;运行时以本次 opts 为准,避免多个 opener 互相覆盖。
|
|
2822
|
-
...
|
|
2868
|
+
...pickDefinedKeys(opts, ["dataSourceKey", "collectionName", "associationName", "mode", "size"])
|
|
2823
2869
|
}
|
|
2824
2870
|
}
|
|
2825
2871
|
}
|
|
@@ -2827,12 +2873,10 @@ const _FlowModelContext = class _FlowModelContext extends BaseFlowModelContext {
|
|
|
2827
2873
|
await model2.save();
|
|
2828
2874
|
}
|
|
2829
2875
|
model2.setParent(this.model);
|
|
2830
|
-
const viewUid = (opts == null ? void 0 : opts.routeViewUid) ?? (opts == null ? void 0 : opts.viewUid) ?? (((
|
|
2876
|
+
const viewUid = (opts == null ? void 0 : opts.routeViewUid) ?? (opts == null ? void 0 : opts.viewUid) ?? (((_c = (_b = model2.stepParams) == null ? void 0 : _b.popupSettings) == null ? void 0 : _c.openView) ? model2.uid : this.model.uid);
|
|
2831
2877
|
const parentView = this.view;
|
|
2832
2878
|
const pendingType = (opts == null ? void 0 : opts.isMobileLayout) ? "embed" : (opts == null ? void 0 : opts.mode) || "drawer";
|
|
2833
2879
|
const pendingInputArgs = { ...opts, viewUid, navigation: opts.navigation };
|
|
2834
|
-
pendingInputArgs.filterByTk = pendingInputArgs.filterByTk || ((_c = this.inputArgs) == null ? void 0 : _c.filterByTk);
|
|
2835
|
-
pendingInputArgs.sourceId = pendingInputArgs.sourceId || ((_d = this.inputArgs) == null ? void 0 : _d.sourceId);
|
|
2836
2880
|
const pendingView = {
|
|
2837
2881
|
type: pendingType,
|
|
2838
2882
|
inputArgs: pendingInputArgs,
|
|
@@ -2841,7 +2885,7 @@ const _FlowModelContext = class _FlowModelContext extends BaseFlowModelContext {
|
|
|
2841
2885
|
engineCtx: this.engine.context
|
|
2842
2886
|
};
|
|
2843
2887
|
model2.context.defineProperty("view", { value: pendingView });
|
|
2844
|
-
const popupFlow = (
|
|
2888
|
+
const popupFlow = (_d = model2.getFlow) == null ? void 0 : _d.call(model2, "popupSettings");
|
|
2845
2889
|
const on = popupFlow == null ? void 0 : popupFlow.on;
|
|
2846
2890
|
let openEventName = "click";
|
|
2847
2891
|
if (typeof on === "string" && on) {
|
|
@@ -2849,17 +2893,10 @@ const _FlowModelContext = class _FlowModelContext extends BaseFlowModelContext {
|
|
|
2849
2893
|
} else if (on && typeof on === "object" && typeof on.eventName === "string" && on.eventName) {
|
|
2850
2894
|
openEventName = on.eventName;
|
|
2851
2895
|
}
|
|
2852
|
-
await model2.dispatchEvent(
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
// ...this.model?.['getInputArgs']?.(), // 避免部分关系字段信息丢失, 仿照 ClickableCollectionField 做法
|
|
2857
|
-
...opts
|
|
2858
|
-
},
|
|
2859
|
-
{
|
|
2860
|
-
debounce: true
|
|
2861
|
-
}
|
|
2862
|
-
);
|
|
2896
|
+
await model2.dispatchEvent(openEventName, {
|
|
2897
|
+
// navigation: false, // TODO: 路由模式有bug,不支持多层同样viewId的弹窗,因此这里默认先用false
|
|
2898
|
+
...opts
|
|
2899
|
+
});
|
|
2863
2900
|
});
|
|
2864
2901
|
this.defineMethod("getEvents", function() {
|
|
2865
2902
|
return this.model.getEvents();
|
|
@@ -3475,6 +3512,20 @@ const _FlowRunJSContext = class _FlowRunJSContext extends FlowContext {
|
|
|
3475
3512
|
ReactDOMShim.__nbRunjsInternalShim = true;
|
|
3476
3513
|
this.defineProperty("ReactDOM", { value: ReactDOMShim });
|
|
3477
3514
|
(0, import_runjsLibs.setupRunJSLibs)(this);
|
|
3515
|
+
this.defineMethod("openView", async function(uid, options) {
|
|
3516
|
+
const delegateOpenView = delegate.openView;
|
|
3517
|
+
if (typeof delegateOpenView !== "function") {
|
|
3518
|
+
throw new Error("ctx.openView is not available in current context.");
|
|
3519
|
+
}
|
|
3520
|
+
const routeState = (0, import_utils.createOpenViewRouteState)(options);
|
|
3521
|
+
if (!routeState) {
|
|
3522
|
+
return delegateOpenView(uid, options);
|
|
3523
|
+
}
|
|
3524
|
+
return delegateOpenView(uid, {
|
|
3525
|
+
...options || {},
|
|
3526
|
+
[import_utils.RUNJS_OPEN_VIEW_ROUTE_STATE]: routeState
|
|
3527
|
+
});
|
|
3528
|
+
});
|
|
3478
3529
|
this.defineMethod(
|
|
3479
3530
|
"render",
|
|
3480
3531
|
function(vnode, container) {
|
package/lib/flowI18n.js
CHANGED
|
@@ -81,7 +81,7 @@ const _FlowI18n = class _FlowI18n {
|
|
|
81
81
|
* @private
|
|
82
82
|
*/
|
|
83
83
|
isTemplate(str) {
|
|
84
|
-
return /\{\{\s*t\s*\(\s*["'`]
|
|
84
|
+
return /\{\{\s*t\s*\(\s*(["'`])(?:\\.|(?!\1).)*?\1\s*(?:,\s*.*?)?\s*\)\s*\}\}/.test(str);
|
|
85
85
|
}
|
|
86
86
|
/**
|
|
87
87
|
* 编译模板字符串
|
|
@@ -89,8 +89,8 @@ const _FlowI18n = class _FlowI18n {
|
|
|
89
89
|
*/
|
|
90
90
|
compileTemplate(template) {
|
|
91
91
|
return template.replace(
|
|
92
|
-
/\{\{\s*t\s*\(\s*["'`](
|
|
93
|
-
(match, key, optionsStr) => {
|
|
92
|
+
/\{\{\s*t\s*\(\s*(["'`])((?:\\.|(?!\1).)*?)\1\s*(?:,\s*((?:[^{}]|\{[^}]*\})*?))?\s*\)\s*\}\}/g,
|
|
93
|
+
(match, _quote, key, optionsStr) => {
|
|
94
94
|
try {
|
|
95
95
|
let templateOptions = {};
|
|
96
96
|
if (optionsStr) {
|
package/lib/flowSettings.d.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import React from 'react';
|
|
10
10
|
import { FlowEngine } from '.';
|
|
11
11
|
import type { FlowModel } from './models';
|
|
12
|
-
import { StepSettingsDialogProps, ToolbarItemConfig } from './types';
|
|
12
|
+
import { DynamicFlowSource, DynamicFlowSourceProvider, StepSettingsDialogProps, ToolbarItemConfig } from './types';
|
|
13
13
|
/**
|
|
14
14
|
* 打开流程设置的参数接口
|
|
15
15
|
*/
|
|
@@ -93,6 +93,7 @@ export declare class FlowSettings {
|
|
|
93
93
|
enabled: boolean;
|
|
94
94
|
private engine;
|
|
95
95
|
toolbarItems: ToolbarItemConfig[];
|
|
96
|
+
private dynamicFlowSourceProviders;
|
|
96
97
|
constructor(engine: FlowEngine);
|
|
97
98
|
on(event: 'beforeOpen', callback: (...args: any[]) => void): void;
|
|
98
99
|
off(event: 'beforeOpen', callback: (...args: any[]) => void): void;
|
|
@@ -206,6 +207,9 @@ export declare class FlowSettings {
|
|
|
206
207
|
* @returns {ToolbarItemConfig[]} 所有项目配置
|
|
207
208
|
*/
|
|
208
209
|
getToolbarItems(): ToolbarItemConfig[];
|
|
210
|
+
registerDynamicFlowSourceProvider(provider: DynamicFlowSourceProvider): () => void;
|
|
211
|
+
hasDynamicFlowSourceProvider(model: FlowModel): boolean;
|
|
212
|
+
getDynamicFlowSources(model: FlowModel): Promise<DynamicFlowSource[]>;
|
|
209
213
|
/**
|
|
210
214
|
* 清空所有工具栏项目
|
|
211
215
|
* @example
|
package/lib/flowSettings.js
CHANGED
|
@@ -78,6 +78,7 @@ const _FlowSettings = class _FlowSettings {
|
|
|
78
78
|
__privateAdd(this, _forceEnabled, false);
|
|
79
79
|
// 强制启用状态,主要用于设计模式下的强制启用
|
|
80
80
|
__publicField(this, "toolbarItems", []);
|
|
81
|
+
__publicField(this, "dynamicFlowSourceProviders", []);
|
|
81
82
|
__privateAdd(this, _emitter, new import_emitter.Emitter());
|
|
82
83
|
this.engine = engine;
|
|
83
84
|
this.enabled = false;
|
|
@@ -369,6 +370,75 @@ const _FlowSettings = class _FlowSettings {
|
|
|
369
370
|
getToolbarItems() {
|
|
370
371
|
return [...this.toolbarItems];
|
|
371
372
|
}
|
|
373
|
+
registerDynamicFlowSourceProvider(provider) {
|
|
374
|
+
const existingIndex = this.dynamicFlowSourceProviders.findIndex((item) => item.key === provider.key);
|
|
375
|
+
if (existingIndex !== -1) {
|
|
376
|
+
console.warn(
|
|
377
|
+
`FlowSettings: Dynamic flow source provider with key '${provider.key}' already exists and will be replaced.`
|
|
378
|
+
);
|
|
379
|
+
this.dynamicFlowSourceProviders[existingIndex] = provider;
|
|
380
|
+
} else {
|
|
381
|
+
this.dynamicFlowSourceProviders.push(provider);
|
|
382
|
+
}
|
|
383
|
+
this.dynamicFlowSourceProviders.sort((a, b) => (a.sort || 0) - (b.sort || 0));
|
|
384
|
+
return () => {
|
|
385
|
+
const index = this.dynamicFlowSourceProviders.indexOf(provider);
|
|
386
|
+
if (index !== -1) {
|
|
387
|
+
this.dynamicFlowSourceProviders.splice(index, 1);
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
hasDynamicFlowSourceProvider(model) {
|
|
392
|
+
return this.dynamicFlowSourceProviders.some((provider) => {
|
|
393
|
+
try {
|
|
394
|
+
return provider.visible ? provider.visible(model) : true;
|
|
395
|
+
} catch (error) {
|
|
396
|
+
console.warn(`FlowSettings: Dynamic flow source provider '${provider.key}' visibility check failed.`, error);
|
|
397
|
+
return false;
|
|
398
|
+
}
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
async getDynamicFlowSources(model) {
|
|
402
|
+
const t = (0, import_utils.getT)(model);
|
|
403
|
+
const selfSource = {
|
|
404
|
+
key: "self",
|
|
405
|
+
label: t("Current block"),
|
|
406
|
+
model,
|
|
407
|
+
sort: -1e3
|
|
408
|
+
};
|
|
409
|
+
const sources = [];
|
|
410
|
+
const seenKeys = /* @__PURE__ */ new Set(["self"]);
|
|
411
|
+
const seenModelUids = /* @__PURE__ */ new Set([model.uid]);
|
|
412
|
+
for (const provider of this.dynamicFlowSourceProviders) {
|
|
413
|
+
try {
|
|
414
|
+
if (provider.visible && !provider.visible(model)) {
|
|
415
|
+
continue;
|
|
416
|
+
}
|
|
417
|
+
const providerSources = await provider.getSources(model);
|
|
418
|
+
for (const source of providerSources || []) {
|
|
419
|
+
if (!(source == null ? void 0 : source.key) || !source.model) {
|
|
420
|
+
continue;
|
|
421
|
+
}
|
|
422
|
+
const key = String(source.key);
|
|
423
|
+
const uid = source.model.uid;
|
|
424
|
+
if (seenKeys.has(key) || seenModelUids.has(uid)) {
|
|
425
|
+
continue;
|
|
426
|
+
}
|
|
427
|
+
seenKeys.add(key);
|
|
428
|
+
seenModelUids.add(uid);
|
|
429
|
+
sources.push({
|
|
430
|
+
...source,
|
|
431
|
+
key,
|
|
432
|
+
label: source.label || key,
|
|
433
|
+
sort: source.sort || 0
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
} catch (error) {
|
|
437
|
+
console.warn(`FlowSettings: Dynamic flow source provider '${provider.key}' failed.`, error);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
return [selfSource, ...sources.sort((a, b) => (a.sort || 0) - (b.sort || 0))];
|
|
441
|
+
}
|
|
372
442
|
/**
|
|
373
443
|
* 清空所有工具栏项目
|
|
374
444
|
* @example
|
package/lib/locale/en-US.json
CHANGED
|
@@ -56,6 +56,7 @@
|
|
|
56
56
|
"Replace current block with template?": "Replace current block with template?",
|
|
57
57
|
"Replaced with template block": "Replaced with template block",
|
|
58
58
|
"Render failed": "Render failed",
|
|
59
|
+
"Response record": "Response record",
|
|
59
60
|
"Step configuration": "Step configuration",
|
|
60
61
|
"Step parameter configuration": "Step parameter configuration",
|
|
61
62
|
"Step with key {{stepKey}} not found": "Step with key {{stepKey}} not found",
|
package/lib/locale/index.d.ts
CHANGED
|
@@ -65,6 +65,7 @@ export declare const locales: {
|
|
|
65
65
|
"Replace current block with template?": string;
|
|
66
66
|
"Replaced with template block": string;
|
|
67
67
|
"Render failed": string;
|
|
68
|
+
"Response record": string;
|
|
68
69
|
"Step configuration": string;
|
|
69
70
|
"Step parameter configuration": string;
|
|
70
71
|
"Step with key {{stepKey}} not found": string;
|
|
@@ -150,6 +151,7 @@ export declare const locales: {
|
|
|
150
151
|
"Other blocks": string;
|
|
151
152
|
"Previous step": string;
|
|
152
153
|
"Render failed": string;
|
|
154
|
+
"Response record": string;
|
|
153
155
|
"Step configuration": string;
|
|
154
156
|
"Step parameter configuration": string;
|
|
155
157
|
"Step with key {{stepKey}} not found": string;
|