@nocobase/plugin-flow-engine 2.1.0-beta.41 → 2.1.0-beta.42
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/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 +614 -6
- package/dist/server/flow-surfaces/blueprint/normalize-document.js +5 -1
- package/dist/server/flow-surfaces/chart-config.js +192 -11
- package/dist/server/flow-surfaces/contract-guard.js +1 -1
- 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 +2 -0
- package/dist/server/flow-surfaces/filter-group.js +295 -0
- package/dist/server/flow-surfaces/route-sync.js +19 -2
- package/dist/server/flow-surfaces/service-utils.js +1 -1
- package/dist/server/flow-surfaces/service.d.ts +3 -1
- package/dist/server/flow-surfaces/service.js +128 -64
- package/package.json +2 -2
|
@@ -60,6 +60,7 @@ var import_association_interfaces = require("./association-interfaces");
|
|
|
60
60
|
var import_defaults = require("./blueprint/defaults");
|
|
61
61
|
var import_runjs_authoring = require("./runjs-authoring");
|
|
62
62
|
var import_configure_options = require("./configure-options");
|
|
63
|
+
var import_filter_group = require("./filter-group");
|
|
63
64
|
const MAIN_BLOCK_UNSUPPORTED_SECTIONS = {
|
|
64
65
|
calendar: ["fields", "fieldGroups", "recordActions", "fieldsLayout"],
|
|
65
66
|
kanban: ["fieldGroups", "recordActions", "fieldsLayout"],
|
|
@@ -83,6 +84,13 @@ const VISIBLE_FIELD_REQUIRED_DATA_BLOCK_TYPES = /* @__PURE__ */ new Set([
|
|
|
83
84
|
"kanban"
|
|
84
85
|
]);
|
|
85
86
|
const VISIBLE_FIELD_MINIMUM_DATA_BLOCK_TYPES = /* @__PURE__ */ new Set(["table", "list", "gridCard", "details"]);
|
|
87
|
+
const IMPLICIT_RELATION_TITLE_FIELD_DISPLAY_BLOCK_TYPES = /* @__PURE__ */ new Set(["table", "list", "gridCard", "details"]);
|
|
88
|
+
const IMPLICIT_RELATION_TITLE_FIELD_CONTAINER_USE_BY_BLOCK_TYPE = {
|
|
89
|
+
details: "DetailsItemModel",
|
|
90
|
+
gridCard: "GridCardItemModel",
|
|
91
|
+
list: "ListItemModel",
|
|
92
|
+
table: "TableColumnModel"
|
|
93
|
+
};
|
|
86
94
|
const RICH_COLLECTION_VISIBLE_FIELD_THRESHOLD = import_public_data_surface_default_filter.FLOW_SURFACE_DEFAULT_FILTER_REQUIRED_FIELD_COUNT * 2;
|
|
87
95
|
const RICH_DATA_BLOCK_VISIBLE_FIELD_MINIMUM = 3;
|
|
88
96
|
const NON_BUSINESS_VISIBLE_FIELD_NAMES = /* @__PURE__ */ new Set([
|
|
@@ -163,10 +171,31 @@ const JS_BLOCK_ALLOWED_SETTINGS_KEYS = /* @__PURE__ */ new Set(["title", "descri
|
|
|
163
171
|
const JS_BLOCK_TOP_LEVEL_JS_KEYS = ["code", "version"];
|
|
164
172
|
const JS_BLOCK_INTERNAL_AUTHORING_KEYS = ["props", "decoratorProps", "flowRegistry", "stepParams"];
|
|
165
173
|
const JS_BLOCK_REPAIR_HINT = "This is a jsBlock payload shape problem. Repair this jsBlock using inline settings.code/settings.version, or applyBlueprint assets.scripts.<key>.code plus block.script. Do not change this block type to table, chart, actionPanel, gridCard, or another block type.";
|
|
166
|
-
const CHART_REPAIR_HINT = "This is a chart payload shape problem.
|
|
174
|
+
const CHART_REPAIR_HINT = "This is a chart payload shape problem. Keep using chart and repair this chart 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, and do not drop or defer the chart. KPI / summary numbers should use jsBlock; charts are for trends, distributions, rankings, and visual analysis.";
|
|
175
|
+
const JS_BLOCK_FORBIDDEN_FALLBACKS = [
|
|
176
|
+
"table",
|
|
177
|
+
"list",
|
|
178
|
+
"chart",
|
|
179
|
+
"actionPanel",
|
|
180
|
+
"gridCard",
|
|
181
|
+
"markdown",
|
|
182
|
+
"drop jsBlock",
|
|
183
|
+
"defer jsBlock"
|
|
184
|
+
];
|
|
185
|
+
const CHART_FORBIDDEN_FALLBACKS = [
|
|
186
|
+
"table",
|
|
187
|
+
"list",
|
|
188
|
+
"jsBlock",
|
|
189
|
+
"actionPanel",
|
|
190
|
+
"gridCard",
|
|
191
|
+
"markdown",
|
|
192
|
+
"drop chart",
|
|
193
|
+
"defer chart"
|
|
194
|
+
];
|
|
167
195
|
const CHART_QUERY_MODE_SET = new Set(import_chart_config.CHART_QUERY_MODES);
|
|
168
196
|
const CHART_VISUAL_MODE_SET = new Set(import_chart_config.CHART_VISUAL_MODES);
|
|
169
197
|
const CHART_BASIC_VISUAL_TYPE_SET = new Set(import_chart_config.CHART_BASIC_VISUAL_TYPES);
|
|
198
|
+
const STRICT_LOCALIZED_CHART_ACTIONS = /* @__PURE__ */ new Set(["compose", "addBlocks"]);
|
|
170
199
|
const CHART_VISUAL_LEGACY_BUILDER_KEYS = /* @__PURE__ */ new Set([
|
|
171
200
|
"xField",
|
|
172
201
|
"yField",
|
|
@@ -201,6 +230,7 @@ const CHART_SQL_QUERY_FORBIDDEN_KEYS = /* @__PURE__ */ new Set([
|
|
|
201
230
|
"offset"
|
|
202
231
|
]);
|
|
203
232
|
const CHART_CUSTOM_VISUAL_FORBIDDEN_KEYS = /* @__PURE__ */ new Set(["type", "mappings", "style"]);
|
|
233
|
+
const CHART_DEFAULT_DATA_SOURCE_KEY = "main";
|
|
204
234
|
const JS_ITEM_COLLECTION_ACTION_HOST_BLOCK_TYPES = /* @__PURE__ */ new Set(["table", "list", "gridCard", "calendar", "kanban"]);
|
|
205
235
|
const JS_ITEM_RECORD_ACTION_HOST_BLOCK_TYPES = /* @__PURE__ */ new Set(["table", "details", "list", "gridCard"]);
|
|
206
236
|
const JS_ITEM_FORM_ACTION_HOST_BLOCK_TYPES = /* @__PURE__ */ new Set(["createForm", "editForm"]);
|
|
@@ -396,6 +426,14 @@ async function collectFlowSurfaceAuthoringErrors(actionName, values, context = {
|
|
|
396
426
|
if (!_.isPlainObject(values)) {
|
|
397
427
|
return errors;
|
|
398
428
|
}
|
|
429
|
+
validationContext.getDefaultFieldGroups = validationContext.getDefaultFieldGroups || ((dataSourceKey, collectionName) => {
|
|
430
|
+
var _a2;
|
|
431
|
+
return (_a2 = (0, import_defaults.resolveFlowSurfaceApplyBlueprintDefaultCollection)({
|
|
432
|
+
metadata: values == null ? void 0 : values.defaults,
|
|
433
|
+
dataSourceKey,
|
|
434
|
+
collectionName
|
|
435
|
+
}).collectionDefaults) == null ? void 0 : _a2.fieldGroups;
|
|
436
|
+
});
|
|
399
437
|
if (actionName === "applyBlueprint" && _.isPlainObject((_a = values == null ? void 0 : values.assets) == null ? void 0 : _a.scripts)) {
|
|
400
438
|
validationContext.applyBlueprintScriptAssets = values.assets.scripts;
|
|
401
439
|
}
|
|
@@ -408,7 +446,7 @@ async function collectFlowSurfaceAuthoringErrors(actionName, values, context = {
|
|
|
408
446
|
collectApplyBlueprintChartAssetErrors(actionName, values, validationContext, errors);
|
|
409
447
|
if (actionName === "configure") {
|
|
410
448
|
await collectConfigureErrors(values, errors, validationContext);
|
|
411
|
-
|
|
449
|
+
appendRunJsAuthoringErrors(actionName, values, validationContext, errors);
|
|
412
450
|
if (!validationContext.skipGeneratedPopupDefaultFieldGroups) {
|
|
413
451
|
collectGeneratedPopupDefaultFieldGroupErrors(actionName, values, validationContext, errors);
|
|
414
452
|
}
|
|
@@ -429,9 +467,42 @@ async function collectFlowSurfaceAuthoringErrors(actionName, values, context = {
|
|
|
429
467
|
if (!validationContext.skipGeneratedPopupDefaultFieldGroups) {
|
|
430
468
|
collectGeneratedPopupDefaultFieldGroupErrors(actionName, values, validationContext, errors);
|
|
431
469
|
}
|
|
432
|
-
|
|
470
|
+
appendRunJsAuthoringErrors(actionName, values, validationContext, errors);
|
|
433
471
|
return errors;
|
|
434
472
|
}
|
|
473
|
+
function appendRunJsAuthoringErrors(actionName, values, context, errors) {
|
|
474
|
+
try {
|
|
475
|
+
errors.push(...(0, import_runjs_authoring.collectRunJsAuthoringErrors)(actionName, values, context));
|
|
476
|
+
} catch (error) {
|
|
477
|
+
if (shouldKeepExistingChartAuthoringErrors(error, errors)) {
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
480
|
+
if (isChartBadRequestError(error)) {
|
|
481
|
+
pushChartBadRequestAuthoringError(errors, error, actionName === "configure" ? "$.changes" : "$");
|
|
482
|
+
return;
|
|
483
|
+
}
|
|
484
|
+
throw error;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
function isChartBadRequestError(error) {
|
|
488
|
+
return error instanceof import_errors.FlowSurfaceBadRequestError && String(error.message || "").startsWith("chart ");
|
|
489
|
+
}
|
|
490
|
+
function shouldKeepExistingChartAuthoringErrors(error, errors) {
|
|
491
|
+
return isChartBadRequestError(error) && errors.some((item) => {
|
|
492
|
+
var _a;
|
|
493
|
+
return ((_a = item.details) == null ? void 0 : _a.repairHint) === CHART_REPAIR_HINT;
|
|
494
|
+
});
|
|
495
|
+
}
|
|
496
|
+
function pushChartBadRequestAuthoringError(errors, error, fallbackPath) {
|
|
497
|
+
var _a, _b, _c;
|
|
498
|
+
const details = _.isPlainObject((_a = error.options) == null ? void 0 : _a.details) ? error.options.details : {};
|
|
499
|
+
pushAuthoringError(errors, {
|
|
500
|
+
path: typeof ((_b = error.options) == null ? void 0 : _b.path) === "string" && error.options.path ? error.options.path : fallbackPath,
|
|
501
|
+
ruleId: typeof ((_c = error.options) == null ? void 0 : _c.ruleId) === "string" && error.options.ruleId ? error.options.ruleId : "chart-configure-invalid",
|
|
502
|
+
message: error.message,
|
|
503
|
+
details: withChartRepairHint(details)
|
|
504
|
+
});
|
|
505
|
+
}
|
|
435
506
|
async function collectNavigationGroupErrors(actionName, values, context, errors) {
|
|
436
507
|
var _a;
|
|
437
508
|
if (actionName !== "applyBlueprint" || (values == null ? void 0 : values.mode) !== "create" || !_.isPlainObject((_a = values == null ? void 0 : values.navigation) == null ? void 0 : _a.group)) {
|
|
@@ -644,12 +715,38 @@ function collectChartAssetBlockTreeErrors(block, path, chartAssets, errors) {
|
|
|
644
715
|
function withJsBlockRepairHint(details = {}) {
|
|
645
716
|
return {
|
|
646
717
|
...details,
|
|
647
|
-
|
|
718
|
+
requiredBlockType: "jsBlock",
|
|
719
|
+
fixStrategy: "repair_same_block_type",
|
|
720
|
+
repairHint: JS_BLOCK_REPAIR_HINT,
|
|
721
|
+
repairExample: {
|
|
722
|
+
inlineBlock: {
|
|
723
|
+
type: "jsBlock",
|
|
724
|
+
settings: {
|
|
725
|
+
code: 'ctx.render("Replace this with the required rendered UI");'
|
|
726
|
+
}
|
|
727
|
+
},
|
|
728
|
+
assetBlock: {
|
|
729
|
+
assets: {
|
|
730
|
+
scripts: {
|
|
731
|
+
scriptKey: {
|
|
732
|
+
code: 'ctx.render("Replace this with the required rendered UI");'
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
},
|
|
736
|
+
block: {
|
|
737
|
+
type: "jsBlock",
|
|
738
|
+
script: "scriptKey"
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
},
|
|
742
|
+
forbiddenFallbacks: JS_BLOCK_FORBIDDEN_FALLBACKS
|
|
648
743
|
};
|
|
649
744
|
}
|
|
650
745
|
function withChartRepairHint(details = {}) {
|
|
651
746
|
return {
|
|
652
747
|
...details,
|
|
748
|
+
requiredBlockType: "chart",
|
|
749
|
+
fixStrategy: "repair_same_block_type",
|
|
653
750
|
repairHint: CHART_REPAIR_HINT,
|
|
654
751
|
repairSteps: [
|
|
655
752
|
"Keep the block type as chart.",
|
|
@@ -658,6 +755,58 @@ function withChartRepairHint(details = {}) {
|
|
|
658
755
|
"Retry the chart payload instead of replacing the chart with another block type or omitting it."
|
|
659
756
|
],
|
|
660
757
|
expectedShape: {
|
|
758
|
+
settings: {
|
|
759
|
+
query: {
|
|
760
|
+
mode: "builder",
|
|
761
|
+
resource: {
|
|
762
|
+
dataSourceKey: "main",
|
|
763
|
+
collectionName: "employees"
|
|
764
|
+
},
|
|
765
|
+
measures: [
|
|
766
|
+
{
|
|
767
|
+
field: "id",
|
|
768
|
+
aggregation: "count",
|
|
769
|
+
alias: "employeeCount"
|
|
770
|
+
}
|
|
771
|
+
]
|
|
772
|
+
},
|
|
773
|
+
visual: {
|
|
774
|
+
mode: "basic",
|
|
775
|
+
type: "bar",
|
|
776
|
+
mappings: {
|
|
777
|
+
x: "status",
|
|
778
|
+
y: "employeeCount"
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
},
|
|
782
|
+
legacySettings: {
|
|
783
|
+
configure: {
|
|
784
|
+
query: {
|
|
785
|
+
mode: "builder",
|
|
786
|
+
resource: {
|
|
787
|
+
dataSourceKey: "main",
|
|
788
|
+
collectionName: "employees"
|
|
789
|
+
},
|
|
790
|
+
measures: [
|
|
791
|
+
{
|
|
792
|
+
field: "id",
|
|
793
|
+
aggregation: "count",
|
|
794
|
+
alias: "employeeCount"
|
|
795
|
+
}
|
|
796
|
+
]
|
|
797
|
+
},
|
|
798
|
+
chart: {
|
|
799
|
+
option: {
|
|
800
|
+
mode: "basic",
|
|
801
|
+
builder: {
|
|
802
|
+
type: "bar",
|
|
803
|
+
xField: "status",
|
|
804
|
+
yField: "employeeCount"
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
},
|
|
661
810
|
assets: {
|
|
662
811
|
charts: {
|
|
663
812
|
chartKey: {
|
|
@@ -671,9 +820,232 @@ function withChartRepairHint(details = {}) {
|
|
|
671
820
|
chart: "chartKey"
|
|
672
821
|
}
|
|
673
822
|
},
|
|
674
|
-
|
|
823
|
+
repairExample: {
|
|
824
|
+
settings: {
|
|
825
|
+
query: {
|
|
826
|
+
mode: "builder",
|
|
827
|
+
resource: {
|
|
828
|
+
dataSourceKey: "main",
|
|
829
|
+
collectionName: "<collectionName>"
|
|
830
|
+
},
|
|
831
|
+
measures: [
|
|
832
|
+
{
|
|
833
|
+
field: "id",
|
|
834
|
+
aggregation: "count",
|
|
835
|
+
alias: "recordCount"
|
|
836
|
+
}
|
|
837
|
+
],
|
|
838
|
+
dimensions: [
|
|
839
|
+
{
|
|
840
|
+
field: "<dimensionField>"
|
|
841
|
+
}
|
|
842
|
+
]
|
|
843
|
+
},
|
|
844
|
+
visual: {
|
|
845
|
+
mode: "basic",
|
|
846
|
+
type: "bar",
|
|
847
|
+
mappings: {
|
|
848
|
+
x: "<dimensionField>",
|
|
849
|
+
y: "recordCount"
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
},
|
|
853
|
+
assets: {
|
|
854
|
+
charts: {
|
|
855
|
+
chartKey: {
|
|
856
|
+
query: {
|
|
857
|
+
mode: "builder",
|
|
858
|
+
resource: {
|
|
859
|
+
dataSourceKey: "main",
|
|
860
|
+
collectionName: "<collectionName>"
|
|
861
|
+
},
|
|
862
|
+
measures: [
|
|
863
|
+
{
|
|
864
|
+
field: "id",
|
|
865
|
+
aggregation: "count",
|
|
866
|
+
alias: "recordCount"
|
|
867
|
+
}
|
|
868
|
+
],
|
|
869
|
+
dimensions: [
|
|
870
|
+
{
|
|
871
|
+
field: "<dimensionField>"
|
|
872
|
+
}
|
|
873
|
+
]
|
|
874
|
+
},
|
|
875
|
+
visual: {
|
|
876
|
+
mode: "basic",
|
|
877
|
+
type: "bar",
|
|
878
|
+
mappings: {
|
|
879
|
+
x: "<dimensionField>",
|
|
880
|
+
y: "recordCount"
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
},
|
|
886
|
+
block: {
|
|
887
|
+
type: "chart",
|
|
888
|
+
chart: "chartKey"
|
|
889
|
+
}
|
|
890
|
+
},
|
|
891
|
+
forbiddenFallbacks: CHART_FORBIDDEN_FALLBACKS
|
|
892
|
+
};
|
|
893
|
+
}
|
|
894
|
+
function collectLocalizedChartSettingsErrors(block, blockType, path, errors, context) {
|
|
895
|
+
if (blockType !== "chart" || !STRICT_LOCALIZED_CHART_ACTIONS.has(context.authoringActionName)) {
|
|
896
|
+
return;
|
|
897
|
+
}
|
|
898
|
+
const settingsPath = `${path}.settings`;
|
|
899
|
+
if (!_.isUndefined(block.settings) && !_.isPlainObject(block.settings)) {
|
|
900
|
+
pushAuthoringError(errors, {
|
|
901
|
+
path: settingsPath,
|
|
902
|
+
ruleId: "chart-localized-settings-invalid",
|
|
903
|
+
message: `flowSurfaces authoring ${settingsPath} must be an object for compose/addBlocks chart blocks`,
|
|
904
|
+
details: withChartRepairHint()
|
|
905
|
+
});
|
|
906
|
+
return;
|
|
907
|
+
}
|
|
908
|
+
const settings = _.isPlainObject(block.settings) ? block.settings : {};
|
|
909
|
+
if (hasOwn(settings, "configure")) {
|
|
910
|
+
if (["query", "visual", "events"].some((key) => hasOwn(settings, key))) {
|
|
911
|
+
pushAuthoringError(errors, {
|
|
912
|
+
path: settingsPath,
|
|
913
|
+
ruleId: "chart-localized-settings-mixed-configure",
|
|
914
|
+
message: `flowSurfaces authoring ${settingsPath} cannot mix legacy configure with query/visual/events`,
|
|
915
|
+
details: withChartRepairHint()
|
|
916
|
+
});
|
|
917
|
+
return;
|
|
918
|
+
}
|
|
919
|
+
collectLocalizedLegacyChartConfigureErrors(settings.configure, `${settingsPath}.configure`, errors);
|
|
920
|
+
return;
|
|
921
|
+
}
|
|
922
|
+
if (!hasOwn(settings, "query") && !hasOwn(settings, "visual")) {
|
|
923
|
+
return;
|
|
924
|
+
}
|
|
925
|
+
collectChartAssetQueryErrors(settings, settingsPath, context, errors);
|
|
926
|
+
collectChartAssetVisualErrors(settings, settingsPath, errors);
|
|
927
|
+
}
|
|
928
|
+
function collectLocalizedLegacyChartConfigureErrors(configure, path, errors) {
|
|
929
|
+
if (!_.isPlainObject(configure)) {
|
|
930
|
+
pushAuthoringError(errors, {
|
|
931
|
+
path,
|
|
932
|
+
ruleId: "chart-configure-invalid",
|
|
933
|
+
message: `flowSurfaces authoring ${path} must be an object`,
|
|
934
|
+
details: withChartRepairHint()
|
|
935
|
+
});
|
|
936
|
+
return;
|
|
937
|
+
}
|
|
938
|
+
collectLegacyChartQueryCompatibilityErrors(configure.query, `${path}.query`, errors);
|
|
939
|
+
}
|
|
940
|
+
function collectLegacyChartQueryCompatibilityErrors(query, path, errors) {
|
|
941
|
+
if (!_.isPlainObject(query)) {
|
|
942
|
+
return;
|
|
943
|
+
}
|
|
944
|
+
collectChartQueryFilterOperatorErrors(query, path, errors);
|
|
945
|
+
const hasResource = hasOwn(query, "resource");
|
|
946
|
+
const hasCollectionPath = hasOwn(query, "collectionPath");
|
|
947
|
+
if (!hasResource && !hasCollectionPath) {
|
|
948
|
+
return;
|
|
949
|
+
}
|
|
950
|
+
const resource = hasResource ? normalizeLegacyChartResourceForValidation(query.resource, `${path}.resource`, errors) : void 0;
|
|
951
|
+
const collectionPathResource = hasCollectionPath ? normalizeLegacyChartCollectionPathResourceForValidation(query.collectionPath, `${path}.collectionPath`, errors) : void 0;
|
|
952
|
+
if (hasResource && hasCollectionPath && resource && collectionPathResource && !_.isEqual(resource, collectionPathResource)) {
|
|
953
|
+
pushAuthoringError(errors, {
|
|
954
|
+
path,
|
|
955
|
+
ruleId: "chart-legacy-query-resource-conflict",
|
|
956
|
+
message: `flowSurfaces authoring ${path}.resource and ${path}.collectionPath must reference the same collection`,
|
|
957
|
+
details: withChartRepairHint({
|
|
958
|
+
resource,
|
|
959
|
+
collectionPathResource
|
|
960
|
+
})
|
|
961
|
+
});
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
function normalizeLegacyChartCollectionPathResource(collectionPath) {
|
|
965
|
+
if (!Array.isArray(collectionPath)) {
|
|
966
|
+
return void 0;
|
|
967
|
+
}
|
|
968
|
+
const collectionName = normalizeLegacyChartRequiredString(collectionPath[1]);
|
|
969
|
+
if (!collectionName) {
|
|
970
|
+
return void 0;
|
|
971
|
+
}
|
|
972
|
+
const dataSourceKey = normalizeLegacyChartCollectionPathDataSourceKey(collectionPath[0]);
|
|
973
|
+
if (!dataSourceKey) {
|
|
974
|
+
return void 0;
|
|
975
|
+
}
|
|
976
|
+
return {
|
|
977
|
+
dataSourceKey,
|
|
978
|
+
collectionName
|
|
675
979
|
};
|
|
676
980
|
}
|
|
981
|
+
function normalizeLegacyChartResourceForValidation(resource, path, errors) {
|
|
982
|
+
if (!_.isPlainObject(resource)) {
|
|
983
|
+
pushAuthoringError(errors, {
|
|
984
|
+
path,
|
|
985
|
+
ruleId: "chart-legacy-query-resource-invalid",
|
|
986
|
+
message: `flowSurfaces authoring ${path} must be an object with string collectionName`,
|
|
987
|
+
details: withChartRepairHint()
|
|
988
|
+
});
|
|
989
|
+
return void 0;
|
|
990
|
+
}
|
|
991
|
+
const collectionName = normalizeLegacyChartRequiredString(resource.collectionName);
|
|
992
|
+
if (!collectionName) {
|
|
993
|
+
pushAuthoringError(errors, {
|
|
994
|
+
path: `${path}.collectionName`,
|
|
995
|
+
ruleId: "chart-legacy-query-resource-invalid",
|
|
996
|
+
message: `flowSurfaces authoring ${path}.collectionName must be a non-empty string`,
|
|
997
|
+
details: withChartRepairHint()
|
|
998
|
+
});
|
|
999
|
+
return void 0;
|
|
1000
|
+
}
|
|
1001
|
+
const dataSourceKey = normalizeLegacyChartResourceDataSourceKey(resource.dataSourceKey);
|
|
1002
|
+
if (!dataSourceKey) {
|
|
1003
|
+
pushAuthoringError(errors, {
|
|
1004
|
+
path: `${path}.dataSourceKey`,
|
|
1005
|
+
ruleId: "chart-legacy-query-resource-invalid",
|
|
1006
|
+
message: `flowSurfaces authoring ${path}.dataSourceKey must be a non-empty string when provided`,
|
|
1007
|
+
details: withChartRepairHint()
|
|
1008
|
+
});
|
|
1009
|
+
return void 0;
|
|
1010
|
+
}
|
|
1011
|
+
return {
|
|
1012
|
+
dataSourceKey,
|
|
1013
|
+
collectionName
|
|
1014
|
+
};
|
|
1015
|
+
}
|
|
1016
|
+
function normalizeLegacyChartCollectionPathResourceForValidation(collectionPath, path, errors) {
|
|
1017
|
+
const resource = normalizeLegacyChartCollectionPathResource(collectionPath);
|
|
1018
|
+
if (!resource) {
|
|
1019
|
+
pushAuthoringError(errors, {
|
|
1020
|
+
path,
|
|
1021
|
+
ruleId: "chart-legacy-query-collection-path-invalid",
|
|
1022
|
+
message: `flowSurfaces authoring ${path} must be [dataSourceKey, collectionName] with string values and a non-empty collectionName`,
|
|
1023
|
+
details: withChartRepairHint()
|
|
1024
|
+
});
|
|
1025
|
+
}
|
|
1026
|
+
return resource;
|
|
1027
|
+
}
|
|
1028
|
+
function normalizeLegacyChartRequiredString(input) {
|
|
1029
|
+
if (typeof input !== "string") {
|
|
1030
|
+
return void 0;
|
|
1031
|
+
}
|
|
1032
|
+
return input.trim() || void 0;
|
|
1033
|
+
}
|
|
1034
|
+
function normalizeLegacyChartResourceDataSourceKey(input) {
|
|
1035
|
+
if (_.isUndefined(input) || _.isNull(input)) {
|
|
1036
|
+
return CHART_DEFAULT_DATA_SOURCE_KEY;
|
|
1037
|
+
}
|
|
1038
|
+
return normalizeLegacyChartRequiredString(input);
|
|
1039
|
+
}
|
|
1040
|
+
function normalizeLegacyChartCollectionPathDataSourceKey(input) {
|
|
1041
|
+
if (_.isUndefined(input) || _.isNull(input)) {
|
|
1042
|
+
return CHART_DEFAULT_DATA_SOURCE_KEY;
|
|
1043
|
+
}
|
|
1044
|
+
if (typeof input === "string" && !input.trim()) {
|
|
1045
|
+
return CHART_DEFAULT_DATA_SOURCE_KEY;
|
|
1046
|
+
}
|
|
1047
|
+
return normalizeLegacyChartRequiredString(input);
|
|
1048
|
+
}
|
|
677
1049
|
function collectChartBlockAssetReferenceErrors(block, path, chartAssets, errors) {
|
|
678
1050
|
if (!CHART_BLOCK_TYPES.has(String((block == null ? void 0 : block.type) || "").trim())) {
|
|
679
1051
|
return;
|
|
@@ -781,8 +1153,85 @@ function collectBuilderChartAssetQueryErrors(query, path, context, errors) {
|
|
|
781
1153
|
errors,
|
|
782
1154
|
withChartRepairHint()
|
|
783
1155
|
);
|
|
1156
|
+
collectChartQueryFilterOperatorErrors(query, `${path}.query`, errors);
|
|
784
1157
|
collectBuilderChartAssetFieldErrors(query, path, context, errors);
|
|
785
1158
|
}
|
|
1159
|
+
function collectChartQueryFilterOperatorErrors(query, path, errors) {
|
|
1160
|
+
if (!_.isPlainObject(query) || !hasOwn(query, "filter")) {
|
|
1161
|
+
return;
|
|
1162
|
+
}
|
|
1163
|
+
collectChartFilterOperatorErrors(query.filter, `${path}.filter`, errors);
|
|
1164
|
+
}
|
|
1165
|
+
function collectChartFilterOperatorErrors(filter, path, errors) {
|
|
1166
|
+
if (_.isUndefined(filter) || _.isNull(filter) || !_.isPlainObject(filter)) {
|
|
1167
|
+
return;
|
|
1168
|
+
}
|
|
1169
|
+
if (Array.isArray(filter.items)) {
|
|
1170
|
+
collectChartFilterGroupOperatorErrors(filter.items, `${path}.items`, errors);
|
|
1171
|
+
return;
|
|
1172
|
+
}
|
|
1173
|
+
collectBackendQueryFilterOperatorErrors(filter, path, errors);
|
|
1174
|
+
}
|
|
1175
|
+
function collectChartFilterGroupOperatorErrors(items, path, errors) {
|
|
1176
|
+
items.forEach((item, index) => {
|
|
1177
|
+
const itemPath = `${path}[${index}]`;
|
|
1178
|
+
if (!_.isPlainObject(item)) {
|
|
1179
|
+
return;
|
|
1180
|
+
}
|
|
1181
|
+
if (Array.isArray(item.items)) {
|
|
1182
|
+
collectChartFilterGroupOperatorErrors(item.items, `${itemPath}.items`, errors);
|
|
1183
|
+
return;
|
|
1184
|
+
}
|
|
1185
|
+
if (hasOwn(item, "operator")) {
|
|
1186
|
+
collectChartFilterOperatorError(item.operator, `${itemPath}.operator`, errors);
|
|
1187
|
+
collectChartFilterDateValueError(item.operator, item.value, `${itemPath}.value`, errors);
|
|
1188
|
+
}
|
|
1189
|
+
});
|
|
1190
|
+
}
|
|
1191
|
+
function collectBackendQueryFilterOperatorErrors(filter, path, errors) {
|
|
1192
|
+
Object.entries(filter).forEach(([field, condition]) => {
|
|
1193
|
+
const fieldPath = `${path}.${field}`;
|
|
1194
|
+
if ((field === "$and" || field === "$or") && Array.isArray(condition)) {
|
|
1195
|
+
condition.forEach(
|
|
1196
|
+
(operand, index) => collectChartFilterOperatorErrors(operand, `${fieldPath}[${index}]`, errors)
|
|
1197
|
+
);
|
|
1198
|
+
return;
|
|
1199
|
+
}
|
|
1200
|
+
if (!_.isPlainObject(condition)) {
|
|
1201
|
+
return;
|
|
1202
|
+
}
|
|
1203
|
+
Object.keys(condition).forEach((operator) => {
|
|
1204
|
+
if (operator === "$and" || operator === "$or") {
|
|
1205
|
+
collectChartFilterOperatorErrors({ [operator]: condition[operator] }, fieldPath, errors);
|
|
1206
|
+
return;
|
|
1207
|
+
}
|
|
1208
|
+
collectChartFilterOperatorError(operator, `${fieldPath}.${operator}`, errors);
|
|
1209
|
+
collectChartFilterDateValueError(operator, condition[operator], `${fieldPath}.${operator}`, errors);
|
|
1210
|
+
});
|
|
1211
|
+
});
|
|
1212
|
+
}
|
|
1213
|
+
function collectChartFilterOperatorError(operator, path, errors) {
|
|
1214
|
+
try {
|
|
1215
|
+
(0, import_filter_group.assertFlowSurfaceFilterOperator)(operator, path);
|
|
1216
|
+
} catch (error) {
|
|
1217
|
+
if (error instanceof import_errors.FlowSurfaceBadRequestError) {
|
|
1218
|
+
pushChartBadRequestAuthoringError(errors, error, path);
|
|
1219
|
+
return;
|
|
1220
|
+
}
|
|
1221
|
+
throw error;
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
function collectChartFilterDateValueError(operator, value, path, errors) {
|
|
1225
|
+
try {
|
|
1226
|
+
(0, import_filter_group.normalizeFlowSurfaceFilterDateValue)(operator, value, path);
|
|
1227
|
+
} catch (error) {
|
|
1228
|
+
if (error instanceof import_errors.FlowSurfaceBadRequestError) {
|
|
1229
|
+
pushChartBadRequestAuthoringError(errors, error, path);
|
|
1230
|
+
return;
|
|
1231
|
+
}
|
|
1232
|
+
throw error;
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
786
1235
|
function normalizeChartAssetFieldPath(input) {
|
|
787
1236
|
if (Array.isArray(input)) {
|
|
788
1237
|
return input.map((item) => String(item || "").trim()).filter(Boolean).join(".");
|
|
@@ -3385,10 +3834,13 @@ function collectBlockErrors(block, path, errors, localKeys, context) {
|
|
|
3385
3834
|
collectVisibleDataBlockFieldErrors(block, blockType, path, errors, context);
|
|
3386
3835
|
collectCommentsBlockErrors(block, blockType, path, errors, context);
|
|
3387
3836
|
collectRecordHistoryBlockErrors(block, blockType, path, errors, context);
|
|
3837
|
+
collectLocalizedChartSettingsErrors(block, blockType, path, errors, context);
|
|
3388
3838
|
collectChartDisplayTitleErrors(block, blockType, path, errors);
|
|
3389
3839
|
collectTreeTableExplicitFieldsErrors(block, blockType, path, errors, context);
|
|
3390
3840
|
collectTreeConnectFieldsErrors((_a = block.settings) == null ? void 0 : _a.connectFields, `${path}.settings.connectFields`, errors);
|
|
3391
|
-
collectTableSettingsErrors(block, blockType, path, errors
|
|
3841
|
+
collectTableSettingsErrors(block, blockType, path, errors, {
|
|
3842
|
+
deferPublicDataScopeErrors: context.authoringActionName === "addBlocks"
|
|
3843
|
+
});
|
|
3392
3844
|
collectGridCardSettingsErrors(block, blockType, path, errors);
|
|
3393
3845
|
const descendantContext = getBlockDescendantValidationContext(block, context);
|
|
3394
3846
|
collectActionListErrors(block.actions, `${path}.actions`, errors, block, descendantContext, "actions");
|
|
@@ -3646,6 +4098,7 @@ function collectFieldGroupsShapeErrors(fieldGroups, blockPath, errors, block, co
|
|
|
3646
4098
|
if (fieldPath) {
|
|
3647
4099
|
collectUnknownFieldPathError(fieldPath, itemPath, block, context, errors);
|
|
3648
4100
|
}
|
|
4101
|
+
collectImplicitRelationTitleFieldErrors(field, itemPath, block, context, errors);
|
|
3649
4102
|
if (!_.isPlainObject(field)) {
|
|
3650
4103
|
return;
|
|
3651
4104
|
}
|
|
@@ -3695,6 +4148,7 @@ async function collectConfigureErrors(values, errors, context) {
|
|
|
3695
4148
|
collectCommentsBlockErrors(changesBlock, hostBlockType, "$.changes", errors, context);
|
|
3696
4149
|
collectRecordHistoryBlockErrors(changesBlock, hostBlockType, "$.changes", errors, context);
|
|
3697
4150
|
collectChartDisplayTitleErrors(changes, hostBlockType, "$.changes", errors);
|
|
4151
|
+
collectChartConfigureFilterOperatorErrors(changes, hostBlockType, "$.changes", errors);
|
|
3698
4152
|
collectTableSettingsErrors(changes, hostBlockType, "$.changes", errors, { directSettings: true });
|
|
3699
4153
|
collectGridCardSettingsErrors(changes, hostBlockType, "$.changes", errors, { directSettings: true });
|
|
3700
4154
|
collectAssignValuesErrors(changes.assignValues, "$.changes.assignValues", errors, changesBlock, context);
|
|
@@ -4783,6 +5237,15 @@ function collectChartDisplayTitleErrors(block, blockType, blockPath, errors) {
|
|
|
4783
5237
|
message: "Chart block settings do not support displayTitle in the current flowSurfaces runtime; keep settings.title and omit displayTitle."
|
|
4784
5238
|
});
|
|
4785
5239
|
}
|
|
5240
|
+
function collectChartConfigureFilterOperatorErrors(changes, hostBlockType, path, errors) {
|
|
5241
|
+
if (hostBlockType !== "chart" || !_.isPlainObject(changes)) {
|
|
5242
|
+
return;
|
|
5243
|
+
}
|
|
5244
|
+
collectChartQueryFilterOperatorErrors(changes.query, `${path}.query`, errors);
|
|
5245
|
+
if (_.isPlainObject(changes.configure)) {
|
|
5246
|
+
collectChartQueryFilterOperatorErrors(changes.configure.query, `${path}.configure.query`, errors);
|
|
5247
|
+
}
|
|
5248
|
+
}
|
|
4786
5249
|
function visitFilterItems(value, path, errors, block, context = {}) {
|
|
4787
5250
|
if (Array.isArray(value)) {
|
|
4788
5251
|
value.forEach((item, index) => visitFilterItems(item, `${path}[${index}]`, errors, block, context));
|
|
@@ -5198,6 +5661,9 @@ function collectTableSettingsErrors(block, blockType, blockPath, errors, options
|
|
|
5198
5661
|
}
|
|
5199
5662
|
pushTableSettingsUnsupportedError(errors, `${settingsPath}.${key}`, key);
|
|
5200
5663
|
});
|
|
5664
|
+
if (!shouldDeferPublicDataScopeErrorsToBatchItem(blockPath, errors, options)) {
|
|
5665
|
+
collectPublicDataScopeErrors(settings.dataScope, `${settingsPath}.dataScope`, errors);
|
|
5666
|
+
}
|
|
5201
5667
|
}
|
|
5202
5668
|
function pushTableSettingsUnsupportedError(errors, path, key) {
|
|
5203
5669
|
pushAuthoringError(errors, {
|
|
@@ -5211,6 +5677,47 @@ function pushTableSettingsUnsupportedError(errors, path, key) {
|
|
|
5211
5677
|
}
|
|
5212
5678
|
});
|
|
5213
5679
|
}
|
|
5680
|
+
function collectPublicDataScopeErrors(value, path, errors) {
|
|
5681
|
+
if (_.isUndefined(value)) {
|
|
5682
|
+
return;
|
|
5683
|
+
}
|
|
5684
|
+
if (value === null || _.isPlainObject(value) && !Object.keys(value).length) {
|
|
5685
|
+
return;
|
|
5686
|
+
}
|
|
5687
|
+
const validationValue = normalizePublicDataScopeValueForValidation(value);
|
|
5688
|
+
try {
|
|
5689
|
+
(0, import_filter_group.assertFlowSurfaceFilterGroupShape)(validationValue);
|
|
5690
|
+
} catch (error) {
|
|
5691
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
5692
|
+
pushAuthoringError(errors, {
|
|
5693
|
+
path,
|
|
5694
|
+
ruleId: "dataScope-filter-group-invalid-shape",
|
|
5695
|
+
message: `flowSurfaces authoring ${path} expects FilterGroup like ${import_filter_group.FLOW_SURFACE_FILTER_GROUP_EXAMPLE}: ${reason}`,
|
|
5696
|
+
details: {
|
|
5697
|
+
repairHint: 'Use settings.dataScope with logic/items, for example {"logic":"$and","items":[{"path":"status","operator":"$eq","value":"Active"}]}; do not use a field-name map.'
|
|
5698
|
+
}
|
|
5699
|
+
});
|
|
5700
|
+
}
|
|
5701
|
+
}
|
|
5702
|
+
function shouldDeferPublicDataScopeErrorsToBatchItem(blockPath, errors, options) {
|
|
5703
|
+
if (options.deferPublicDataScopeErrors !== true) {
|
|
5704
|
+
return false;
|
|
5705
|
+
}
|
|
5706
|
+
if (!/^\$\.blocks\[\d+\]$/.test(blockPath)) {
|
|
5707
|
+
return false;
|
|
5708
|
+
}
|
|
5709
|
+
return !errors.some((error) => error.path === `${blockPath}.settings.dataScope`);
|
|
5710
|
+
}
|
|
5711
|
+
function normalizePublicDataScopeValueForValidation(value) {
|
|
5712
|
+
if (!_.isPlainObject(value)) {
|
|
5713
|
+
return value;
|
|
5714
|
+
}
|
|
5715
|
+
const keys = Object.keys(value);
|
|
5716
|
+
if (keys.length === 1 && keys[0] === "filter") {
|
|
5717
|
+
return value.filter;
|
|
5718
|
+
}
|
|
5719
|
+
return value;
|
|
5720
|
+
}
|
|
5214
5721
|
function collectGridCardSettingsErrors(block, blockType, blockPath, errors, options = {}) {
|
|
5215
5722
|
const hasSettings = _.isPlainObject(block == null ? void 0 : block.settings);
|
|
5216
5723
|
if (!hasSettings && options.directSettings !== true) {
|
|
@@ -5851,6 +6358,7 @@ function collectFieldListErrors(fields, path, errors, localKeys, context, block)
|
|
|
5851
6358
|
if (fieldPath) {
|
|
5852
6359
|
collectUnknownFieldPathError(fieldPath, `${path}[${index}]`, block, context, errors);
|
|
5853
6360
|
}
|
|
6361
|
+
collectImplicitRelationTitleFieldErrors(field, `${path}[${index}]`, block, context, errors);
|
|
5854
6362
|
if (!_.isPlainObject(field)) {
|
|
5855
6363
|
return;
|
|
5856
6364
|
}
|
|
@@ -6171,6 +6679,106 @@ function collectRelationTitleFieldErrors(fieldSpec, path, block, context, errors
|
|
|
6171
6679
|
})
|
|
6172
6680
|
});
|
|
6173
6681
|
}
|
|
6682
|
+
function collectImplicitRelationTitleFieldErrors(fieldSpec, path, block, context, errors) {
|
|
6683
|
+
var _a;
|
|
6684
|
+
if (context.authoringActionName !== "applyBlueprint") {
|
|
6685
|
+
return;
|
|
6686
|
+
}
|
|
6687
|
+
const hostBlockType = String((block == null ? void 0 : block.type) || "").trim();
|
|
6688
|
+
if (!IMPLICIT_RELATION_TITLE_FIELD_DISPLAY_BLOCK_TYPES.has(hostBlockType)) {
|
|
6689
|
+
return;
|
|
6690
|
+
}
|
|
6691
|
+
if (_.isPlainObject(fieldSpec) && fieldSpec.__autoPopupForRelationField === true) {
|
|
6692
|
+
return;
|
|
6693
|
+
}
|
|
6694
|
+
if (_.isPlainObject(fieldSpec) && Object.prototype.hasOwnProperty.call(fieldSpec, "titleField")) {
|
|
6695
|
+
return;
|
|
6696
|
+
}
|
|
6697
|
+
const fieldPath = getFieldPathInput(fieldSpec);
|
|
6698
|
+
if (!fieldPath || fieldPath.includes(".")) {
|
|
6699
|
+
return;
|
|
6700
|
+
}
|
|
6701
|
+
const collection = getBlockCollection(block, context);
|
|
6702
|
+
if (!collection || !context.getCollection) {
|
|
6703
|
+
return;
|
|
6704
|
+
}
|
|
6705
|
+
const resolvedField = (0, import_service_helpers.resolveFieldFromCollection)(collection, (0, import_service_helpers.normalizeFieldPath)(fieldPath));
|
|
6706
|
+
if (!resolvedField || !(0, import_service_helpers.isAssociationField)(resolvedField)) {
|
|
6707
|
+
return;
|
|
6708
|
+
}
|
|
6709
|
+
const dataSourceKey = getBlockDataSourceKey(block, context);
|
|
6710
|
+
if (hasUsableDefaultFieldGroupRelationTitleField({
|
|
6711
|
+
fieldGroups: (_a = context.getDefaultFieldGroups) == null ? void 0 : _a.call(context, dataSourceKey, getBlockCollectionName(block, context)),
|
|
6712
|
+
fieldPath,
|
|
6713
|
+
field: resolvedField,
|
|
6714
|
+
dataSourceKey,
|
|
6715
|
+
context
|
|
6716
|
+
})) {
|
|
6717
|
+
return;
|
|
6718
|
+
}
|
|
6719
|
+
const registeredBinding = (0, import_field_binding_registry.resolveRegisteredFieldBinding)({
|
|
6720
|
+
containerUse: IMPLICIT_RELATION_TITLE_FIELD_CONTAINER_USE_BY_BLOCK_TYPE[hostBlockType],
|
|
6721
|
+
field: resolvedField,
|
|
6722
|
+
dataSourceKey,
|
|
6723
|
+
enabledPackages: context.enabledPackages,
|
|
6724
|
+
getCollection: (resolvedDataSourceKey, targetCollectionName) => {
|
|
6725
|
+
var _a2;
|
|
6726
|
+
return (_a2 = context.getCollection) == null ? void 0 : _a2.call(context, resolvedDataSourceKey, targetCollectionName);
|
|
6727
|
+
},
|
|
6728
|
+
useStrictOnly: true
|
|
6729
|
+
});
|
|
6730
|
+
if (registeredBinding == null ? void 0 : registeredBinding.modelClassName) {
|
|
6731
|
+
return;
|
|
6732
|
+
}
|
|
6733
|
+
try {
|
|
6734
|
+
const resolvedTitleField = (0, import_association_title_field.resolveAssociationSafeTitleField)(resolvedField, dataSourceKey, context.getCollection, {
|
|
6735
|
+
action: context.authoringActionName,
|
|
6736
|
+
path: `${path}.titleField`,
|
|
6737
|
+
fieldPath
|
|
6738
|
+
});
|
|
6739
|
+
if (!(resolvedTitleField == null ? void 0 : resolvedTitleField.fieldName)) {
|
|
6740
|
+
pushAuthoringError(errors, {
|
|
6741
|
+
path: `${path}.titleField`,
|
|
6742
|
+
ruleId: "relation-titleField-unavailable",
|
|
6743
|
+
message: `flowSurfaces authoring ${path} relation field '${fieldPath}' requires an explicit readable titleField`,
|
|
6744
|
+
details: {
|
|
6745
|
+
fieldPath,
|
|
6746
|
+
repairHint: `Use object field form such as {"field":"${fieldPath}","titleField":"<readable target field>"}.`
|
|
6747
|
+
}
|
|
6748
|
+
});
|
|
6749
|
+
}
|
|
6750
|
+
} catch (error) {
|
|
6751
|
+
if (!(error instanceof import_errors.FlowSurfaceBadRequestError)) {
|
|
6752
|
+
throw error;
|
|
6753
|
+
}
|
|
6754
|
+
pushAuthoringError(errors, {
|
|
6755
|
+
path: `${path}.titleField`,
|
|
6756
|
+
ruleId: error.options.ruleId || "relation-titleField-unavailable",
|
|
6757
|
+
message: `flowSurfaces authoring ${path} relation field '${fieldPath}' requires an explicit readable titleField`,
|
|
6758
|
+
details: {
|
|
6759
|
+
...error.options.details || {},
|
|
6760
|
+
fieldPath,
|
|
6761
|
+
repairHint: `Use object field form such as {"field":"${fieldPath}","titleField":"<readable target field>"}.`
|
|
6762
|
+
}
|
|
6763
|
+
});
|
|
6764
|
+
}
|
|
6765
|
+
}
|
|
6766
|
+
function hasUsableDefaultFieldGroupRelationTitleField(input) {
|
|
6767
|
+
const titleField = (0, import_defaults.getFlowSurfaceDefaultFieldGroupRelationTitleFieldOverride)(input.fieldGroups, input.fieldPath);
|
|
6768
|
+
if (!titleField || titleField === "id" || !input.context.getCollection) {
|
|
6769
|
+
return false;
|
|
6770
|
+
}
|
|
6771
|
+
const targetCollection = (0, import_service_helpers.resolveFieldTargetCollection)(
|
|
6772
|
+
input.field,
|
|
6773
|
+
input.dataSourceKey,
|
|
6774
|
+
(dataSourceKey, collectionName) => {
|
|
6775
|
+
var _a, _b;
|
|
6776
|
+
return (_b = (_a = input.context).getCollection) == null ? void 0 : _b.call(_a, dataSourceKey, collectionName);
|
|
6777
|
+
}
|
|
6778
|
+
);
|
|
6779
|
+
const targetField = targetCollection ? (0, import_service_helpers.resolveFieldFromCollection)(targetCollection, titleField) : void 0;
|
|
6780
|
+
return !!targetField && !(0, import_service_helpers.isAssociationField)(targetField);
|
|
6781
|
+
}
|
|
6174
6782
|
function getRelationTitleFieldInvalidReason(titleField, targetField) {
|
|
6175
6783
|
if (titleField === "id") {
|
|
6176
6784
|
return "id";
|