@nocobase/plugin-flow-engine 2.1.0-alpha.45 → 2.1.0-alpha.47
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/dist/client/index.js +1 -1
- package/dist/externalVersion.js +9 -9
- package/dist/node_modules/@ant-design/icons-svg/package.json +1 -1
- package/dist/node_modules/acorn/package.json +1 -1
- package/dist/node_modules/acorn-jsx/package.json +1 -1
- package/dist/node_modules/acorn-walk/package.json +1 -1
- package/dist/node_modules/ses/package.json +1 -1
- package/dist/node_modules/zod/package.json +1 -1
- package/dist/server/flow-surfaces/apply/compiler.js +10 -11
- package/dist/server/flow-surfaces/authoring-validation.d.ts +1 -0
- package/dist/server/flow-surfaces/authoring-validation.js +773 -26
- package/dist/server/flow-surfaces/blueprint/normalize-document.js +5 -1
- package/dist/server/flow-surfaces/catalog.js +9 -5
- package/dist/server/flow-surfaces/chart-config.js +220 -16
- package/dist/server/flow-surfaces/contract-guard.js +40 -6
- package/dist/server/flow-surfaces/default-block-actions.js +2 -0
- package/dist/server/flow-surfaces/errors.d.ts +15 -0
- package/dist/server/flow-surfaces/errors.js +49 -3
- package/dist/server/flow-surfaces/event-flow-normalizer.d.ts +19 -0
- package/dist/server/flow-surfaces/event-flow-normalizer.js +128 -0
- package/dist/server/flow-surfaces/filter-group.d.ts +9 -1
- package/dist/server/flow-surfaces/filter-group.js +402 -3
- package/dist/server/flow-surfaces/public-data-surface-default-filter.js +2 -1
- package/dist/server/flow-surfaces/route-sync.js +19 -2
- package/dist/server/flow-surfaces/runjs-authoring/ast/bindings.d.ts +66 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/bindings.js +661 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/execution.d.ts +20 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/execution.js +275 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/parser.d.ts +16 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/parser.js +130 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/react-values.d.ts +20 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/react-values.js +401 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/request-config.d.ts +21 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/request-config.js +199 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/source.d.ts +70 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/source.js +895 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/static-bindings.d.ts +23 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/static-bindings.js +618 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/static-values.d.ts +196 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/static-values.js +1777 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/walk.d.ts +10 -0
- package/dist/server/flow-surfaces/runjs-authoring/ast/walk.js +55 -0
- package/dist/server/flow-surfaces/runjs-authoring/collectors.d.ts +12 -0
- package/dist/server/flow-surfaces/runjs-authoring/collectors.js +589 -0
- package/dist/server/flow-surfaces/runjs-authoring/index.d.ts +2 -25
- package/dist/server/flow-surfaces/runjs-authoring/index.js +5 -11138
- package/dist/server/flow-surfaces/runjs-authoring/inspect.d.ts +13 -0
- package/dist/server/flow-surfaces/runjs-authoring/inspect.js +149 -0
- package/dist/server/flow-surfaces/runjs-authoring/internal-types.d.ts +333 -0
- package/dist/server/flow-surfaces/runjs-authoring/internal-types.js +36 -0
- package/dist/server/flow-surfaces/runjs-authoring/rules.js +2 -0
- package/dist/server/flow-surfaces/runjs-authoring/runtime/constants.d.ts +67 -0
- package/dist/server/flow-surfaces/runjs-authoring/runtime/constants.js +757 -0
- package/dist/server/flow-surfaces/runjs-authoring/runtime/errors.d.ts +22 -0
- package/dist/server/flow-surfaces/runjs-authoring/runtime/errors.js +91 -0
- package/dist/server/flow-surfaces/runjs-authoring/runtime/source-budget.d.ts +16 -0
- package/dist/server/flow-surfaces/runjs-authoring/runtime/source-budget.js +115 -0
- package/dist/server/flow-surfaces/runjs-authoring/runtime/surface.d.ts +19 -0
- package/dist/server/flow-surfaces/runjs-authoring/runtime/surface.js +140 -0
- package/dist/server/flow-surfaces/runjs-authoring/runtime/types.d.ts +91 -0
- package/dist/server/flow-surfaces/runjs-authoring/runtime/types.js +24 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/ctx-api.d.ts +138 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/ctx-api.js +1779 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/filter.d.ts +10 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/filter.js +1583 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/index.d.ts +195 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/index.js +463 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/react-render.d.ts +48 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/react-render.js +379 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/react.d.ts +26 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/react.js +1441 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/resource.d.ts +23 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/resource.js +1427 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/source-patterns.d.ts +91 -0
- package/dist/server/flow-surfaces/runjs-authoring/scan/source-patterns.js +889 -0
- package/dist/server/flow-surfaces/runjs-authoring/types.d.ts +1 -1
- package/dist/server/flow-surfaces/runjs-authoring/unknown-global-stop/index.d.ts +10 -0
- package/dist/server/flow-surfaces/runjs-authoring/unknown-global-stop/index.js +40 -0
- package/dist/server/flow-surfaces/runjs-authoring/validators/index.d.ts +12 -0
- package/dist/server/flow-surfaces/runjs-authoring/validators/index.js +887 -0
- package/dist/server/flow-surfaces/service-helpers.d.ts +29 -0
- package/dist/server/flow-surfaces/service-helpers.js +105 -0
- package/dist/server/flow-surfaces/service-utils.d.ts +15 -3
- package/dist/server/flow-surfaces/service-utils.js +6 -5
- package/dist/server/flow-surfaces/service.d.ts +7 -1
- package/dist/server/flow-surfaces/service.js +488 -94
- package/dist/server/flow-surfaces/types.d.ts +3 -0
- package/dist/server/repository.d.ts +15 -1
- package/dist/server/repository.js +262 -23
- package/dist/server/template/contexts.d.ts +2 -0
- package/dist/server/template/contexts.js +34 -0
- package/dist/server/template/resolver.js +233 -22
- package/dist/swagger/flow-surfaces.d.ts +175 -0
- package/dist/swagger/flow-surfaces.js +130 -51
- package/dist/swagger/index.d.ts +175 -0
- package/package.json +2 -2
|
@@ -81,6 +81,7 @@ var import_placement = require("./placement");
|
|
|
81
81
|
var import_route_sync = require("./route-sync");
|
|
82
82
|
var import_surface_context = require("./surface-context");
|
|
83
83
|
var import_context = require("./context");
|
|
84
|
+
var import_event_flow_normalizer = require("./event-flow-normalizer");
|
|
84
85
|
var import_configure_options = require("./configure-options");
|
|
85
86
|
var import_public_compatibility = require("./public-compatibility");
|
|
86
87
|
var import_support_matrix = require("./support-matrix");
|
|
@@ -103,14 +104,38 @@ var import_template_service_utils = require("./template-service-utils");
|
|
|
103
104
|
var import_hidden_popup_contract = require("./hidden-popup-contract");
|
|
104
105
|
var import_hidden_popup_calendar = require("./hidden-popup-calendar");
|
|
105
106
|
var import_hidden_popup_kanban = require("./hidden-popup-kanban");
|
|
106
|
-
const FLOW_SURFACE_CHART_REPAIR_HINT = "This is a chart payload shape problem.
|
|
107
|
+
const FLOW_SURFACE_CHART_REPAIR_HINT = "This is a chart payload shape problem. Keep using chart and repair the current chart block payload using assets.charts.<key>.query/visual plus block.chart, or localized settings.query/settings.visual. Do not change this block type to table, jsBlock, actionPanel, gridCard, or another block type. Do not drop or defer the chart. KPI / summary numbers should use jsBlock; charts are for trends, distributions, rankings, and visual analysis.";
|
|
107
108
|
const FLOW_SURFACE_CHART_REPAIR_STEPS = [
|
|
108
109
|
"Keep the block type as chart.",
|
|
109
|
-
"Define assets.charts.<key>.query and assets.charts.<key>.visual, or
|
|
110
|
+
"Define assets.charts.<key>.query and assets.charts.<key>.visual, or fill localized settings.query and settings.visual on the existing chart block.",
|
|
110
111
|
"Reference the asset from the chart block with block.chart = <key> when using assets.charts.",
|
|
111
112
|
"Retry the chart payload instead of replacing the chart with another block type, omitting it, or deferring it."
|
|
112
113
|
];
|
|
113
114
|
const FLOW_SURFACE_CHART_EXPECTED_SHAPE = {
|
|
115
|
+
settings: {
|
|
116
|
+
query: {
|
|
117
|
+
mode: "builder",
|
|
118
|
+
resource: {
|
|
119
|
+
dataSourceKey: "main",
|
|
120
|
+
collectionName: "employees"
|
|
121
|
+
},
|
|
122
|
+
measures: [
|
|
123
|
+
{
|
|
124
|
+
field: "id",
|
|
125
|
+
aggregation: "count",
|
|
126
|
+
alias: "employeeCount"
|
|
127
|
+
}
|
|
128
|
+
]
|
|
129
|
+
},
|
|
130
|
+
visual: {
|
|
131
|
+
mode: "basic",
|
|
132
|
+
type: "bar",
|
|
133
|
+
mappings: {
|
|
134
|
+
x: "status",
|
|
135
|
+
y: "employeeCount"
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
},
|
|
114
139
|
assets: {
|
|
115
140
|
charts: {
|
|
116
141
|
chartKey: {
|
|
@@ -126,29 +151,80 @@ const FLOW_SURFACE_CHART_EXPECTED_SHAPE = {
|
|
|
126
151
|
};
|
|
127
152
|
const FLOW_SURFACE_CHART_FORBIDDEN_FALLBACKS = [
|
|
128
153
|
"table",
|
|
154
|
+
"list",
|
|
129
155
|
"jsBlock",
|
|
130
156
|
"actionPanel",
|
|
131
157
|
"gridCard",
|
|
158
|
+
"markdown",
|
|
132
159
|
"drop chart",
|
|
133
160
|
"defer chart"
|
|
134
161
|
];
|
|
162
|
+
const FLOW_SURFACE_CHART_REPAIR_EXAMPLE = {
|
|
163
|
+
settings: {
|
|
164
|
+
query: {
|
|
165
|
+
mode: "builder",
|
|
166
|
+
resource: {
|
|
167
|
+
dataSourceKey: "main",
|
|
168
|
+
collectionName: "<collectionName>"
|
|
169
|
+
},
|
|
170
|
+
measures: [
|
|
171
|
+
{
|
|
172
|
+
field: "id",
|
|
173
|
+
aggregation: "count",
|
|
174
|
+
alias: "recordCount"
|
|
175
|
+
}
|
|
176
|
+
],
|
|
177
|
+
dimensions: [
|
|
178
|
+
{
|
|
179
|
+
field: "<dimensionField>"
|
|
180
|
+
}
|
|
181
|
+
]
|
|
182
|
+
},
|
|
183
|
+
visual: {
|
|
184
|
+
mode: "basic",
|
|
185
|
+
type: "bar",
|
|
186
|
+
mappings: {
|
|
187
|
+
x: "<dimensionField>",
|
|
188
|
+
y: "recordCount"
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
};
|
|
135
193
|
function withChartRepairMessage(message) {
|
|
136
194
|
return `${message}. ${FLOW_SURFACE_CHART_REPAIR_HINT}`;
|
|
137
195
|
}
|
|
138
196
|
function withFlowSurfaceChartRepairDetails(details = {}) {
|
|
139
197
|
return {
|
|
140
198
|
...details,
|
|
199
|
+
requiredBlockType: "chart",
|
|
200
|
+
fixStrategy: "repair_same_block_type",
|
|
141
201
|
repairHint: FLOW_SURFACE_CHART_REPAIR_HINT,
|
|
142
202
|
repairSteps: FLOW_SURFACE_CHART_REPAIR_STEPS,
|
|
143
203
|
expectedShape: FLOW_SURFACE_CHART_EXPECTED_SHAPE,
|
|
204
|
+
repairExample: FLOW_SURFACE_CHART_REPAIR_EXAMPLE,
|
|
144
205
|
forbiddenFallbacks: FLOW_SURFACE_CHART_FORBIDDEN_FALLBACKS
|
|
145
206
|
};
|
|
146
207
|
}
|
|
147
|
-
function throwChartRepairBadRequest(message,
|
|
208
|
+
function throwChartRepairBadRequest(message, options = {}) {
|
|
209
|
+
const details = import_lodash.default.isPlainObject(options.details) ? options.details : {};
|
|
148
210
|
(0, import_errors.throwBadRequest)(withChartRepairMessage(message), {
|
|
211
|
+
...options,
|
|
149
212
|
details: withFlowSurfaceChartRepairDetails(details)
|
|
150
213
|
});
|
|
151
214
|
}
|
|
215
|
+
function isChartConfigureBadRequestError(error) {
|
|
216
|
+
return error instanceof import_errors.FlowSurfaceBadRequestError && String(error.message || "").startsWith("chart ");
|
|
217
|
+
}
|
|
218
|
+
function buildChartConfigureFromSemanticChangesWithRepair(currentConfigure, changes) {
|
|
219
|
+
try {
|
|
220
|
+
return (0, import_chart_config.buildChartConfigureFromSemanticChanges)(currentConfigure, changes);
|
|
221
|
+
} catch (error) {
|
|
222
|
+
if (isChartConfigureBadRequestError(error)) {
|
|
223
|
+
throwChartRepairBadRequest(error.message, error.options);
|
|
224
|
+
}
|
|
225
|
+
throw error;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
152
228
|
function isFlowSurfaceChartRepairError(error) {
|
|
153
229
|
var _a, _b;
|
|
154
230
|
return error instanceof import_errors.FlowSurfaceBadRequestError && ((_b = (_a = error.options) == null ? void 0 : _a.details) == null ? void 0 : _b.repairHint) === FLOW_SURFACE_CHART_REPAIR_HINT;
|
|
@@ -1088,7 +1164,7 @@ class FlowSurfacesService {
|
|
|
1088
1164
|
parentId: null,
|
|
1089
1165
|
options: {
|
|
1090
1166
|
documentTitle: values.tabDocumentTitle,
|
|
1091
|
-
flowRegistry: values.tabFlowRegistry || {}
|
|
1167
|
+
flowRegistry: this.normalizeEventFlowRegistry("createMenu", values.tabFlowRegistry || {})
|
|
1092
1168
|
}
|
|
1093
1169
|
}
|
|
1094
1170
|
]
|
|
@@ -2819,7 +2895,7 @@ class FlowSurfacesService {
|
|
|
2819
2895
|
use: "RootPageTabModel",
|
|
2820
2896
|
props: import_lodash.default.omit(import_lodash.default.cloneDeep((currentNode == null ? void 0 : currentNode.props) || {}), ["route"]),
|
|
2821
2897
|
decoratorProps: import_lodash.default.cloneDeep((currentNode == null ? void 0 : currentNode.decoratorProps) || {}),
|
|
2822
|
-
flowRegistry:
|
|
2898
|
+
flowRegistry: this.getEventFlowRegistry(currentNode),
|
|
2823
2899
|
stepParams: import_lodash.default.cloneDeep((values == null ? void 0 : values.stepParams) || (currentNode == null ? void 0 : currentNode.stepParams) || {})
|
|
2824
2900
|
}),
|
|
2825
2901
|
{ transaction: options == null ? void 0 : options.transaction }
|
|
@@ -3040,7 +3116,7 @@ class FlowSurfacesService {
|
|
|
3040
3116
|
continue;
|
|
3041
3117
|
}
|
|
3042
3118
|
(0, import_service_utils.assertSupportedSimpleChanges)("chart", chartAsset, (0, import_configure_options.getConfigureOptionKeysForUse)("ChartBlockModel"));
|
|
3043
|
-
const nextConfigure = (
|
|
3119
|
+
const nextConfigure = buildChartConfigureFromSemanticChangesWithRepair(void 0, chartAsset);
|
|
3044
3120
|
await this.validateChartConfigureForRuntime(
|
|
3045
3121
|
`applyBlueprint assets.charts.${chartKey}`,
|
|
3046
3122
|
nextConfigure,
|
|
@@ -3048,6 +3124,209 @@ class FlowSurfacesService {
|
|
|
3048
3124
|
);
|
|
3049
3125
|
}
|
|
3050
3126
|
}
|
|
3127
|
+
composeChartBlockHasInlineConfig(block) {
|
|
3128
|
+
const settings = import_lodash.default.isPlainObject(block.settings) ? block.settings : {};
|
|
3129
|
+
return ["configure", "query", "visual", "events"].some(
|
|
3130
|
+
(key) => Object.prototype.hasOwnProperty.call(settings, key)
|
|
3131
|
+
);
|
|
3132
|
+
}
|
|
3133
|
+
prepareComposeChartAssetNestedPopupBlocks(input, path, chartAssets) {
|
|
3134
|
+
if (!import_lodash.default.isPlainObject(input)) {
|
|
3135
|
+
return { value: input, didResolveChartAsset: false };
|
|
3136
|
+
}
|
|
3137
|
+
let didResolveChartAsset = false;
|
|
3138
|
+
let nextInput = input;
|
|
3139
|
+
const ensureNextInput = () => {
|
|
3140
|
+
if (nextInput === input) {
|
|
3141
|
+
nextInput = { ...input };
|
|
3142
|
+
}
|
|
3143
|
+
return nextInput;
|
|
3144
|
+
};
|
|
3145
|
+
const preparePopupBlocks = (key) => {
|
|
3146
|
+
const popup = input[key];
|
|
3147
|
+
if (!import_lodash.default.isPlainObject(popup) || !Array.isArray(popup.blocks)) {
|
|
3148
|
+
return;
|
|
3149
|
+
}
|
|
3150
|
+
const prepared = this.prepareComposeChartAssetBlockList(popup.blocks, `${path}.${key}.blocks`, chartAssets);
|
|
3151
|
+
if (!prepared.didResolveChartAsset) {
|
|
3152
|
+
return;
|
|
3153
|
+
}
|
|
3154
|
+
ensureNextInput()[key] = {
|
|
3155
|
+
...popup,
|
|
3156
|
+
blocks: prepared.blocks
|
|
3157
|
+
};
|
|
3158
|
+
didResolveChartAsset = true;
|
|
3159
|
+
};
|
|
3160
|
+
preparePopupBlocks("popup");
|
|
3161
|
+
preparePopupBlocks("openView");
|
|
3162
|
+
return {
|
|
3163
|
+
value: nextInput,
|
|
3164
|
+
didResolveChartAsset
|
|
3165
|
+
};
|
|
3166
|
+
}
|
|
3167
|
+
prepareComposeChartAssetBlockList(blocks, path, chartAssets) {
|
|
3168
|
+
const rawBlocks = import_lodash.default.castArray(blocks || []);
|
|
3169
|
+
if (!rawBlocks.length) {
|
|
3170
|
+
return { blocks: rawBlocks, didResolveChartAsset: false };
|
|
3171
|
+
}
|
|
3172
|
+
let didResolveChartAsset = false;
|
|
3173
|
+
const hiddenPopupKeys = [
|
|
3174
|
+
"quickCreatePopup",
|
|
3175
|
+
"eventPopup",
|
|
3176
|
+
"cardPopup",
|
|
3177
|
+
"quickCreatePopupSettings",
|
|
3178
|
+
"eventPopupSettings",
|
|
3179
|
+
"cardPopupSettings"
|
|
3180
|
+
];
|
|
3181
|
+
const nextBlocks = rawBlocks.map((block, index) => {
|
|
3182
|
+
if (!import_lodash.default.isPlainObject(block)) {
|
|
3183
|
+
return block;
|
|
3184
|
+
}
|
|
3185
|
+
const blockPath = `${path}[${index}]`;
|
|
3186
|
+
let nextBlock = block;
|
|
3187
|
+
const ensureNextBlock = () => {
|
|
3188
|
+
if (nextBlock === block) {
|
|
3189
|
+
nextBlock = { ...block };
|
|
3190
|
+
}
|
|
3191
|
+
return nextBlock;
|
|
3192
|
+
};
|
|
3193
|
+
if (Array.isArray(block.blocks)) {
|
|
3194
|
+
const prepared = this.prepareComposeChartAssetBlockList(block.blocks, `${blockPath}.blocks`, chartAssets);
|
|
3195
|
+
if (prepared.didResolveChartAsset) {
|
|
3196
|
+
ensureNextBlock().blocks = prepared.blocks;
|
|
3197
|
+
didResolveChartAsset = true;
|
|
3198
|
+
}
|
|
3199
|
+
}
|
|
3200
|
+
for (const slot of ["actions", "recordActions", "fields"]) {
|
|
3201
|
+
if (!Array.isArray(block[slot])) {
|
|
3202
|
+
continue;
|
|
3203
|
+
}
|
|
3204
|
+
let didPrepareSlot = false;
|
|
3205
|
+
const nextItems = block[slot].map((item, itemIndex) => {
|
|
3206
|
+
const prepared = this.prepareComposeChartAssetNestedPopupBlocks(
|
|
3207
|
+
item,
|
|
3208
|
+
`${blockPath}.${slot}[${itemIndex}]`,
|
|
3209
|
+
chartAssets
|
|
3210
|
+
);
|
|
3211
|
+
didPrepareSlot = didPrepareSlot || prepared.didResolveChartAsset;
|
|
3212
|
+
return prepared.value;
|
|
3213
|
+
});
|
|
3214
|
+
if (didPrepareSlot) {
|
|
3215
|
+
ensureNextBlock()[slot] = nextItems;
|
|
3216
|
+
didResolveChartAsset = true;
|
|
3217
|
+
}
|
|
3218
|
+
}
|
|
3219
|
+
if (Array.isArray(block.fieldGroups)) {
|
|
3220
|
+
let didPrepareFieldGroups = false;
|
|
3221
|
+
const nextFieldGroups = block.fieldGroups.map((group, groupIndex) => {
|
|
3222
|
+
if (!import_lodash.default.isPlainObject(group) || !Array.isArray(group.fields)) {
|
|
3223
|
+
return group;
|
|
3224
|
+
}
|
|
3225
|
+
let didPrepareGroupFields = false;
|
|
3226
|
+
const nextFields = group.fields.map((field, fieldIndex) => {
|
|
3227
|
+
const prepared = this.prepareComposeChartAssetNestedPopupBlocks(
|
|
3228
|
+
field,
|
|
3229
|
+
`${blockPath}.fieldGroups[${groupIndex}].fields[${fieldIndex}]`,
|
|
3230
|
+
chartAssets
|
|
3231
|
+
);
|
|
3232
|
+
didPrepareGroupFields = didPrepareGroupFields || prepared.didResolveChartAsset;
|
|
3233
|
+
return prepared.value;
|
|
3234
|
+
});
|
|
3235
|
+
if (!didPrepareGroupFields) {
|
|
3236
|
+
return group;
|
|
3237
|
+
}
|
|
3238
|
+
didPrepareFieldGroups = true;
|
|
3239
|
+
return {
|
|
3240
|
+
...group,
|
|
3241
|
+
fields: nextFields
|
|
3242
|
+
};
|
|
3243
|
+
});
|
|
3244
|
+
if (didPrepareFieldGroups) {
|
|
3245
|
+
ensureNextBlock().fieldGroups = nextFieldGroups;
|
|
3246
|
+
didResolveChartAsset = true;
|
|
3247
|
+
}
|
|
3248
|
+
}
|
|
3249
|
+
if (import_lodash.default.isPlainObject(block.popup) && Array.isArray(block.popup.blocks)) {
|
|
3250
|
+
const prepared = this.prepareComposeChartAssetBlockList(
|
|
3251
|
+
block.popup.blocks,
|
|
3252
|
+
`${blockPath}.popup.blocks`,
|
|
3253
|
+
chartAssets
|
|
3254
|
+
);
|
|
3255
|
+
if (prepared.didResolveChartAsset) {
|
|
3256
|
+
ensureNextBlock().popup = {
|
|
3257
|
+
...block.popup,
|
|
3258
|
+
blocks: prepared.blocks
|
|
3259
|
+
};
|
|
3260
|
+
didResolveChartAsset = true;
|
|
3261
|
+
}
|
|
3262
|
+
}
|
|
3263
|
+
if (import_lodash.default.isPlainObject(block.settings)) {
|
|
3264
|
+
for (const key of hiddenPopupKeys) {
|
|
3265
|
+
const popup = block.settings[key];
|
|
3266
|
+
if (!import_lodash.default.isPlainObject(popup) || !Array.isArray(popup.blocks)) {
|
|
3267
|
+
continue;
|
|
3268
|
+
}
|
|
3269
|
+
const prepared = this.prepareComposeChartAssetBlockList(
|
|
3270
|
+
popup.blocks,
|
|
3271
|
+
`${blockPath}.settings.${key}.blocks`,
|
|
3272
|
+
chartAssets
|
|
3273
|
+
);
|
|
3274
|
+
if (!prepared.didResolveChartAsset) {
|
|
3275
|
+
continue;
|
|
3276
|
+
}
|
|
3277
|
+
ensureNextBlock().settings = {
|
|
3278
|
+
...nextBlock.settings || {},
|
|
3279
|
+
[key]: {
|
|
3280
|
+
...popup,
|
|
3281
|
+
blocks: prepared.blocks
|
|
3282
|
+
}
|
|
3283
|
+
};
|
|
3284
|
+
didResolveChartAsset = true;
|
|
3285
|
+
}
|
|
3286
|
+
}
|
|
3287
|
+
if (String(nextBlock.type || "").trim() !== "chart" || !Object.prototype.hasOwnProperty.call(nextBlock, "chart") || this.composeChartBlockHasInlineConfig(nextBlock)) {
|
|
3288
|
+
return nextBlock;
|
|
3289
|
+
}
|
|
3290
|
+
const chartKey = String(nextBlock.chart || "").trim();
|
|
3291
|
+
if (!chartKey) {
|
|
3292
|
+
throwChartRepairBadRequest(`${blockPath}.chart must reference one key from assets.charts`, {
|
|
3293
|
+
path: `${blockPath}.chart`,
|
|
3294
|
+
ruleId: "chart-block-asset-reference-required"
|
|
3295
|
+
});
|
|
3296
|
+
}
|
|
3297
|
+
const chartAsset = chartAssets[chartKey];
|
|
3298
|
+
if (!import_lodash.default.isPlainObject(chartAsset)) {
|
|
3299
|
+
throwChartRepairBadRequest(`${blockPath}.chart references missing chart asset '${chartKey}'`, {
|
|
3300
|
+
path: `${blockPath}.chart`,
|
|
3301
|
+
ruleId: "chart-block-asset-reference-missing",
|
|
3302
|
+
details: {
|
|
3303
|
+
chartKey
|
|
3304
|
+
}
|
|
3305
|
+
});
|
|
3306
|
+
}
|
|
3307
|
+
if (!import_lodash.default.isUndefined(nextBlock.settings) && !import_lodash.default.isPlainObject(nextBlock.settings)) {
|
|
3308
|
+
return nextBlock;
|
|
3309
|
+
}
|
|
3310
|
+
didResolveChartAsset = true;
|
|
3311
|
+
return {
|
|
3312
|
+
...nextBlock,
|
|
3313
|
+
settings: import_lodash.default.merge({}, import_lodash.default.cloneDeep(nextBlock.settings || {}), import_lodash.default.cloneDeep(chartAsset))
|
|
3314
|
+
};
|
|
3315
|
+
});
|
|
3316
|
+
return {
|
|
3317
|
+
blocks: nextBlocks,
|
|
3318
|
+
didResolveChartAsset
|
|
3319
|
+
};
|
|
3320
|
+
}
|
|
3321
|
+
prepareComposeChartAssetSettings(values) {
|
|
3322
|
+
var _a;
|
|
3323
|
+
const chartAssets = import_lodash.default.isPlainObject((_a = values == null ? void 0 : values.assets) == null ? void 0 : _a.charts) ? values.assets.charts : {};
|
|
3324
|
+
const prepared = this.prepareComposeChartAssetBlockList(values == null ? void 0 : values.blocks, "$.blocks", chartAssets);
|
|
3325
|
+
return prepared.didResolveChartAsset ? {
|
|
3326
|
+
...values,
|
|
3327
|
+
blocks: prepared.blocks
|
|
3328
|
+
} : values;
|
|
3329
|
+
}
|
|
3051
3330
|
getApplyBlueprintKanbanBlockResourceObject(block) {
|
|
3052
3331
|
return import_lodash.default.isPlainObject(block == null ? void 0 : block.resource) ? block.resource : {};
|
|
3053
3332
|
}
|
|
@@ -3450,16 +3729,6 @@ class FlowSurfacesService {
|
|
|
3450
3729
|
await this.assertApplyBlueprintAuthoringPayload(values, options);
|
|
3451
3730
|
const document = (0, import_blueprint.prepareFlowSurfaceApplyBlueprintDocument)(values);
|
|
3452
3731
|
await this.prevalidateApplyBlueprintChartAssets(document);
|
|
3453
|
-
if (document.mode === "create") {
|
|
3454
|
-
return await this.applyBlueprintWithTransaction(
|
|
3455
|
-
values,
|
|
3456
|
-
{ ...options, skipAuthoringValidation: true },
|
|
3457
|
-
createdKanbanSortFields,
|
|
3458
|
-
{
|
|
3459
|
-
readSurface: false
|
|
3460
|
-
}
|
|
3461
|
-
);
|
|
3462
|
-
}
|
|
3463
3732
|
return await this.transaction(
|
|
3464
3733
|
(transaction) => this.applyBlueprintWithTransaction(
|
|
3465
3734
|
values,
|
|
@@ -5132,12 +5401,13 @@ class FlowSurfacesService {
|
|
|
5132
5401
|
async compose(values, options = {}) {
|
|
5133
5402
|
var _a, _b, _c;
|
|
5134
5403
|
const enabledPackages = await this.resolveEnabledPluginPackages(options);
|
|
5135
|
-
const
|
|
5404
|
+
const composeValues = this.prepareComposeChartAssetSettings(values);
|
|
5405
|
+
const target = await this.prepareWriteTarget("compose", composeValues == null ? void 0 : composeValues.target, composeValues, options);
|
|
5136
5406
|
const authoringContext = await this.buildTargetAuthoringContext({
|
|
5137
5407
|
target,
|
|
5138
5408
|
transaction: options.transaction
|
|
5139
5409
|
});
|
|
5140
|
-
await (0, import_authoring_validation.assertFlowSurfaceAuthoringPayload)("compose",
|
|
5410
|
+
await (0, import_authoring_validation.assertFlowSurfaceAuthoringPayload)("compose", composeValues, {
|
|
5141
5411
|
transaction: options.transaction,
|
|
5142
5412
|
enabledPackages,
|
|
5143
5413
|
skipGeneratedLayoutSingleColumnErrors: options.skipGeneratedLayoutSingleColumnErrors === true,
|
|
@@ -5150,12 +5420,17 @@ class FlowSurfacesService {
|
|
|
5150
5420
|
...options,
|
|
5151
5421
|
popupTemplateTreeCache
|
|
5152
5422
|
};
|
|
5153
|
-
const mode = this.assertComposeMode(
|
|
5154
|
-
const popupDefaultsMetadata = this.buildPopupDefaultsMetadata(
|
|
5155
|
-
const normalizedBlocks = this.normalizeComposeBlocks(
|
|
5156
|
-
|
|
5157
|
-
|
|
5158
|
-
|
|
5423
|
+
const mode = this.assertComposeMode(composeValues == null ? void 0 : composeValues.mode);
|
|
5424
|
+
const popupDefaultsMetadata = this.buildPopupDefaultsMetadata(composeValues == null ? void 0 : composeValues.defaults);
|
|
5425
|
+
const normalizedBlocks = this.normalizeComposeBlocks(
|
|
5426
|
+
composeValues == null ? void 0 : composeValues.blocks,
|
|
5427
|
+
enabledPackages,
|
|
5428
|
+
popupDefaultsMetadata,
|
|
5429
|
+
{
|
|
5430
|
+
dataSourceKey: authoringContext.currentDataSourceKey,
|
|
5431
|
+
collectionName: authoringContext.currentCollectionName
|
|
5432
|
+
}
|
|
5433
|
+
);
|
|
5159
5434
|
this.validateComposePopupTemplateAliases(normalizedBlocks, popupTemplateAliasSession);
|
|
5160
5435
|
const blockParent = await this.surfaceContext.resolveBlockParent(target, options.transaction);
|
|
5161
5436
|
const gridUid = blockParent.parentUid;
|
|
@@ -5181,7 +5456,7 @@ class FlowSurfacesService {
|
|
|
5181
5456
|
mode,
|
|
5182
5457
|
normalizedBlocks,
|
|
5183
5458
|
existingItemUids: existingItems.map((item) => item.uid),
|
|
5184
|
-
layout:
|
|
5459
|
+
layout: composeValues.layout
|
|
5185
5460
|
});
|
|
5186
5461
|
const generatedDefaultFilterByComposeBlockUid = /* @__PURE__ */ new Map();
|
|
5187
5462
|
const result = await (0, import_compose_runtime.executeComposeRuntime)(plan, {
|
|
@@ -5216,7 +5491,7 @@ class FlowSurfacesService {
|
|
|
5216
5491
|
{
|
|
5217
5492
|
...payload,
|
|
5218
5493
|
...Object.keys(hiddenPopupSettings).length ? { settings: hiddenPopupSettings } : {},
|
|
5219
|
-
...
|
|
5494
|
+
...composeValues.defaults ? { defaults: composeValues.defaults } : {}
|
|
5220
5495
|
},
|
|
5221
5496
|
{
|
|
5222
5497
|
...runtimeOptions,
|
|
@@ -5553,7 +5828,7 @@ class FlowSurfacesService {
|
|
|
5553
5828
|
parentId: routeId,
|
|
5554
5829
|
options: {
|
|
5555
5830
|
documentTitle: values.tabDocumentTitle,
|
|
5556
|
-
flowRegistry: values.tabFlowRegistry || {}
|
|
5831
|
+
flowRegistry: this.normalizeEventFlowRegistry("createPage", values.tabFlowRegistry || {})
|
|
5557
5832
|
}
|
|
5558
5833
|
},
|
|
5559
5834
|
transaction
|
|
@@ -5572,7 +5847,10 @@ class FlowSurfacesService {
|
|
|
5572
5847
|
options: {
|
|
5573
5848
|
...this.readRouteOptions(tabRoute),
|
|
5574
5849
|
documentTitle: values.tabDocumentTitle ?? this.readRouteOptions(tabRoute).documentTitle,
|
|
5575
|
-
flowRegistry:
|
|
5850
|
+
flowRegistry: this.normalizeEventFlowRegistry(
|
|
5851
|
+
"createPage",
|
|
5852
|
+
values.tabFlowRegistry || this.readRouteOptions(tabRoute).flowRegistry || {}
|
|
5853
|
+
)
|
|
5576
5854
|
}
|
|
5577
5855
|
},
|
|
5578
5856
|
transaction
|
|
@@ -5714,7 +5992,7 @@ class FlowSurfacesService {
|
|
|
5714
5992
|
hidden: !pageRoute.get("enableTabs"),
|
|
5715
5993
|
options: {
|
|
5716
5994
|
documentTitle: values.documentTitle,
|
|
5717
|
-
flowRegistry: values.flowRegistry || {}
|
|
5995
|
+
flowRegistry: this.normalizeEventFlowRegistry("addTab", values.flowRegistry || {})
|
|
5718
5996
|
}
|
|
5719
5997
|
},
|
|
5720
5998
|
transaction: options.transaction
|
|
@@ -5762,7 +6040,7 @@ class FlowSurfacesService {
|
|
|
5762
6040
|
)
|
|
5763
6041
|
}
|
|
5764
6042
|
} : void 0,
|
|
5765
|
-
flowRegistry: !import_lodash.default.isUndefined(values.flowRegistry) ? values.flowRegistry : void 0
|
|
6043
|
+
flowRegistry: !import_lodash.default.isUndefined(values.flowRegistry) ? this.normalizeEventFlowRegistry("updateTab", values.flowRegistry) : void 0
|
|
5766
6044
|
});
|
|
5767
6045
|
await this.routeSync.persistTabSettings(target, current, nextPayload, options.transaction);
|
|
5768
6046
|
return {
|
|
@@ -5878,7 +6156,7 @@ class FlowSurfacesService {
|
|
|
5878
6156
|
title: values.title,
|
|
5879
6157
|
icon: values.icon,
|
|
5880
6158
|
documentTitle: values.documentTitle,
|
|
5881
|
-
flowRegistry: values.flowRegistry
|
|
6159
|
+
flowRegistry: this.normalizeEventFlowRegistry("addPopupTab", values.flowRegistry)
|
|
5882
6160
|
});
|
|
5883
6161
|
await this.repository.upsertModel(
|
|
5884
6162
|
{
|
|
@@ -5933,7 +6211,7 @@ class FlowSurfacesService {
|
|
|
5933
6211
|
}
|
|
5934
6212
|
}
|
|
5935
6213
|
} : void 0,
|
|
5936
|
-
flowRegistry: !import_lodash.default.isUndefined(values.flowRegistry) ? values.flowRegistry : void 0
|
|
6214
|
+
flowRegistry: !import_lodash.default.isUndefined(values.flowRegistry) ? this.normalizeEventFlowRegistry("updatePopupTab", values.flowRegistry) : void 0
|
|
5937
6215
|
});
|
|
5938
6216
|
if (Object.keys(nextPayload).length === 1) {
|
|
5939
6217
|
return { uid: popupTab.uid };
|
|
@@ -6134,7 +6412,7 @@ class FlowSurfacesService {
|
|
|
6134
6412
|
use: "ReferenceFormGridModel",
|
|
6135
6413
|
props: currentGrid.props,
|
|
6136
6414
|
decoratorProps: currentGrid.decoratorProps,
|
|
6137
|
-
flowRegistry: currentGrid
|
|
6415
|
+
flowRegistry: this.getEventFlowRegistry(currentGrid),
|
|
6138
6416
|
sortIndex: currentGrid.sortIndex,
|
|
6139
6417
|
parentId: blockUid,
|
|
6140
6418
|
subKey: "grid",
|
|
@@ -6380,7 +6658,8 @@ class FlowSurfacesService {
|
|
|
6380
6658
|
if ((0, import_service_utils.hasOwnDefined)(normalizedSettings, "defaultFilter")) {
|
|
6381
6659
|
normalizedSettings.defaultFilter = (0, import_filter_group.normalizeFlowSurfaceFilterGroupValue)(
|
|
6382
6660
|
normalizedSettings.defaultFilter,
|
|
6383
|
-
`flowSurfaces ${actionName} defaultActionSettings.filter.defaultFilter expects FilterGroup like ${import_filter_group.FLOW_SURFACE_FILTER_GROUP_EXAMPLE}
|
|
6661
|
+
`flowSurfaces ${actionName} defaultActionSettings.filter.defaultFilter expects FilterGroup like ${import_filter_group.FLOW_SURFACE_FILTER_GROUP_EXAMPLE}`,
|
|
6662
|
+
{ strictDateValues: true }
|
|
6384
6663
|
);
|
|
6385
6664
|
normalizedSettings.defaultFilter = this.normalizeEffectivePublicDataSurfaceDefaultFilter(
|
|
6386
6665
|
normalizedSettings.defaultFilter,
|
|
@@ -7390,7 +7669,7 @@ class FlowSurfacesService {
|
|
|
7390
7669
|
props: actionSettingsPayload.props,
|
|
7391
7670
|
decoratorProps: values.decoratorProps,
|
|
7392
7671
|
stepParams: actionSettingsPayload.stepParams,
|
|
7393
|
-
flowRegistry: values.flowRegistry
|
|
7672
|
+
flowRegistry: this.normalizeEventFlowRegistry("addAction", values.flowRegistry)
|
|
7394
7673
|
});
|
|
7395
7674
|
this.contractGuard.validateNodeTreeAgainstContract(action);
|
|
7396
7675
|
const created = await this.repository.upsertModel(
|
|
@@ -7517,7 +7796,7 @@ class FlowSurfacesService {
|
|
|
7517
7796
|
props: actionSettingsPayload.props,
|
|
7518
7797
|
decoratorProps: values.decoratorProps,
|
|
7519
7798
|
stepParams: actionSettingsPayload.stepParams,
|
|
7520
|
-
flowRegistry: values.flowRegistry
|
|
7799
|
+
flowRegistry: this.normalizeEventFlowRegistry("addRecordAction", values.flowRegistry)
|
|
7521
7800
|
});
|
|
7522
7801
|
this.contractGuard.validateNodeTreeAgainstContract(action);
|
|
7523
7802
|
const created = await this.repository.upsertModel(
|
|
@@ -7569,7 +7848,8 @@ class FlowSurfacesService {
|
|
|
7569
7848
|
},
|
|
7570
7849
|
{
|
|
7571
7850
|
...options,
|
|
7572
|
-
preserveSingleScopeDataBlockTitle
|
|
7851
|
+
preserveSingleScopeDataBlockTitle,
|
|
7852
|
+
skipAuthoringValidation: true
|
|
7573
7853
|
}
|
|
7574
7854
|
)
|
|
7575
7855
|
});
|
|
@@ -11157,6 +11437,7 @@ class FlowSurfacesService {
|
|
|
11157
11437
|
}
|
|
11158
11438
|
if (domain === "flowRegistry") {
|
|
11159
11439
|
this.assertNoTreeConnectFieldsFlowRegistry(current, normalizedValues[domain], "updateSettings");
|
|
11440
|
+
normalizedValues[domain] = this.normalizeEventFlowRegistry("updateSettings", normalizedValues[domain]);
|
|
11160
11441
|
}
|
|
11161
11442
|
if (!contract.editableDomains.includes(domain)) {
|
|
11162
11443
|
(0, import_errors.throwBadRequest)(`flowSurfaces updateSettings domain '${domain}' is not editable`);
|
|
@@ -11173,6 +11454,9 @@ class FlowSurfacesService {
|
|
|
11173
11454
|
current.use
|
|
11174
11455
|
);
|
|
11175
11456
|
});
|
|
11457
|
+
if (!import_lodash.default.isUndefined(nextPayload.flowRegistry)) {
|
|
11458
|
+
nextPayload.flowRegistry = this.normalizeEventFlowRegistry("updateSettings", nextPayload.flowRegistry);
|
|
11459
|
+
}
|
|
11176
11460
|
this.replaceExplicitPopupStepParamSubtreesForUpdateSettings(
|
|
11177
11461
|
current,
|
|
11178
11462
|
normalizedValues,
|
|
@@ -11239,7 +11523,7 @@ class FlowSurfacesService {
|
|
|
11239
11523
|
props: nextPayload.props ?? current.props,
|
|
11240
11524
|
decoratorProps: nextPayload.decoratorProps ?? current.decoratorProps,
|
|
11241
11525
|
stepParams: nextPayload.stepParams ?? current.stepParams,
|
|
11242
|
-
flowRegistry: nextPayload.flowRegistry ?? current
|
|
11526
|
+
flowRegistry: nextPayload.flowRegistry ?? this.getEventFlowRegistry(current)
|
|
11243
11527
|
};
|
|
11244
11528
|
const shouldValidateFlowRegistry = !import_lodash.default.isUndefined(nextPayload.flowRegistry) || !import_lodash.default.isUndefined(nextPayload.stepParams);
|
|
11245
11529
|
assertNoFlowSurfaceIdTitleFieldSettings(import_lodash.default.pick(effectiveNode, ["props", "stepParams"]), {
|
|
@@ -11664,12 +11948,12 @@ class FlowSurfacesService {
|
|
|
11664
11948
|
"flowSurfaces updateSettings filter action values 'props.defaultFilterValue/filterValue' and 'stepParams.filterSettings.defaultFilter.defaultFilter' must match"
|
|
11665
11949
|
);
|
|
11666
11950
|
}
|
|
11667
|
-
const
|
|
11668
|
-
hasStepDefaultFilter ? nextStepFilter : nextPropFilter
|
|
11669
|
-
{
|
|
11670
|
-
requiredFieldCount: options.requiredFieldCount
|
|
11671
|
-
}
|
|
11951
|
+
const normalizedFilterValue = this.normalizeFilterActionDefaultFilterValue(
|
|
11952
|
+
hasStepDefaultFilter ? nextStepFilter : nextPropFilter
|
|
11672
11953
|
);
|
|
11954
|
+
const filterValue = this.normalizeEffectivePublicDataSurfaceDefaultFilter(normalizedFilterValue, {
|
|
11955
|
+
requiredFieldCount: options.requiredFieldCount
|
|
11956
|
+
});
|
|
11673
11957
|
if (!hasPropsFilterableFieldNames && !hasStepFilterableFieldNames) {
|
|
11674
11958
|
const filterableFieldNames = (0, import_public_data_surface_default_filter.resolveFlowSurfaceDefaultFilterFieldNames)(filterValue);
|
|
11675
11959
|
if (filterableFieldNames.length) {
|
|
@@ -12113,7 +12397,7 @@ class FlowSurfacesService {
|
|
|
12113
12397
|
return String(input || "").trim();
|
|
12114
12398
|
}
|
|
12115
12399
|
validateBuilderChartFieldsForRuntime(actionName, configure) {
|
|
12116
|
-
var _a, _b;
|
|
12400
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
12117
12401
|
const resourceInit = (0, import_chart_config.getChartBuilderResourceInit)(configure);
|
|
12118
12402
|
if (!(resourceInit == null ? void 0 : resourceInit.collectionName)) {
|
|
12119
12403
|
return;
|
|
@@ -12131,10 +12415,12 @@ class FlowSurfacesService {
|
|
|
12131
12415
|
const selections = [
|
|
12132
12416
|
...import_lodash.default.castArray(state.query.measures || []).map((selection, index) => ({
|
|
12133
12417
|
selection,
|
|
12418
|
+
kind: "measure",
|
|
12134
12419
|
path: `chart query.measures[${index}].field`
|
|
12135
12420
|
})),
|
|
12136
12421
|
...import_lodash.default.castArray(state.query.dimensions || []).map((selection, index) => ({
|
|
12137
12422
|
selection,
|
|
12423
|
+
kind: "dimension",
|
|
12138
12424
|
path: `chart query.dimensions[${index}].field`
|
|
12139
12425
|
}))
|
|
12140
12426
|
];
|
|
@@ -12143,37 +12429,151 @@ class FlowSurfacesService {
|
|
|
12143
12429
|
if (!fieldPath) {
|
|
12144
12430
|
continue;
|
|
12145
12431
|
}
|
|
12432
|
+
const fieldPathParts = fieldPath.split(".").filter(Boolean);
|
|
12433
|
+
const isCountMeasureSelection = item.kind === "measure" && String(((_c = item.selection) == null ? void 0 : _c.aggregation) || "").trim() === "count" && !((_d = item.selection) == null ? void 0 : _d.distinct);
|
|
12434
|
+
if (fieldPathParts.length > 1 && !isCountMeasureSelection) {
|
|
12435
|
+
const directAssociationPath = fieldPathParts[0];
|
|
12436
|
+
const directAssociationField = (0, import_service_helpers.resolveFieldFromCollection)(collection, directAssociationPath);
|
|
12437
|
+
const directAssociationTargetCollection = directAssociationField && (0, import_service_helpers.isAssociationField)(directAssociationField) ? (0, import_service_helpers.resolveFieldTargetCollection)(
|
|
12438
|
+
directAssociationField,
|
|
12439
|
+
dataSourceKey,
|
|
12440
|
+
(resolvedDataSourceKey, targetCollection) => this.getCollection(resolvedDataSourceKey, targetCollection)
|
|
12441
|
+
) : null;
|
|
12442
|
+
const invalidDirectSubfield = directAssociationTargetCollection ? (0, import_service_helpers.getInvalidChartBuilderRelationDirectSubfieldDetails)({
|
|
12443
|
+
associationPathName: directAssociationPath,
|
|
12444
|
+
selectedSubfieldPath: fieldPathParts.slice(1).join("."),
|
|
12445
|
+
targetCollection: directAssociationTargetCollection
|
|
12446
|
+
}) : null;
|
|
12447
|
+
if (invalidDirectSubfield) {
|
|
12448
|
+
(0, import_errors.throwBadRequest)(
|
|
12449
|
+
withChartRepairMessage(
|
|
12450
|
+
`flowSurfaces ${actionName} ${item.path} '${fieldPath}' must reference a direct scalar child field under relation '${invalidDirectSubfield.associationPath}'. ${(0, import_service_helpers.formatChartBuilderSupportedRelationSubfields)(
|
|
12451
|
+
invalidDirectSubfield.associationPath,
|
|
12452
|
+
invalidDirectSubfield.supportedFields
|
|
12453
|
+
)}`
|
|
12454
|
+
),
|
|
12455
|
+
{
|
|
12456
|
+
path: item.path,
|
|
12457
|
+
ruleId: "chart-builder-query-relation-direct-subfield-required",
|
|
12458
|
+
details: withFlowSurfaceChartRepairDetails({
|
|
12459
|
+
fieldPath,
|
|
12460
|
+
dataSourceKey,
|
|
12461
|
+
collectionName,
|
|
12462
|
+
...invalidDirectSubfield
|
|
12463
|
+
})
|
|
12464
|
+
}
|
|
12465
|
+
);
|
|
12466
|
+
}
|
|
12467
|
+
}
|
|
12146
12468
|
const parsed = this.parseFieldPath(collection, fieldPath, void 0, dataSourceKey, collectionName);
|
|
12469
|
+
if (parsed.associationPathName) {
|
|
12470
|
+
const associationField = parsed.associationField;
|
|
12471
|
+
const associationTargetCollection = associationField && (0, import_service_helpers.isAssociationField)(associationField) ? (0, import_service_helpers.resolveFieldTargetCollection)(
|
|
12472
|
+
associationField,
|
|
12473
|
+
dataSourceKey,
|
|
12474
|
+
(resolvedDataSourceKey, targetCollection) => this.getCollection(resolvedDataSourceKey, targetCollection)
|
|
12475
|
+
) : null;
|
|
12476
|
+
if (!associationField || !(0, import_service_helpers.isAssociationField)(associationField) || !associationTargetCollection) {
|
|
12477
|
+
(0, import_errors.throwBadRequest)(
|
|
12478
|
+
withChartRepairMessage(
|
|
12479
|
+
`flowSurfaces ${actionName} ${item.path} '${fieldPath}' uses invalid association path '${parsed.associationPathName}' for builder charts`
|
|
12480
|
+
),
|
|
12481
|
+
{
|
|
12482
|
+
path: item.path,
|
|
12483
|
+
ruleId: "chart-builder-query-association-path-invalid",
|
|
12484
|
+
details: withFlowSurfaceChartRepairDetails({
|
|
12485
|
+
fieldPath,
|
|
12486
|
+
associationPath: parsed.associationPathName,
|
|
12487
|
+
dataSourceKey,
|
|
12488
|
+
collectionName
|
|
12489
|
+
})
|
|
12490
|
+
}
|
|
12491
|
+
);
|
|
12492
|
+
}
|
|
12493
|
+
}
|
|
12147
12494
|
const field = (0, import_service_helpers.resolveFieldFromCollection)(parsed.leafCollection, parsed.leafFieldPath);
|
|
12495
|
+
const leafModelAttributes = (0, import_service_helpers.getCollectionModelAttributes)(parsed.leafCollection);
|
|
12496
|
+
const hasLeafModelAttribute = Object.prototype.hasOwnProperty.call(leafModelAttributes, parsed.leafFieldPath);
|
|
12497
|
+
const isCountMeasureRelationSubfield = item.kind === "measure" && String(((_e = item.selection) == null ? void 0 : _e.aggregation) || "").trim() === "count" && !((_f = item.selection) == null ? void 0 : _f.distinct) && parsed.associationField && (0, import_service_helpers.isAssociationField)(parsed.associationField);
|
|
12498
|
+
const unsupportedRelationSubfield = parsed.associationField && (0, import_service_helpers.isAssociationField)(parsed.associationField) ? (0, import_service_helpers.getUnsupportedChartBuilderRelationSubfieldDetails)({
|
|
12499
|
+
associationPathName: parsed.associationPathName,
|
|
12500
|
+
leafFieldName: parsed.leafFieldPath,
|
|
12501
|
+
leafField: field,
|
|
12502
|
+
targetCollection: parsed.leafCollection
|
|
12503
|
+
}) : null;
|
|
12148
12504
|
if (!field) {
|
|
12149
|
-
|
|
12150
|
-
|
|
12505
|
+
const hasConcreteField = hasLeafModelAttribute || this.collectionHasConcreteField(parsed.leafCollection, parsed.leafFieldPath);
|
|
12506
|
+
if (!hasConcreteField) {
|
|
12507
|
+
(0, import_errors.throwBadRequest)(
|
|
12508
|
+
withChartRepairMessage(
|
|
12509
|
+
`flowSurfaces ${actionName} ${item.path} '${fieldPath}' does not exist on collection '${dataSourceKey}.${collectionName}'`
|
|
12510
|
+
),
|
|
12511
|
+
{
|
|
12512
|
+
details: withFlowSurfaceChartRepairDetails({
|
|
12513
|
+
fieldPath,
|
|
12514
|
+
dataSourceKey,
|
|
12515
|
+
collectionName
|
|
12516
|
+
})
|
|
12517
|
+
}
|
|
12518
|
+
);
|
|
12151
12519
|
}
|
|
12520
|
+
}
|
|
12521
|
+
if (!fieldPath.includes(".") && field && (0, import_service_helpers.isAssociationField)(field)) {
|
|
12522
|
+
const suggestion = this.resolveBuilderChartAssociationSubfieldSuggestion(fieldPath, field, dataSourceKey);
|
|
12152
12523
|
(0, import_errors.throwBadRequest)(
|
|
12153
12524
|
withChartRepairMessage(
|
|
12154
|
-
`flowSurfaces ${actionName} ${item.path} '${fieldPath}'
|
|
12525
|
+
`flowSurfaces ${actionName} ${item.path} '${fieldPath}' references an association field directly; use scalar subfield '${suggestion.suggestedFieldPath}' for builder charts`
|
|
12155
12526
|
),
|
|
12156
12527
|
{
|
|
12157
12528
|
details: withFlowSurfaceChartRepairDetails({
|
|
12158
12529
|
fieldPath,
|
|
12159
12530
|
dataSourceKey,
|
|
12160
|
-
collectionName
|
|
12531
|
+
collectionName,
|
|
12532
|
+
...suggestion
|
|
12161
12533
|
})
|
|
12162
12534
|
}
|
|
12163
12535
|
);
|
|
12164
12536
|
}
|
|
12165
|
-
if (
|
|
12166
|
-
const suggestion = this.resolveBuilderChartAssociationSubfieldSuggestion(fieldPath, field, dataSourceKey);
|
|
12537
|
+
if (isCountMeasureRelationSubfield) {
|
|
12167
12538
|
(0, import_errors.throwBadRequest)(
|
|
12168
12539
|
withChartRepairMessage(
|
|
12169
|
-
`flowSurfaces ${actionName} ${item.path} '${fieldPath}'
|
|
12540
|
+
`flowSurfaces ${actionName} ${item.path} '${fieldPath}' counts a relation subfield; count a scalar base field such as 'id' and keep '${fieldPath}' as a dimension`
|
|
12170
12541
|
),
|
|
12171
12542
|
{
|
|
12543
|
+
path: item.path,
|
|
12544
|
+
ruleId: "chart-builder-query-count-measure-relation-subfield",
|
|
12172
12545
|
details: withFlowSurfaceChartRepairDetails({
|
|
12173
12546
|
fieldPath,
|
|
12174
12547
|
dataSourceKey,
|
|
12175
12548
|
collectionName,
|
|
12176
|
-
|
|
12549
|
+
suggestedMeasure: {
|
|
12550
|
+
field: "id",
|
|
12551
|
+
aggregation: "count",
|
|
12552
|
+
alias: String(((_g = item.selection) == null ? void 0 : _g.alias) || "").trim() || "recordCount"
|
|
12553
|
+
},
|
|
12554
|
+
suggestedDimension: {
|
|
12555
|
+
field: fieldPath
|
|
12556
|
+
}
|
|
12557
|
+
})
|
|
12558
|
+
}
|
|
12559
|
+
);
|
|
12560
|
+
}
|
|
12561
|
+
if (unsupportedRelationSubfield) {
|
|
12562
|
+
(0, import_errors.throwBadRequest)(
|
|
12563
|
+
withChartRepairMessage(
|
|
12564
|
+
`flowSurfaces ${actionName} ${item.path} '${fieldPath}' references relation subfield '${fieldPath}', but current chart builder SQL generation cannot query relation subfield '${unsupportedRelationSubfield.leafFieldName}' because its database column is '${unsupportedRelationSubfield.columnName}'. ${(0, import_service_helpers.formatChartBuilderSupportedRelationSubfields)(
|
|
12565
|
+
unsupportedRelationSubfield.associationPath,
|
|
12566
|
+
unsupportedRelationSubfield.supportedFields
|
|
12567
|
+
)}`
|
|
12568
|
+
),
|
|
12569
|
+
{
|
|
12570
|
+
path: item.path,
|
|
12571
|
+
ruleId: "chart-builder-query-relation-subfield-column-unsupported",
|
|
12572
|
+
details: withFlowSurfaceChartRepairDetails({
|
|
12573
|
+
fieldPath,
|
|
12574
|
+
dataSourceKey,
|
|
12575
|
+
collectionName,
|
|
12576
|
+
...unsupportedRelationSubfield
|
|
12177
12577
|
})
|
|
12178
12578
|
}
|
|
12179
12579
|
);
|
|
@@ -12448,6 +12848,8 @@ class FlowSurfacesService {
|
|
|
12448
12848
|
options
|
|
12449
12849
|
);
|
|
12450
12850
|
const flowRegistry = this.getEventFlowRegistry(current);
|
|
12851
|
+
const directEvents = import_lodash.default.cloneDeep(((_a = contract.eventCapabilities) == null ? void 0 : _a.direct) || []);
|
|
12852
|
+
const objectEvents = import_lodash.default.uniq([...import_lodash.default.cloneDeep(((_b = contract.eventCapabilities) == null ? void 0 : _b.object) || []), ...directEvents]);
|
|
12451
12853
|
return {
|
|
12452
12854
|
target: {
|
|
12453
12855
|
uid: target.uid,
|
|
@@ -12456,8 +12858,8 @@ class FlowSurfacesService {
|
|
|
12456
12858
|
},
|
|
12457
12859
|
flowRegistry,
|
|
12458
12860
|
events: {
|
|
12459
|
-
direct:
|
|
12460
|
-
object:
|
|
12861
|
+
direct: directEvents,
|
|
12862
|
+
object: objectEvents
|
|
12461
12863
|
},
|
|
12462
12864
|
phases: {
|
|
12463
12865
|
supported: ["beforeAllFlows", "afterAllFlows", "beforeFlow", "afterFlow", "beforeStep", "afterStep"],
|
|
@@ -12492,13 +12894,12 @@ class FlowSurfacesService {
|
|
|
12492
12894
|
if (phase !== "beforeAllFlows") {
|
|
12493
12895
|
(0, import_errors.throwBadRequest)(`flowSurfaces addEventFlow only supports phase 'beforeAllFlows'`);
|
|
12494
12896
|
}
|
|
12495
|
-
const
|
|
12496
|
-
const nextFlowRegistry = {
|
|
12897
|
+
const nextFlowRegistry = this.normalizeEventFlowRegistry("addEventFlow", {
|
|
12497
12898
|
...flowRegistry,
|
|
12498
|
-
[key]:
|
|
12499
|
-
};
|
|
12899
|
+
[key]: this.normalizeAddEventFlowInput(key, values, phase)
|
|
12900
|
+
});
|
|
12500
12901
|
await this.persistEventFlowRegistry("addEventFlow", target, current, nextFlowRegistry, options);
|
|
12501
|
-
return this.buildEventFlowWriteResult(target, key,
|
|
12902
|
+
return this.buildEventFlowWriteResult(target, key, nextFlowRegistry[key], nextFlowRegistry);
|
|
12502
12903
|
}
|
|
12503
12904
|
async setEventFlow(values, options = {}) {
|
|
12504
12905
|
var _a;
|
|
@@ -12512,13 +12913,12 @@ class FlowSurfacesService {
|
|
|
12512
12913
|
const key = this.normalizeEventFlowKey("setEventFlow", (values == null ? void 0 : values.key) ?? ((_a = values == null ? void 0 : values.flow) == null ? void 0 : _a.key));
|
|
12513
12914
|
this.assertEventFlowFingerprint("setEventFlow", values == null ? void 0 : values.expectedFingerprint, flowRegistry);
|
|
12514
12915
|
const flowInput = import_lodash.default.isPlainObject(values == null ? void 0 : values.flow) ? values.flow : values;
|
|
12515
|
-
const
|
|
12516
|
-
const nextFlowRegistry = {
|
|
12916
|
+
const nextFlowRegistry = this.normalizeEventFlowRegistry("setEventFlow", {
|
|
12517
12917
|
...flowRegistry,
|
|
12518
|
-
[key]:
|
|
12519
|
-
};
|
|
12918
|
+
[key]: this.normalizeEventFlowObject("setEventFlow", key, flowInput)
|
|
12919
|
+
});
|
|
12520
12920
|
await this.persistEventFlowRegistry("setEventFlow", target, current, nextFlowRegistry, options);
|
|
12521
|
-
return this.buildEventFlowWriteResult(target, key,
|
|
12921
|
+
return this.buildEventFlowWriteResult(target, key, nextFlowRegistry[key], nextFlowRegistry);
|
|
12522
12922
|
}
|
|
12523
12923
|
async removeEventFlow(values, options = {}) {
|
|
12524
12924
|
(0, import_payload_shape.validateFlowSurfacePayloadShape)("removeEventFlow", values, "values");
|
|
@@ -12533,14 +12933,14 @@ class FlowSurfacesService {
|
|
|
12533
12933
|
(0, import_errors.throwBadRequest)(`flowSurfaces removeEventFlow flow '${key}' does not exist`);
|
|
12534
12934
|
}
|
|
12535
12935
|
this.assertEventFlowFingerprint("removeEventFlow", values == null ? void 0 : values.expectedFingerprint, flowRegistry);
|
|
12536
|
-
const nextFlowRegistry = import_lodash.default.omit(flowRegistry, [key]);
|
|
12936
|
+
const nextFlowRegistry = this.normalizeEventFlowRegistry("removeEventFlow", import_lodash.default.omit(flowRegistry, [key]));
|
|
12537
12937
|
await this.persistEventFlowRegistry("removeEventFlow", target, current, nextFlowRegistry, options);
|
|
12538
12938
|
return this.buildEventFlowWriteResult(target, key, void 0, nextFlowRegistry);
|
|
12539
12939
|
}
|
|
12540
12940
|
async setEventFlows(values, options = {}) {
|
|
12541
12941
|
(0, import_payload_shape.validateFlowSurfacePayloadShape)("setEventFlows", values, "values");
|
|
12542
12942
|
const { target, current } = await this.resolveEventFlowTarget("setEventFlows", values == null ? void 0 : values.target, values, options);
|
|
12543
|
-
const flows = values.flowRegistry || values.flows || {};
|
|
12943
|
+
const flows = this.normalizeEventFlowRegistry("setEventFlows", values.flowRegistry || values.flows || {});
|
|
12544
12944
|
await this.persistEventFlowRegistry("setEventFlows", target, current, flows, options);
|
|
12545
12945
|
return {
|
|
12546
12946
|
uid: target.uid,
|
|
@@ -12566,7 +12966,10 @@ class FlowSurfacesService {
|
|
|
12566
12966
|
};
|
|
12567
12967
|
}
|
|
12568
12968
|
getEventFlowRegistry(node) {
|
|
12569
|
-
return import_lodash.default.isPlainObject(node == null ? void 0 : node.flowRegistry) ?
|
|
12969
|
+
return import_lodash.default.isPlainObject(node == null ? void 0 : node.flowRegistry) ? this.normalizeEventFlowRegistry("getEventFlowRegistry", node.flowRegistry) : {};
|
|
12970
|
+
}
|
|
12971
|
+
normalizeEventFlowRegistry(actionName, flowRegistry) {
|
|
12972
|
+
return (0, import_event_flow_normalizer.normalizeFlowSurfaceEventFlowRegistry)(actionName, flowRegistry);
|
|
12570
12973
|
}
|
|
12571
12974
|
buildEventFlowFingerprint(flowRegistry) {
|
|
12572
12975
|
return this.buildSurfaceFingerprint({
|
|
@@ -12604,7 +13007,9 @@ class FlowSurfacesService {
|
|
|
12604
13007
|
normalizeAddEventFlowInput(key, values, phase) {
|
|
12605
13008
|
var _a, _b, _c;
|
|
12606
13009
|
const flow = import_lodash.default.isPlainObject(values.flow) ? import_lodash.default.cloneDeep(values.flow) : {};
|
|
12607
|
-
const eventName = String(
|
|
13010
|
+
const eventName = String(
|
|
13011
|
+
values.eventName ?? (typeof flow.on === "string" ? flow.on : (_a = flow == null ? void 0 : flow.on) == null ? void 0 : _a.eventName) ?? ""
|
|
13012
|
+
).trim();
|
|
12608
13013
|
if (!eventName) {
|
|
12609
13014
|
(0, import_errors.throwBadRequest)(`flowSurfaces addEventFlow requires eventName`);
|
|
12610
13015
|
}
|
|
@@ -12627,25 +13032,7 @@ class FlowSurfacesService {
|
|
|
12627
13032
|
});
|
|
12628
13033
|
}
|
|
12629
13034
|
normalizeEventFlowObject(actionName, key, flowInput) {
|
|
12630
|
-
|
|
12631
|
-
(0, import_errors.throwBadRequest)(`flowSurfaces ${actionName} flow '${key}' must be an object`);
|
|
12632
|
-
}
|
|
12633
|
-
const flow = import_lodash.default.cloneDeep(flowInput);
|
|
12634
|
-
flow.key = key;
|
|
12635
|
-
if (import_lodash.default.isPlainObject(flow.on)) {
|
|
12636
|
-
const eventName = String(flow.on.eventName || "").trim();
|
|
12637
|
-
if (eventName) {
|
|
12638
|
-
flow.on.eventName = eventName;
|
|
12639
|
-
}
|
|
12640
|
-
const phase = String(flow.on.phase || "").trim();
|
|
12641
|
-
if (phase) {
|
|
12642
|
-
flow.on.phase = phase;
|
|
12643
|
-
}
|
|
12644
|
-
}
|
|
12645
|
-
if (import_lodash.default.isUndefined(flow.steps)) {
|
|
12646
|
-
flow.steps = {};
|
|
12647
|
-
}
|
|
12648
|
-
return flow;
|
|
13035
|
+
return (0, import_event_flow_normalizer.normalizeFlowSurfaceEventFlow)(actionName, key, flowInput);
|
|
12649
13036
|
}
|
|
12650
13037
|
async persistEventFlowRegistry(actionName, target, current, flowRegistry, options = {}) {
|
|
12651
13038
|
this.assertNoTreeConnectFieldsFlowRegistry(current, flowRegistry, actionName);
|
|
@@ -16037,7 +16424,10 @@ class FlowSurfacesService {
|
|
|
16037
16424
|
const shouldLoadCurrent = shouldUpdateConfigure || shouldUpdateCardSettings;
|
|
16038
16425
|
const resolved = shouldLoadCurrent ? await this.locator.resolve(target, options) : null;
|
|
16039
16426
|
const current = resolved ? await this.loadResolvedNode(resolved, options.transaction) : null;
|
|
16040
|
-
let nextConfigure = shouldUpdateConfigure ? (
|
|
16427
|
+
let nextConfigure = shouldUpdateConfigure ? buildChartConfigureFromSemanticChangesWithRepair(
|
|
16428
|
+
import_lodash.default.get(current, ["stepParams", "chartSettings", "configure"]),
|
|
16429
|
+
changes
|
|
16430
|
+
) : void 0;
|
|
16041
16431
|
if (shouldUpdateConfigure) {
|
|
16042
16432
|
nextConfigure = await this.stripBasicSqlVisualWhenPreviewUnavailable(nextConfigure, changes, options.transaction);
|
|
16043
16433
|
}
|
|
@@ -16165,18 +16555,18 @@ class FlowSurfacesService {
|
|
|
16165
16555
|
return String(raw || "").trim();
|
|
16166
16556
|
}
|
|
16167
16557
|
collectionHasConcreteField(collection, fieldName) {
|
|
16168
|
-
var _a, _b, _c
|
|
16558
|
+
var _a, _b, _c;
|
|
16169
16559
|
const normalized = String(fieldName || "").trim();
|
|
16170
16560
|
if (!normalized) {
|
|
16171
16561
|
return false;
|
|
16172
16562
|
}
|
|
16173
|
-
const modelAttributes = (
|
|
16563
|
+
const modelAttributes = (0, import_service_helpers.getCollectionModelAttributes)(collection);
|
|
16174
16564
|
const primaryKeyAttributes = import_lodash.default.castArray(
|
|
16175
|
-
((
|
|
16565
|
+
((_a = collection == null ? void 0 : collection.model) == null ? void 0 : _a.primaryKeyAttributes) || ((_b = collection == null ? void 0 : collection.model) == null ? void 0 : _b.primaryKeyAttribute) || []
|
|
16176
16566
|
);
|
|
16177
16567
|
const modelAttribute = modelAttributes == null ? void 0 : modelAttributes[normalized];
|
|
16178
16568
|
const isModelPrimaryKey = primaryKeyAttributes.includes(normalized) || !!(modelAttribute == null ? void 0 : modelAttribute.primaryKey);
|
|
16179
|
-
return !!((0, import_service_helpers.resolveFieldFromCollection)(collection, normalized) || ((
|
|
16569
|
+
return !!((0, import_service_helpers.resolveFieldFromCollection)(collection, normalized) || ((_c = collection == null ? void 0 : collection.getField) == null ? void 0 : _c.call(collection, normalized)) || (0, import_service_helpers.getCollectionFields)(collection).some((field) => (0, import_service_helpers.getFieldName)(field) === normalized) || isModelPrimaryKey);
|
|
16180
16570
|
}
|
|
16181
16571
|
assertInitialBlockResourceCompatible(actionName, blockUse, resourceInit, popupProfile) {
|
|
16182
16572
|
if (blockUse === "CommentsBlockModel") {
|
|
@@ -16987,7 +17377,11 @@ class FlowSurfacesService {
|
|
|
16987
17377
|
items: []
|
|
16988
17378
|
};
|
|
16989
17379
|
}
|
|
16990
|
-
return
|
|
17380
|
+
return (0, import_filter_group.normalizeFlowSurfaceFilterGroupValue)(
|
|
17381
|
+
value,
|
|
17382
|
+
`flowSurfaces configure action defaultFilter expects FilterGroup like ${import_filter_group.FLOW_SURFACE_FILTER_GROUP_EXAMPLE}`,
|
|
17383
|
+
{ strictDateValues: true }
|
|
17384
|
+
);
|
|
16991
17385
|
}
|
|
16992
17386
|
normalizeActionAssignValues(actionName, value) {
|
|
16993
17387
|
if (!import_lodash.default.isPlainObject(value)) {
|
|
@@ -21637,7 +22031,7 @@ ${AI_EMPLOYEE_CURRENT_RECORD_PROMPT_VARIABLE}` : AI_EMPLOYEE_CURRENT_RECORD_PROM
|
|
|
21637
22031
|
(value) => !import_lodash.default.isUndefined(value)
|
|
21638
22032
|
),
|
|
21639
22033
|
decoratorProps: import_lodash.default.cloneDeep(innerField.decoratorProps || {}),
|
|
21640
|
-
flowRegistry:
|
|
22034
|
+
flowRegistry: this.getEventFlowRegistry(innerField),
|
|
21641
22035
|
stepParams: import_lodash.default.merge({}, innerField.stepParams || {}, {
|
|
21642
22036
|
fieldBinding: {
|
|
21643
22037
|
use: normalizedTargetUse
|