@acorex-platform/module-platform-management-client 0.0.38 → 0.0.48
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/fesm2022/{acorex-platform-module-platform-management-client-acorex-platform-module-platform-management-client-BGVhn6wv.mjs → acorex-platform-module-platform-management-client-acorex-platform-module-platform-management-client-YuJijjKh.mjs} +465 -101
- package/fesm2022/acorex-platform-module-platform-management-client-acorex-platform-module-platform-management-client-YuJijjKh.mjs.map +1 -0
- package/fesm2022/acorex-platform-module-platform-management-client-contracts-entities-command-definition.mjs +20 -0
- package/fesm2022/acorex-platform-module-platform-management-client-contracts-entities-command-definition.mjs.map +1 -1
- package/fesm2022/acorex-platform-module-platform-management-client-contracts-entities-entity-access-policy.mjs +20 -0
- package/fesm2022/acorex-platform-module-platform-management-client-contracts-entities-entity-access-policy.mjs.map +1 -1
- package/fesm2022/acorex-platform-module-platform-management-client-contracts-entities-entity-definition.mjs +1499 -30
- package/fesm2022/acorex-platform-module-platform-management-client-contracts-entities-entity-definition.mjs.map +1 -1
- package/fesm2022/acorex-platform-module-platform-management-client-contracts-entities-module-definition.mjs +396 -0
- package/fesm2022/acorex-platform-module-platform-management-client-contracts-entities-module-definition.mjs.map +1 -0
- package/fesm2022/acorex-platform-module-platform-management-client-contracts-entities-plugin-definition.mjs +20 -0
- package/fesm2022/acorex-platform-module-platform-management-client-contracts-entities-plugin-definition.mjs.map +1 -1
- package/fesm2022/acorex-platform-module-platform-management-client-contracts-entities-query-definition.mjs +49 -1
- package/fesm2022/acorex-platform-module-platform-management-client-contracts-entities-query-definition.mjs.map +1 -1
- package/fesm2022/acorex-platform-module-platform-management-client-contracts-entities-token.mjs +20 -0
- package/fesm2022/acorex-platform-module-platform-management-client-contracts-entities-token.mjs.map +1 -1
- package/fesm2022/acorex-platform-module-platform-management-client-contracts-entities-widget.mjs +20 -0
- package/fesm2022/acorex-platform-module-platform-management-client-contracts-entities-widget.mjs.map +1 -1
- package/fesm2022/{acorex-platform-module-platform-management-client-contracts-entity-catalog-acorex-platform-module-platform-management-client-contracts-entity-catalog-BOwC5Ns9.mjs → acorex-platform-module-platform-management-client-contracts-entity-catalog-acorex-platform-module-platform-management-client-contracts-entity-catalog-HWczTPH2.mjs} +15 -8
- package/fesm2022/acorex-platform-module-platform-management-client-contracts-entity-catalog-acorex-platform-module-platform-management-client-contracts-entity-catalog-HWczTPH2.mjs.map +1 -0
- package/fesm2022/{acorex-platform-module-platform-management-client-contracts-entity-catalog-command-definition.entity-CdvQlwAk.mjs → acorex-platform-module-platform-management-client-contracts-entity-catalog-command-definition.entity-C3B1_QMs.mjs} +16 -2
- package/fesm2022/acorex-platform-module-platform-management-client-contracts-entity-catalog-command-definition.entity-C3B1_QMs.mjs.map +1 -0
- package/fesm2022/{acorex-platform-module-platform-management-client-contracts-entity-catalog-entity-access-policy.entity-Dye4aSKE.mjs → acorex-platform-module-platform-management-client-contracts-entity-catalog-entity-access-policy.entity-BPkJloHy.mjs} +16 -2
- package/fesm2022/acorex-platform-module-platform-management-client-contracts-entity-catalog-entity-access-policy.entity-BPkJloHy.mjs.map +1 -0
- package/fesm2022/acorex-platform-module-platform-management-client-contracts-entity-catalog-entity-definition.entity-BL1I9pmK.mjs +1621 -0
- package/fesm2022/acorex-platform-module-platform-management-client-contracts-entity-catalog-entity-definition.entity-BL1I9pmK.mjs.map +1 -0
- package/fesm2022/acorex-platform-module-platform-management-client-contracts-entity-catalog-module-definition.entity-Cknl0vbc.mjs +299 -0
- package/fesm2022/acorex-platform-module-platform-management-client-contracts-entity-catalog-module-definition.entity-Cknl0vbc.mjs.map +1 -0
- package/fesm2022/{acorex-platform-module-platform-management-client-contracts-entity-catalog-plugin-definition.entity-CwU5hMjI.mjs → acorex-platform-module-platform-management-client-contracts-entity-catalog-plugin-definition.entity-BxABTl8L.mjs} +16 -2
- package/fesm2022/acorex-platform-module-platform-management-client-contracts-entity-catalog-plugin-definition.entity-BxABTl8L.mjs.map +1 -0
- package/fesm2022/{acorex-platform-module-platform-management-client-contracts-entity-catalog-query-definition.entity-DGK684Q1.mjs → acorex-platform-module-platform-management-client-contracts-entity-catalog-query-definition.entity-Cv6HVQOU.mjs} +45 -3
- package/fesm2022/acorex-platform-module-platform-management-client-contracts-entity-catalog-query-definition.entity-Cv6HVQOU.mjs.map +1 -0
- package/fesm2022/{acorex-platform-module-platform-management-client-contracts-entity-catalog-token.entity-DI_k6-ha.mjs → acorex-platform-module-platform-management-client-contracts-entity-catalog-token.entity-BV8iSuoK.mjs} +16 -2
- package/fesm2022/acorex-platform-module-platform-management-client-contracts-entity-catalog-token.entity-BV8iSuoK.mjs.map +1 -0
- package/fesm2022/{acorex-platform-module-platform-management-client-contracts-entity-catalog-widget.entity-C18msniH.mjs → acorex-platform-module-platform-management-client-contracts-entity-catalog-widget.entity-BYH6SIqU.mjs} +16 -2
- package/fesm2022/acorex-platform-module-platform-management-client-contracts-entity-catalog-widget.entity-BYH6SIqU.mjs.map +1 -0
- package/fesm2022/acorex-platform-module-platform-management-client-contracts-entity-catalog.mjs +1 -1
- package/fesm2022/acorex-platform-module-platform-management-client-contracts.mjs +1664 -1
- package/fesm2022/acorex-platform-module-platform-management-client-contracts.mjs.map +1 -1
- package/fesm2022/acorex-platform-module-platform-management-client-create-user-query-contract.util-D_af2BUi.mjs +586 -0
- package/fesm2022/acorex-platform-module-platform-management-client-create-user-query-contract.util-D_af2BUi.mjs.map +1 -0
- package/fesm2022/{acorex-platform-module-platform-management-client-create-user-query.command-9Ku7C1BC.mjs → acorex-platform-module-platform-management-client-create-user-query.command-Bh49QHkl.mjs} +374 -324
- package/fesm2022/acorex-platform-module-platform-management-client-create-user-query.command-Bh49QHkl.mjs.map +1 -0
- package/fesm2022/acorex-platform-module-platform-management-client-entity-definition-form-page.component-BgBWob9p.mjs +329 -0
- package/fesm2022/acorex-platform-module-platform-management-client-entity-definition-form-page.component-BgBWob9p.mjs.map +1 -0
- package/fesm2022/acorex-platform-module-platform-management-client-entity-definition-form-page.provider-hLzgoJu3.mjs +23 -0
- package/fesm2022/acorex-platform-module-platform-management-client-entity-definition-form-page.provider-hLzgoJu3.mjs.map +1 -0
- package/fesm2022/acorex-platform-module-platform-management-client-list-registered-entities.query-CZM6JQou.mjs +197 -0
- package/fesm2022/acorex-platform-module-platform-management-client-list-registered-entities.query-CZM6JQou.mjs.map +1 -0
- package/fesm2022/acorex-platform-module-platform-management-client-local-entities.mjs +1 -0
- package/fesm2022/acorex-platform-module-platform-management-client-local-entities.mjs.map +1 -1
- package/fesm2022/{acorex-platform-module-platform-management-client-menu-list.component-uF5w1c7t.mjs → acorex-platform-module-platform-management-client-menu-list.component-iMEnFPEY.mjs} +2 -2
- package/fesm2022/{acorex-platform-module-platform-management-client-menu-list.component-uF5w1c7t.mjs.map → acorex-platform-module-platform-management-client-menu-list.component-iMEnFPEY.mjs.map} +1 -1
- package/fesm2022/acorex-platform-module-platform-management-client-query-contract-widget-column.component-COfOzMGh.mjs +45 -0
- package/fesm2022/acorex-platform-module-platform-management-client-query-contract-widget-column.component-COfOzMGh.mjs.map +1 -0
- package/fesm2022/acorex-platform-module-platform-management-client-query-contract-widget-edit.component-BW2pBOeg.mjs +166 -0
- package/fesm2022/acorex-platform-module-platform-management-client-query-contract-widget-edit.component-BW2pBOeg.mjs.map +1 -0
- package/fesm2022/acorex-platform-module-platform-management-client-query-contract-widget-view.component-DD9ETjFD.mjs +45 -0
- package/fesm2022/acorex-platform-module-platform-management-client-query-contract-widget-view.component-DD9ETjFD.mjs.map +1 -0
- package/fesm2022/{acorex-platform-module-platform-management-client-rest-api-generator-widget-column.component-B0g6dweQ.mjs → acorex-platform-module-platform-management-client-rest-api-generator-widget-column.component-DRkE2a7n.mjs} +2 -2
- package/fesm2022/{acorex-platform-module-platform-management-client-rest-api-generator-widget-column.component-B0g6dweQ.mjs.map → acorex-platform-module-platform-management-client-rest-api-generator-widget-column.component-DRkE2a7n.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-module-platform-management-client-rest-api-generator-widget-edit.component-A0v5MWRU.mjs → acorex-platform-module-platform-management-client-rest-api-generator-widget-edit.component-CXI6fJi3.mjs} +2 -3
- package/fesm2022/{acorex-platform-module-platform-management-client-rest-api-generator-widget-edit.component-A0v5MWRU.mjs.map → acorex-platform-module-platform-management-client-rest-api-generator-widget-edit.component-CXI6fJi3.mjs.map} +1 -1
- package/fesm2022/{acorex-platform-module-platform-management-client-rest-api-generator-widget-view.component-RR5zcsnI.mjs → acorex-platform-module-platform-management-client-rest-api-generator-widget-view.component-C3iHgoC2.mjs} +2 -2
- package/fesm2022/{acorex-platform-module-platform-management-client-rest-api-generator-widget-view.component-RR5zcsnI.mjs.map → acorex-platform-module-platform-management-client-rest-api-generator-widget-view.component-C3iHgoC2.mjs.map} +1 -1
- package/fesm2022/acorex-platform-module-platform-management-client-run-user-query.command-BzNa3B48.mjs +144 -0
- package/fesm2022/acorex-platform-module-platform-management-client-run-user-query.command-BzNa3B48.mjs.map +1 -0
- package/fesm2022/acorex-platform-module-platform-management-client.mjs +1 -1
- package/package.json +7 -3
- package/types/acorex-platform-module-platform-management-client-contracts-entities-module-definition.d.ts +5 -0
- package/types/acorex-platform-module-platform-management-client-contracts.d.ts +225 -5
- package/types/acorex-platform-module-platform-management-client.d.ts +35 -3
- package/fesm2022/acorex-platform-module-platform-management-client-acorex-platform-module-platform-management-client-BGVhn6wv.mjs.map +0 -1
- package/fesm2022/acorex-platform-module-platform-management-client-contracts-entity-catalog-acorex-platform-module-platform-management-client-contracts-entity-catalog-BOwC5Ns9.mjs.map +0 -1
- package/fesm2022/acorex-platform-module-platform-management-client-contracts-entity-catalog-command-definition.entity-CdvQlwAk.mjs.map +0 -1
- package/fesm2022/acorex-platform-module-platform-management-client-contracts-entity-catalog-entity-access-policy.entity-Dye4aSKE.mjs.map +0 -1
- package/fesm2022/acorex-platform-module-platform-management-client-contracts-entity-catalog-entity-definition.entity-CcJ58vfr.mjs +0 -158
- package/fesm2022/acorex-platform-module-platform-management-client-contracts-entity-catalog-entity-definition.entity-CcJ58vfr.mjs.map +0 -1
- package/fesm2022/acorex-platform-module-platform-management-client-contracts-entity-catalog-plugin-definition.entity-CwU5hMjI.mjs.map +0 -1
- package/fesm2022/acorex-platform-module-platform-management-client-contracts-entity-catalog-query-definition.entity-DGK684Q1.mjs.map +0 -1
- package/fesm2022/acorex-platform-module-platform-management-client-contracts-entity-catalog-token.entity-DI_k6-ha.mjs.map +0 -1
- package/fesm2022/acorex-platform-module-platform-management-client-contracts-entity-catalog-widget.entity-C18msniH.mjs.map +0 -1
- package/fesm2022/acorex-platform-module-platform-management-client-create-user-query.command-9Ku7C1BC.mjs.map +0 -1
- package/fesm2022/acorex-platform-module-platform-management-client-create-user-query.types-DdygAori.mjs +0 -71
- package/fesm2022/acorex-platform-module-platform-management-client-create-user-query.types-DdygAori.mjs.map +0 -1
- package/fesm2022/acorex-platform-module-platform-management-client-list-registered-entities.query-DjStd3a8.mjs +0 -136
- package/fesm2022/acorex-platform-module-platform-management-client-list-registered-entities.query-DjStd3a8.mjs.map +0 -1
|
@@ -1,287 +1,109 @@
|
|
|
1
|
+
import { extractRequestErrorInfo, platformErrorI18nKey } from '@acorex-platform/framework-client/common';
|
|
1
2
|
import { resolveLayoutBuilderDialogResult, AXPLayoutBuilderService } from '@acorex-platform/framework-client/layout/builder';
|
|
2
|
-
import { AXPEntityResolver } from '@acorex-platform/framework-client/layout/entity';
|
|
3
|
-
import { resolveEntityActionCommandInput, entityActionDataRecord } from '@acorex-platform/framework-shared/runtime';
|
|
3
|
+
import { AXPEntityResolver, AXPEntityService } from '@acorex-platform/framework-client/layout/entity';
|
|
4
|
+
import { ENTITY_INSERT_DEFAULT, resolveEntityActionCommandInput, entityActionDataRecord } from '@acorex-platform/framework-shared/runtime';
|
|
5
|
+
import { AXPCommandService } from '@acorex-platform/framework-client/runtime';
|
|
6
|
+
import { RootConfig } from '@acorex-platform/module-platform-management-client/contracts';
|
|
4
7
|
import { AXToastService } from '@acorex/components/toast';
|
|
5
8
|
import { AXTranslationService } from '@acorex/core/translation';
|
|
6
9
|
import * as i0 from '@angular/core';
|
|
7
10
|
import { inject, Injectable } from '@angular/core';
|
|
11
|
+
import { n as normalizeUserQueryMeasure, r as resolvePickedEntityFullName, w as withRequiredIdField, c as collectSelectedFieldGroupPaths, a as resolveAvailableContractFields, f as flattenEntityFieldItems, b as assembleEntityQueryContract, v as validateEntityQueryContract, p as parseEntityFullName, d as collectUserQueryEntityFieldGroups, e as defaultSelectedFieldGroups, U as USER_QUERY_RELATED_DEPTH, g as numericUserQueryFields, h as createDefaultEntityContract } from './acorex-platform-module-platform-management-client-create-user-query-contract.util-D_af2BUi.mjs';
|
|
12
|
+
import { C as CREATE_USER_QUERY_I18N, a as CREATE_USER_QUERY_WIZARD_NAME, n as normalizeRestApiOutput, c as createEmptyRestApiOutput, b as CREATE_USER_QUERY_ENTITY_CATALOG, U as USER_QUERY_KIND_OPTIONS, d as USER_QUERY_VALUE_TYPE_OPTIONS, e as USER_QUERY_MEASURE_REDUCER_OPTIONS, Q as QUERY_CONTRACT_WIDGET_NAME, R as REST_API_GENERATOR_WIDGET_NAME } from './acorex-platform-module-platform-management-client-acorex-platform-module-platform-management-client-YuJijjKh.mjs';
|
|
8
13
|
import { AXPWidgetsList } from '@acorex-platform/framework-shared/core';
|
|
9
|
-
import { parsePropertyExposeEntries } from '@acorex-platform/framework-shared/entity';
|
|
10
|
-
import { C as CREATE_USER_QUERY_I18N, a as CREATE_USER_QUERY_WIZARD_NAME, b as CREATE_USER_QUERY_ENTITY_CATALOG } from './acorex-platform-module-platform-management-client-create-user-query.types-DdygAori.mjs';
|
|
11
|
-
import { n as normalizeRestApiOutput, c as createEmptyRestApiOutput, R as REST_API_GENERATOR_WIDGET_NAME } from './acorex-platform-module-platform-management-client-acorex-platform-module-platform-management-client-BGVhn6wv.mjs';
|
|
12
14
|
|
|
13
|
-
//#region ----- Imports -----
|
|
14
|
-
//#endregion
|
|
15
15
|
//#region ----- Constants -----
|
|
16
|
-
const
|
|
17
|
-
const
|
|
16
|
+
const VALUE_REDUCERS = ['count', 'sum', 'min', 'max', 'avg'];
|
|
17
|
+
const EMPTY_USER_QUERY_WHERE = {
|
|
18
|
+
id: 'root',
|
|
19
|
+
logic: 'and',
|
|
20
|
+
filters: [],
|
|
21
|
+
order: 0,
|
|
22
|
+
title: 'Root',
|
|
23
|
+
widget: { type: 'string-filter', options: {} },
|
|
24
|
+
filterType: { advance: true, inline: true },
|
|
25
|
+
};
|
|
18
26
|
//#endregion
|
|
19
27
|
//#region ----- Public API -----
|
|
20
|
-
function
|
|
21
|
-
const trimmed = fullName.trim();
|
|
22
|
-
const separator = trimmed.indexOf('.');
|
|
23
|
-
if (separator <= 0 || separator === trimmed.length - 1) {
|
|
24
|
-
return null;
|
|
25
|
-
}
|
|
28
|
+
function emptyUserQueryBuilderValue() {
|
|
26
29
|
return {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
if (typeof value === 'string') {
|
|
33
|
-
return value.trim();
|
|
34
|
-
}
|
|
35
|
-
if (value == null || typeof value !== 'object') {
|
|
36
|
-
return '';
|
|
37
|
-
}
|
|
38
|
-
const record = value;
|
|
39
|
-
const id = typeof record['id'] === 'string' ? record['id'].trim() : '';
|
|
40
|
-
if (id.includes('.')) {
|
|
41
|
-
return id;
|
|
42
|
-
}
|
|
43
|
-
const moduleName = typeof record['module_id'] === 'string' ? record['module_id'].trim() : '';
|
|
44
|
-
const name = typeof record['name'] === 'string' ? record['name'].trim() : '';
|
|
45
|
-
if (moduleName && name) {
|
|
46
|
-
return `${moduleName}.${name}`;
|
|
47
|
-
}
|
|
48
|
-
return id;
|
|
49
|
-
}
|
|
50
|
-
function collectUserQueryEntityFieldGroups(entity, relatedByName) {
|
|
51
|
-
return collectGroups(entity, relatedByName, '', new Set());
|
|
52
|
-
}
|
|
53
|
-
function flattenEntityFieldGroups(groups) {
|
|
54
|
-
const result = [];
|
|
55
|
-
const walk = (group) => {
|
|
56
|
-
result.push(group);
|
|
57
|
-
for (const child of group.children ?? []) {
|
|
58
|
-
walk(child);
|
|
59
|
-
}
|
|
60
|
-
};
|
|
61
|
-
for (const group of groups) {
|
|
62
|
-
walk(group);
|
|
63
|
-
}
|
|
64
|
-
return result;
|
|
65
|
-
}
|
|
66
|
-
function defaultSelectedFieldGroups(groups) {
|
|
67
|
-
const selected = {};
|
|
68
|
-
for (const group of flattenEntityFieldGroups(groups)) {
|
|
69
|
-
selected[group.id] = [];
|
|
70
|
-
}
|
|
71
|
-
for (const group of groups) {
|
|
72
|
-
if (group.kind !== 'relation') {
|
|
73
|
-
selected[group.id] = group.items.map((item) => item.path);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
return selected;
|
|
77
|
-
}
|
|
78
|
-
function collectSelectedFieldGroupPaths(fieldGroups, groups) {
|
|
79
|
-
const paths = [];
|
|
80
|
-
const walk = (group) => {
|
|
81
|
-
paths.push(...normalizeSelectedFieldPaths(fieldGroups?.[group.id]));
|
|
82
|
-
for (const child of group.children ?? []) {
|
|
83
|
-
walk(child);
|
|
84
|
-
}
|
|
30
|
+
columns: [],
|
|
31
|
+
where: { ...EMPTY_USER_QUERY_WHERE, filters: [] },
|
|
32
|
+
sort: [],
|
|
33
|
+
groupBy: [],
|
|
34
|
+
aggregates: [],
|
|
85
35
|
};
|
|
86
|
-
for (const group of groups) {
|
|
87
|
-
walk(group);
|
|
88
|
-
}
|
|
89
|
-
return paths;
|
|
90
|
-
}
|
|
91
|
-
function withRequiredIdField(paths) {
|
|
92
|
-
const unique = [];
|
|
93
|
-
const seen = new Set();
|
|
94
|
-
for (const path of paths) {
|
|
95
|
-
const trimmed = path.trim();
|
|
96
|
-
if (!trimmed || seen.has(trimmed)) {
|
|
97
|
-
continue;
|
|
98
|
-
}
|
|
99
|
-
seen.add(trimmed);
|
|
100
|
-
unique.push(trimmed);
|
|
101
|
-
}
|
|
102
|
-
if (!seen.has('id')) {
|
|
103
|
-
unique.unshift('id');
|
|
104
|
-
}
|
|
105
|
-
return unique;
|
|
106
36
|
}
|
|
107
|
-
function
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
return paths;
|
|
125
|
-
}
|
|
126
|
-
//#endregion
|
|
127
|
-
//#region ----- Group collection -----
|
|
128
|
-
function collectGroups(entity, relatedByName, pathPrefix, ancestry) {
|
|
129
|
-
const groups = [];
|
|
130
|
-
const { host, lookups } = collectHostAndLookups(entity, pathPrefix);
|
|
131
|
-
if (host.items.length) {
|
|
132
|
-
groups.push(host);
|
|
133
|
-
}
|
|
134
|
-
groups.push(...lookups);
|
|
135
|
-
const hostFullName = `${entity.module}.${entity.name}`;
|
|
136
|
-
const nextAncestry = new Set(ancestry);
|
|
137
|
-
nextAncestry.add(hostFullName);
|
|
138
|
-
for (const related of entity.relatedEntities ?? []) {
|
|
139
|
-
const group = collectRelatedGroup(related, relatedByName, pathPrefix, nextAncestry);
|
|
140
|
-
if (group) {
|
|
141
|
-
groups.push(group);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
return groups;
|
|
145
|
-
}
|
|
146
|
-
function collectHostAndLookups(entity, pathPrefix, allowedNames) {
|
|
147
|
-
const hostItems = [];
|
|
148
|
-
const lookups = [];
|
|
149
|
-
for (const property of entity?.properties ?? []) {
|
|
150
|
-
const name = property.name?.trim();
|
|
151
|
-
if (!name || name.toLowerCase() === 'id') {
|
|
152
|
-
continue;
|
|
153
|
-
}
|
|
154
|
-
if (allowedNames && !allowedNames.has(name)) {
|
|
155
|
-
continue;
|
|
156
|
-
}
|
|
157
|
-
if (isLookupProperty(property)) {
|
|
158
|
-
const lookupGroup = collectLookupGroup(property, pathPrefix);
|
|
159
|
-
if (lookupGroup) {
|
|
160
|
-
lookups.push(lookupGroup);
|
|
161
|
-
}
|
|
162
|
-
continue;
|
|
163
|
-
}
|
|
164
|
-
hostItems.push({
|
|
165
|
-
path: joinPath(pathPrefix, name),
|
|
166
|
-
title: property.title,
|
|
167
|
-
fallback: name,
|
|
168
|
-
});
|
|
169
|
-
}
|
|
37
|
+
function toQueryBuilderDataSource(entityName, fields) {
|
|
38
|
+
const columns = fields.map((field) => ({
|
|
39
|
+
name: field.path,
|
|
40
|
+
title: field.text || field.path,
|
|
41
|
+
datatype: field.dataType || 'string',
|
|
42
|
+
type: field.filterWidget || 'text-editor',
|
|
43
|
+
}));
|
|
44
|
+
const filters = fields.map((field) => ({
|
|
45
|
+
id: field.path,
|
|
46
|
+
field: field.path,
|
|
47
|
+
title: field.text || field.path,
|
|
48
|
+
operator: { type: 'equal' },
|
|
49
|
+
widget: { type: field.filterWidget || 'string-filter', options: {} },
|
|
50
|
+
filterType: { advance: true, inline: true },
|
|
51
|
+
}));
|
|
170
52
|
return {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
fallback: 'fields',
|
|
176
|
-
items: hostItems,
|
|
177
|
-
},
|
|
178
|
-
lookups,
|
|
53
|
+
name: entityName,
|
|
54
|
+
title: entityName,
|
|
55
|
+
columns,
|
|
56
|
+
filters,
|
|
179
57
|
};
|
|
180
58
|
}
|
|
181
|
-
function
|
|
182
|
-
const
|
|
183
|
-
if (!
|
|
184
|
-
return
|
|
185
|
-
}
|
|
186
|
-
const
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
fallback: name,
|
|
210
|
-
items,
|
|
59
|
+
function measureFromBuilderValue(query, fallback, available) {
|
|
60
|
+
const first = query?.aggregates?.find((item) => typeof item?.function === 'string' && item.function.trim());
|
|
61
|
+
if (!first) {
|
|
62
|
+
return normalizeUserQueryMeasure(fallback, available);
|
|
63
|
+
}
|
|
64
|
+
const key = first.function.trim().toLowerCase();
|
|
65
|
+
const reducer = key === 'average' ? 'avg' : VALUE_REDUCERS.includes(key) ? key : 'count';
|
|
66
|
+
if (reducer === 'count') {
|
|
67
|
+
return { reducer: 'count', alias: first.alias?.trim() || 'value' };
|
|
68
|
+
}
|
|
69
|
+
return normalizeUserQueryMeasure({ reducer, field: first.field, alias: first.alias?.trim() || 'value' }, available);
|
|
70
|
+
}
|
|
71
|
+
function toUserQueryDefinitionRow(context, available) {
|
|
72
|
+
const contract = context.contract;
|
|
73
|
+
if (!contract) {
|
|
74
|
+
throw new Error('contract');
|
|
75
|
+
}
|
|
76
|
+
const entityName = typeof context.source?.entity?.entityName === 'string' ? context.source.entity.entityName.trim() : '';
|
|
77
|
+
const fields = context.source?.entity?.fields ?? [];
|
|
78
|
+
const query = (context.source?.entity?.query ?? emptyUserQueryBuilderValue());
|
|
79
|
+
const measure = contract.kind === 'value' ? measureFromBuilderValue(query, contract.measure, available) : undefined;
|
|
80
|
+
const source = {
|
|
81
|
+
kind: 'entity',
|
|
82
|
+
entityName,
|
|
83
|
+
fields,
|
|
84
|
+
fieldGroups: context.source?.entity?.fieldGroups,
|
|
85
|
+
query,
|
|
86
|
+
...(measure ? { measure } : {}),
|
|
211
87
|
};
|
|
212
|
-
}
|
|
213
|
-
function collectRelatedGroup(related, relatedByName, pathPrefix, ancestry) {
|
|
214
|
-
if (related.hidden === true) {
|
|
215
|
-
return null;
|
|
216
|
-
}
|
|
217
|
-
const entityName = related.entity?.trim();
|
|
218
|
-
if (!entityName || ancestry.has(entityName)) {
|
|
219
|
-
return null;
|
|
220
|
-
}
|
|
221
|
-
const relatedEntity = relatedByName.get(entityName);
|
|
222
|
-
const dataPath = related.persistence?.dataPath?.trim() || entityName.split('.').pop() || entityName;
|
|
223
|
-
const pathRoot = joinPath(pathPrefix, dataPath);
|
|
224
|
-
const allowed = resolveAllowedPropertyNames(related, relatedEntity);
|
|
225
|
-
const { host, lookups } = collectHostAndLookups(relatedEntity, pathRoot, allowed);
|
|
226
|
-
const childAncestry = new Set(ancestry);
|
|
227
|
-
childAncestry.add(entityName);
|
|
228
|
-
const children = [...lookups];
|
|
229
|
-
for (const nested of relatedEntity?.relatedEntities ?? []) {
|
|
230
|
-
const child = collectRelatedGroup(nested, relatedByName, pathRoot, childAncestry);
|
|
231
|
-
if (child) {
|
|
232
|
-
children.push(child);
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
if (!host.items.length && !children.length) {
|
|
236
|
-
return null;
|
|
237
|
-
}
|
|
238
88
|
return {
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
89
|
+
name: contract.name.trim(),
|
|
90
|
+
catalogTitle: contract.catalogTitle.trim(),
|
|
91
|
+
description: contract.description,
|
|
92
|
+
active: true,
|
|
93
|
+
executionMode: 'backend',
|
|
94
|
+
kind: contract.kind,
|
|
95
|
+
valueType: contract.kind === 'value' ? contract.valueType : undefined,
|
|
96
|
+
binding: contract.kind === 'collection' ? contract.capabilities?.binding : undefined,
|
|
97
|
+
args: { enabled: false },
|
|
98
|
+
filter: contract.capabilities?.filter ?? { enabled: false },
|
|
99
|
+
sort: contract.kind === 'collection' ? contract.capabilities?.sort : { enabled: false },
|
|
100
|
+
paging: contract.kind === 'collection' ? contract.capabilities?.paging : { enabled: false },
|
|
101
|
+
columns: contract.kind === 'value' ? undefined : contract.columns,
|
|
102
|
+
capabilities: ['ai'],
|
|
103
|
+
source,
|
|
104
|
+
stateInfo: { isSystem: false },
|
|
245
105
|
};
|
|
246
106
|
}
|
|
247
|
-
function resolveAllowedPropertyNames(related, relatedEntity) {
|
|
248
|
-
const excluded = new Set((related.excludeProperties ?? [])
|
|
249
|
-
.filter((name) => typeof name === 'string')
|
|
250
|
-
.map((name) => name.trim())
|
|
251
|
-
.filter(Boolean));
|
|
252
|
-
const fromConfig = Array.isArray(related.properties)
|
|
253
|
-
? related.properties.filter((name) => typeof name === 'string' && name.trim().length > 0)
|
|
254
|
-
: [];
|
|
255
|
-
if (fromConfig.length) {
|
|
256
|
-
return new Set(fromConfig.map((name) => name.trim()).filter((name) => name.toLowerCase() !== 'id' && !excluded.has(name)));
|
|
257
|
-
}
|
|
258
|
-
if (!excluded.size) {
|
|
259
|
-
return undefined;
|
|
260
|
-
}
|
|
261
|
-
const names = (relatedEntity?.properties ?? [])
|
|
262
|
-
.map((property) => property.name?.trim() ?? '')
|
|
263
|
-
.filter((name) => name && name.toLowerCase() !== 'id' && !excluded.has(name));
|
|
264
|
-
return new Set(names);
|
|
265
|
-
}
|
|
266
|
-
function isLookupProperty(property) {
|
|
267
|
-
const iface = property.schema?.interface;
|
|
268
|
-
const opts = iface?.options;
|
|
269
|
-
const lookupEntity = typeof opts?.['entity'] === 'string' ? String(opts['entity']).trim() : '';
|
|
270
|
-
if (!lookupEntity) {
|
|
271
|
-
return false;
|
|
272
|
-
}
|
|
273
|
-
const widgetType = typeof iface?.type === 'string' ? iface.type : '';
|
|
274
|
-
if (LOOKUP_WIDGET_TYPES.has(widgetType)) {
|
|
275
|
-
return true;
|
|
276
|
-
}
|
|
277
|
-
return /(Ids|IDs|Id|ID)$/i.test(property.name);
|
|
278
|
-
}
|
|
279
|
-
function joinPath(prefix, segment) {
|
|
280
|
-
return prefix ? `${prefix}.${segment}` : segment;
|
|
281
|
-
}
|
|
282
|
-
function sanitizeGroupId(value) {
|
|
283
|
-
return value.replace(/[^a-zA-Z0-9]+/g, '_').replace(/^_|_$/g, '');
|
|
284
|
-
}
|
|
285
107
|
//#endregion
|
|
286
108
|
|
|
287
109
|
//#region ----- Imports -----
|
|
@@ -342,7 +164,10 @@ async function openEntityPickDialog(args, entityName) {
|
|
|
342
164
|
.setCloseButton(true)
|
|
343
165
|
.setContext(createInitialContext('entity', entityName))
|
|
344
166
|
.content((flex) => {
|
|
345
|
-
flex
|
|
167
|
+
flex
|
|
168
|
+
.setDirection('column')
|
|
169
|
+
.setGap('16px')
|
|
170
|
+
.stepWizard((wizard) => {
|
|
346
171
|
wizard
|
|
347
172
|
.name(CREATE_USER_QUERY_WIZARD_NAME)
|
|
348
173
|
.setLook('circular-icon')
|
|
@@ -361,7 +186,7 @@ async function openEntityPickDialog(args, entityName) {
|
|
|
361
186
|
})
|
|
362
187
|
.step('contract', CREATE_USER_QUERY_I18N.steps.contract, (step) => {
|
|
363
188
|
step.setIcon('fa-light fa-file-contract').content((layout) => {
|
|
364
|
-
|
|
189
|
+
fillHintStep(layout, CREATE_USER_QUERY_I18N.steps.contract, CREATE_USER_QUERY_I18N.placeholders.contractNext);
|
|
365
190
|
});
|
|
366
191
|
});
|
|
367
192
|
});
|
|
@@ -387,7 +212,7 @@ async function openEntityPickDialog(args, entityName) {
|
|
|
387
212
|
})
|
|
388
213
|
.custom({
|
|
389
214
|
title: '@general:actions.submit.title',
|
|
390
|
-
command:
|
|
215
|
+
command: 'submit',
|
|
391
216
|
icon: 'fa-regular fa-check',
|
|
392
217
|
color: 'success',
|
|
393
218
|
hidden: '{{!api.getStatus().isLast}}',
|
|
@@ -417,9 +242,12 @@ async function openEntityFieldsDialog(args, entityName, groups, selectedGroups)
|
|
|
417
242
|
.setTitle(CREATE_USER_QUERY_I18N.titles.entity)
|
|
418
243
|
.setSize('xl')
|
|
419
244
|
.setCloseButton(true)
|
|
420
|
-
.setContext(createInitialContext('entity', entityName, [], selectedGroups))
|
|
245
|
+
.setContext(createInitialContext('entity', entityName, [], selectedGroups, createEntityContractSeed(entityName, groups, selectedGroups)))
|
|
421
246
|
.content((flex) => {
|
|
422
|
-
flex
|
|
247
|
+
flex
|
|
248
|
+
.setDirection('column')
|
|
249
|
+
.setGap('16px')
|
|
250
|
+
.stepWizard((wizard) => {
|
|
423
251
|
wizard
|
|
424
252
|
.name(CREATE_USER_QUERY_WIZARD_NAME)
|
|
425
253
|
.setLook('circular-icon')
|
|
@@ -436,7 +264,7 @@ async function openEntityFieldsDialog(args, entityName, groups, selectedGroups)
|
|
|
436
264
|
})
|
|
437
265
|
.step('contract', CREATE_USER_QUERY_I18N.steps.contract, (step) => {
|
|
438
266
|
step.setIcon('fa-light fa-file-contract').content((layout) => {
|
|
439
|
-
|
|
267
|
+
fillEntityContractStep(layout, entityName, groups);
|
|
440
268
|
});
|
|
441
269
|
});
|
|
442
270
|
});
|
|
@@ -472,7 +300,7 @@ async function openEntityFieldsDialog(args, entityName, groups, selectedGroups)
|
|
|
472
300
|
})
|
|
473
301
|
.custom({
|
|
474
302
|
title: '@general:actions.submit.title',
|
|
475
|
-
command:
|
|
303
|
+
command: 'submit',
|
|
476
304
|
icon: 'fa-regular fa-check',
|
|
477
305
|
color: 'success',
|
|
478
306
|
hidden: '{{!api.getStatus().isLast}}',
|
|
@@ -494,12 +322,27 @@ async function openEntityFieldsDialog(args, entityName, groups, selectedGroups)
|
|
|
494
322
|
if (countFieldGroupItems(groups) > 0 && fields.filter((path) => path !== 'id').length === 0) {
|
|
495
323
|
throw new Error(CREATE_USER_QUERY_I18N.errors.fieldsRequired);
|
|
496
324
|
}
|
|
325
|
+
const available = resolveAvailableContractFields(flattenEntityFieldItems(groups), fields);
|
|
326
|
+
const contract = assembleEntityQueryContract({
|
|
327
|
+
name: context.contract?.name ?? '',
|
|
328
|
+
catalogTitle: context.contract?.catalogTitle ?? '',
|
|
329
|
+
description: context.contract?.description,
|
|
330
|
+
kind: context.contract?.kind,
|
|
331
|
+
valueType: context.contract?.valueType,
|
|
332
|
+
measure: context.contract?.measure,
|
|
333
|
+
}, context.contract?.capabilities, available);
|
|
334
|
+
const contractError = validateEntityQueryContract(contract, available);
|
|
335
|
+
if (contractError) {
|
|
336
|
+
throw new Error(contractValidationErrorKey(contractError));
|
|
337
|
+
}
|
|
497
338
|
return {
|
|
498
339
|
...context,
|
|
340
|
+
contract,
|
|
499
341
|
source: {
|
|
500
342
|
...context.source,
|
|
501
343
|
kind: 'entity',
|
|
502
344
|
entity: {
|
|
345
|
+
...context.source?.entity,
|
|
503
346
|
entityName,
|
|
504
347
|
fields,
|
|
505
348
|
fieldGroups: context.source?.entity?.fieldGroups,
|
|
@@ -566,9 +409,7 @@ async function openApiSourceWizard(args) {
|
|
|
566
409
|
}
|
|
567
410
|
const groups = inferJsonFieldGroups(tested.source?.api?.lastTest?.body);
|
|
568
411
|
const views = await toFieldGroupViews(groups, args.translationService);
|
|
569
|
-
const selected = isSameApiRequest(previous, tested) && previous.source?.api?.fieldGroups
|
|
570
|
-
? previous.source.api.fieldGroups
|
|
571
|
-
: defaultHostFieldGroups(groups);
|
|
412
|
+
const selected = isSameApiRequest(previous, tested) && previous.source?.api?.fieldGroups ? previous.source.api.fieldGroups : defaultHostFieldGroups(groups);
|
|
572
413
|
const outcome = await openApiFieldsDialog(args, tested, views, selected);
|
|
573
414
|
if (outcome === API_WIZARD_BACK) {
|
|
574
415
|
previous = tested;
|
|
@@ -587,7 +428,10 @@ async function openApiSourceDialog(args, previous) {
|
|
|
587
428
|
.setCloseButton(true)
|
|
588
429
|
.setContext(previous)
|
|
589
430
|
.content((flex) => {
|
|
590
|
-
flex
|
|
431
|
+
flex
|
|
432
|
+
.setDirection('column')
|
|
433
|
+
.setGap('16px')
|
|
434
|
+
.stepWizard((wizard) => {
|
|
591
435
|
wizard
|
|
592
436
|
.name(CREATE_USER_QUERY_WIZARD_NAME)
|
|
593
437
|
.setLook('circular-icon')
|
|
@@ -632,7 +476,7 @@ async function openApiSourceDialog(args, previous) {
|
|
|
632
476
|
})
|
|
633
477
|
.custom({
|
|
634
478
|
title: '@general:actions.submit.title',
|
|
635
|
-
command:
|
|
479
|
+
command: 'submit',
|
|
636
480
|
icon: 'fa-regular fa-check',
|
|
637
481
|
color: 'success',
|
|
638
482
|
hidden: '{{!api.getStatus().isLast}}',
|
|
@@ -675,7 +519,10 @@ async function openApiFieldsDialog(args, tested, groups, selectedGroups) {
|
|
|
675
519
|
.setCloseButton(true)
|
|
676
520
|
.setContext(createApiWizardContext(tested.source?.api, selectedGroups))
|
|
677
521
|
.content((flex) => {
|
|
678
|
-
flex
|
|
522
|
+
flex
|
|
523
|
+
.setDirection('column')
|
|
524
|
+
.setGap('16px')
|
|
525
|
+
.stepWizard((wizard) => {
|
|
679
526
|
wizard
|
|
680
527
|
.name(CREATE_USER_QUERY_WIZARD_NAME)
|
|
681
528
|
.setLook('circular-icon')
|
|
@@ -728,7 +575,7 @@ async function openApiFieldsDialog(args, tested, groups, selectedGroups) {
|
|
|
728
575
|
})
|
|
729
576
|
.custom({
|
|
730
577
|
title: '@general:actions.submit.title',
|
|
731
|
-
command:
|
|
578
|
+
command: 'submit',
|
|
732
579
|
icon: 'fa-regular fa-check',
|
|
733
580
|
color: 'success',
|
|
734
581
|
hidden: '{{!api.getStatus().isLast}}',
|
|
@@ -805,9 +652,7 @@ function createApiWizardContext(api, fieldGroups = {}) {
|
|
|
805
652
|
api: {
|
|
806
653
|
request: api?.request ?? createEmptyRestApiOutput(),
|
|
807
654
|
connectionId: api?.connectionId,
|
|
808
|
-
lastTest: api?.lastTest
|
|
809
|
-
? { ...api.lastTest, status: String(api.lastTest.status) }
|
|
810
|
-
: undefined,
|
|
655
|
+
lastTest: api?.lastTest ? { ...api.lastTest, status: String(api.lastTest.status) } : undefined,
|
|
811
656
|
fields: api?.fields ?? [],
|
|
812
657
|
fieldGroups: Object.keys(fieldGroups).length ? fieldGroups : (api?.fieldGroups ?? {}),
|
|
813
658
|
},
|
|
@@ -935,9 +780,7 @@ function splitJsonEnvelope(root) {
|
|
|
935
780
|
return Array.isArray(value) && value.some((item) => isPlainObject(item));
|
|
936
781
|
});
|
|
937
782
|
const otherKeys = keys.filter((key) => !arrayKeys.includes(key));
|
|
938
|
-
if (arrayKeys.length === 1 &&
|
|
939
|
-
otherKeys.length > 0 &&
|
|
940
|
-
otherKeys.every((key) => isJsonScalar(root[key]))) {
|
|
783
|
+
if (arrayKeys.length === 1 && otherKeys.length > 0 && otherKeys.every((key) => isJsonScalar(root[key]))) {
|
|
941
784
|
payloadKey = arrayKeys[0];
|
|
942
785
|
}
|
|
943
786
|
}
|
|
@@ -1059,11 +902,7 @@ async function openAdvancedPlaceholder(args) {
|
|
|
1059
902
|
await args.layoutBuilder
|
|
1060
903
|
.create()
|
|
1061
904
|
.dialog((dialog) => {
|
|
1062
|
-
dialog
|
|
1063
|
-
.setTitle(CREATE_USER_QUERY_I18N.titles.advanced)
|
|
1064
|
-
.setMessage(CREATE_USER_QUERY_I18N.placeholders.advanced)
|
|
1065
|
-
.setSize('md')
|
|
1066
|
-
.setCloseButton(true);
|
|
905
|
+
dialog.setTitle(CREATE_USER_QUERY_I18N.titles.advanced).setMessage(CREATE_USER_QUERY_I18N.placeholders.advanced).setSize('md').setCloseButton(true);
|
|
1067
906
|
})
|
|
1068
907
|
.show();
|
|
1069
908
|
return null;
|
|
@@ -1077,7 +916,10 @@ function configureSimpleSourceWizard(dialog, args) {
|
|
|
1077
916
|
.setCloseButton(true)
|
|
1078
917
|
.setContext(createInitialContext(args.sourceKind))
|
|
1079
918
|
.content((flex) => {
|
|
1080
|
-
flex
|
|
919
|
+
flex
|
|
920
|
+
.setDirection('column')
|
|
921
|
+
.setGap('16px')
|
|
922
|
+
.stepWizard((wizard) => {
|
|
1081
923
|
wizard
|
|
1082
924
|
.name(CREATE_USER_QUERY_WIZARD_NAME)
|
|
1083
925
|
.setLook('circular-icon')
|
|
@@ -1121,7 +963,7 @@ function configureSimpleSourceWizard(dialog, args) {
|
|
|
1121
963
|
})
|
|
1122
964
|
.custom({
|
|
1123
965
|
title: '@general:actions.submit.title',
|
|
1124
|
-
command:
|
|
966
|
+
command: 'submit',
|
|
1125
967
|
icon: 'fa-regular fa-check',
|
|
1126
968
|
color: 'success',
|
|
1127
969
|
hidden: '{{!api.getStatus().isLast}}',
|
|
@@ -1158,9 +1000,8 @@ function fillEntityPickStep(layout, readonly = false) {
|
|
|
1158
1000
|
fieldset.formField(CREATE_USER_QUERY_I18N.fields.entity, (field) => {
|
|
1159
1001
|
field.path('source.entity.entityName').lookupBox({
|
|
1160
1002
|
entity: CREATE_USER_QUERY_ENTITY_CATALOG,
|
|
1161
|
-
valueField: '
|
|
1162
|
-
textField: '
|
|
1163
|
-
columns: ['name', 'module_id'],
|
|
1003
|
+
valueField: 'name',
|
|
1004
|
+
textField: 'name',
|
|
1164
1005
|
look: 'select',
|
|
1165
1006
|
searchable: true,
|
|
1166
1007
|
allowClear: !readonly,
|
|
@@ -1172,15 +1013,115 @@ function fillEntityPickStep(layout, readonly = false) {
|
|
|
1172
1013
|
});
|
|
1173
1014
|
});
|
|
1174
1015
|
}
|
|
1175
|
-
function
|
|
1016
|
+
function fillEntityContractStep(layout, entityName, groups) {
|
|
1017
|
+
const builderFields = flattenEntityFieldItems(groups);
|
|
1176
1018
|
layout.flex((flex) => {
|
|
1177
1019
|
flex.setDirection('column').setGap('16px').setAlignItems('stretch');
|
|
1178
1020
|
flex.fieldset((fieldset) => {
|
|
1179
1021
|
fieldset
|
|
1180
|
-
.setTitle(
|
|
1181
|
-
.setDescription(CREATE_USER_QUERY_I18N.placeholders.
|
|
1182
|
-
.setIcon('fa-light fa-
|
|
1183
|
-
.
|
|
1022
|
+
.setTitle(CREATE_USER_QUERY_I18N.fields.identity)
|
|
1023
|
+
.setDescription(CREATE_USER_QUERY_I18N.placeholders.identity)
|
|
1024
|
+
.setIcon('fa-light fa-id-card')
|
|
1025
|
+
.setCols(2)
|
|
1026
|
+
.formField(CREATE_USER_QUERY_I18N.fields.queryName, (field) => {
|
|
1027
|
+
field.path('contract.name').textBox({ validations: [{ rule: 'required' }] });
|
|
1028
|
+
})
|
|
1029
|
+
.formField(CREATE_USER_QUERY_I18N.fields.catalogTitle, (field) => {
|
|
1030
|
+
field.path('contract.catalogTitle').textBox({ validations: [{ rule: 'required' }] });
|
|
1031
|
+
})
|
|
1032
|
+
.formField(CREATE_USER_QUERY_I18N.fields.description, (field) => {
|
|
1033
|
+
field.path('contract.description').largeTextBox({ rows: 3 }).layout(2);
|
|
1034
|
+
});
|
|
1035
|
+
});
|
|
1036
|
+
flex.fieldset((fieldset) => {
|
|
1037
|
+
fieldset
|
|
1038
|
+
.setTitle(CREATE_USER_QUERY_I18N.fields.kind)
|
|
1039
|
+
.setDescription(CREATE_USER_QUERY_I18N.placeholders.kind)
|
|
1040
|
+
.setIcon('fa-light fa-shapes')
|
|
1041
|
+
.setCols(2)
|
|
1042
|
+
.formField(CREATE_USER_QUERY_I18N.fields.kind, (field) => {
|
|
1043
|
+
field
|
|
1044
|
+
.path('contract.kind')
|
|
1045
|
+
.setShowLabel(false)
|
|
1046
|
+
.selectBox({
|
|
1047
|
+
valueField: 'value',
|
|
1048
|
+
textField: 'text',
|
|
1049
|
+
dataSource: USER_QUERY_KIND_OPTIONS,
|
|
1050
|
+
validations: [{ rule: 'required' }],
|
|
1051
|
+
});
|
|
1052
|
+
})
|
|
1053
|
+
.formField(CREATE_USER_QUERY_I18N.fields.valueType, (field) => {
|
|
1054
|
+
field
|
|
1055
|
+
.path('contract.valueType')
|
|
1056
|
+
.selectBox({
|
|
1057
|
+
valueField: 'value',
|
|
1058
|
+
textField: 'text',
|
|
1059
|
+
dataSource: USER_QUERY_VALUE_TYPE_OPTIONS,
|
|
1060
|
+
})
|
|
1061
|
+
.visible('{{ context.eval("contract.kind") === "value" }}');
|
|
1062
|
+
})
|
|
1063
|
+
.formField(CREATE_USER_QUERY_I18N.fields.measure, (field) => {
|
|
1064
|
+
field
|
|
1065
|
+
.path('contract.measure.reducer')
|
|
1066
|
+
.selectBox({
|
|
1067
|
+
valueField: 'value',
|
|
1068
|
+
textField: 'text',
|
|
1069
|
+
dataSource: USER_QUERY_MEASURE_REDUCER_OPTIONS,
|
|
1070
|
+
validations: [{ rule: 'required' }],
|
|
1071
|
+
})
|
|
1072
|
+
.visible('{{ context.eval("contract.kind") === "value" }}');
|
|
1073
|
+
})
|
|
1074
|
+
.formField(CREATE_USER_QUERY_I18N.fields.measureField, (field) => {
|
|
1075
|
+
field
|
|
1076
|
+
.path('contract.measure.field')
|
|
1077
|
+
.selectBox({
|
|
1078
|
+
valueField: 'path',
|
|
1079
|
+
textField: 'text',
|
|
1080
|
+
dataSource: numericUserQueryFields(flattenEntityFieldItems(groups)),
|
|
1081
|
+
})
|
|
1082
|
+
.visible('{{ context.eval("contract.kind") === "value" && context.eval("contract.measure.reducer") !== "count" }}');
|
|
1083
|
+
});
|
|
1084
|
+
});
|
|
1085
|
+
flex.fieldset((fieldset) => {
|
|
1086
|
+
fieldset
|
|
1087
|
+
.setTitle(CREATE_USER_QUERY_I18N.fields.predicates)
|
|
1088
|
+
.setDescription(CREATE_USER_QUERY_I18N.placeholders.predicates)
|
|
1089
|
+
.setIcon('fa-light fa-filter')
|
|
1090
|
+
.setCols(1)
|
|
1091
|
+
.formField(' ', (field) => {
|
|
1092
|
+
field
|
|
1093
|
+
.path('source.entity.query')
|
|
1094
|
+
.setShowLabel(false)
|
|
1095
|
+
.customWidget(AXPWidgetsList.Editors.QueryBuilder, {
|
|
1096
|
+
visibleTabs: ['where', 'aggregate'],
|
|
1097
|
+
dataSource: toQueryBuilderDataSource(entityName, builderFields),
|
|
1098
|
+
})
|
|
1099
|
+
.layout(1);
|
|
1100
|
+
});
|
|
1101
|
+
});
|
|
1102
|
+
flex.fieldset((fieldset) => {
|
|
1103
|
+
fieldset
|
|
1104
|
+
.setTitle(CREATE_USER_QUERY_I18N.fields.capabilities)
|
|
1105
|
+
.setDescription(CREATE_USER_QUERY_I18N.placeholders.capabilities)
|
|
1106
|
+
.setIcon('fa-light fa-sliders')
|
|
1107
|
+
.setCols(1)
|
|
1108
|
+
.formField(' ', (field) => {
|
|
1109
|
+
field
|
|
1110
|
+
.path('contract.capabilities')
|
|
1111
|
+
.setShowLabel(false)
|
|
1112
|
+
.customWidget(QUERY_CONTRACT_WIDGET_NAME, {
|
|
1113
|
+
fields: flattenEntityFieldItems(groups),
|
|
1114
|
+
})
|
|
1115
|
+
.layout(1);
|
|
1116
|
+
});
|
|
1117
|
+
});
|
|
1118
|
+
});
|
|
1119
|
+
}
|
|
1120
|
+
function fillEntityFieldsStep(layout, entityName, groups) {
|
|
1121
|
+
layout.flex((flex) => {
|
|
1122
|
+
flex.setDirection('column').setGap('16px').setAlignItems('stretch');
|
|
1123
|
+
flex.fieldset((fieldset) => {
|
|
1124
|
+
fieldset.setTitle(entityName).setDescription(CREATE_USER_QUERY_I18N.placeholders.selectedEntityHint).setIcon('fa-light fa-database').setLook('group');
|
|
1184
1125
|
});
|
|
1185
1126
|
for (const group of groups) {
|
|
1186
1127
|
renderFieldGroup(flex, group);
|
|
@@ -1288,10 +1229,7 @@ function staticItemRepeaterChildren() {
|
|
|
1288
1229
|
gap: '12px',
|
|
1289
1230
|
alignItems: 'stretch',
|
|
1290
1231
|
},
|
|
1291
|
-
children: [
|
|
1292
|
-
staticItemRepeaterField(CREATE_USER_QUERY_I18N.fields.value, 'value'),
|
|
1293
|
-
staticItemRepeaterField(CREATE_USER_QUERY_I18N.fields.title, 'title'),
|
|
1294
|
-
],
|
|
1232
|
+
children: [staticItemRepeaterField(CREATE_USER_QUERY_I18N.fields.value, 'value'), staticItemRepeaterField(CREATE_USER_QUERY_I18N.fields.title, 'title')],
|
|
1295
1233
|
},
|
|
1296
1234
|
];
|
|
1297
1235
|
}
|
|
@@ -1339,11 +1277,7 @@ function fillApiSourceStep(layout) {
|
|
|
1339
1277
|
}
|
|
1340
1278
|
function fillContractPlaceholderStep(layout) {
|
|
1341
1279
|
layout.fieldset((fieldset) => {
|
|
1342
|
-
fieldset
|
|
1343
|
-
.setTitle(CREATE_USER_QUERY_I18N.steps.contract)
|
|
1344
|
-
.setDescription(CREATE_USER_QUERY_I18N.placeholders.contract)
|
|
1345
|
-
.setIcon('fa-light fa-file-contract')
|
|
1346
|
-
.setLook('group');
|
|
1280
|
+
fieldset.setTitle(CREATE_USER_QUERY_I18N.steps.contract).setDescription(CREATE_USER_QUERY_I18N.placeholders.contract).setIcon('fa-light fa-file-contract').setLook('group');
|
|
1347
1281
|
});
|
|
1348
1282
|
}
|
|
1349
1283
|
//#endregion
|
|
@@ -1386,18 +1320,35 @@ function sourceStepErrorKey(sourceKind, context) {
|
|
|
1386
1320
|
}
|
|
1387
1321
|
return null;
|
|
1388
1322
|
}
|
|
1389
|
-
function createInitialContext(sourceKind, entityName = '', fields = [], fieldGroups = {}) {
|
|
1323
|
+
function createInitialContext(sourceKind, entityName = '', fields = [], fieldGroups = {}, contract) {
|
|
1390
1324
|
const items = [{ value: '', title: '' }];
|
|
1391
1325
|
return {
|
|
1392
1326
|
sourceKind,
|
|
1393
1327
|
source: {
|
|
1394
1328
|
kind: sourceKind,
|
|
1395
|
-
entity: { entityName, fields, fieldGroups },
|
|
1329
|
+
entity: { entityName, fields, fieldGroups, query: emptyUserQueryBuilderValue() },
|
|
1396
1330
|
static: { items },
|
|
1397
1331
|
api: { request: createEmptyRestApiOutput() },
|
|
1398
1332
|
},
|
|
1333
|
+
contract,
|
|
1399
1334
|
};
|
|
1400
1335
|
}
|
|
1336
|
+
function createEntityContractSeed(entityName, groups, selectedGroups) {
|
|
1337
|
+
const available = resolveAvailableContractFields(flattenEntityFieldItems(groups), collectSelectedFieldGroupPaths(selectedGroups, groups));
|
|
1338
|
+
return createDefaultEntityContract(entityName, available);
|
|
1339
|
+
}
|
|
1340
|
+
function contractValidationErrorKey(error) {
|
|
1341
|
+
if (error === 'title') {
|
|
1342
|
+
return CREATE_USER_QUERY_I18N.errors.contractTitleRequired;
|
|
1343
|
+
}
|
|
1344
|
+
if (error === 'binding') {
|
|
1345
|
+
return CREATE_USER_QUERY_I18N.errors.contractBindingInvalid;
|
|
1346
|
+
}
|
|
1347
|
+
if (error === 'measure') {
|
|
1348
|
+
return CREATE_USER_QUERY_I18N.errors.contractMeasureInvalid;
|
|
1349
|
+
}
|
|
1350
|
+
return CREATE_USER_QUERY_I18N.errors.contractNameRequired;
|
|
1351
|
+
}
|
|
1401
1352
|
function countFieldGroupItems(groups) {
|
|
1402
1353
|
let count = 0;
|
|
1403
1354
|
const walk = (group) => {
|
|
@@ -1412,9 +1363,9 @@ function countFieldGroupItems(groups) {
|
|
|
1412
1363
|
return count;
|
|
1413
1364
|
}
|
|
1414
1365
|
async function toFieldGroupViews(groups, translationService) {
|
|
1415
|
-
const hostTitle = resolveLabel(translationService, CREATE_USER_QUERY_I18N.fields.hostFields, 'Fields');
|
|
1366
|
+
const hostTitle = await resolveLabel(translationService, CREATE_USER_QUERY_I18N.fields.hostFields, 'Fields');
|
|
1416
1367
|
const mapGroup = async (group) => {
|
|
1417
|
-
const resolvedName = resolveLabel(translationService, group.title, group.fallback);
|
|
1368
|
+
const resolvedName = await resolveLabel(translationService, group.title, group.fallback);
|
|
1418
1369
|
let title = resolvedName;
|
|
1419
1370
|
if (group.kind === 'host') {
|
|
1420
1371
|
title = hostTitle;
|
|
@@ -1422,17 +1373,17 @@ async function toFieldGroupViews(groups, translationService) {
|
|
|
1422
1373
|
else if (group.kind === 'relation') {
|
|
1423
1374
|
title = await formatRelatedGroupTitle(translationService, resolvedName);
|
|
1424
1375
|
}
|
|
1425
|
-
const children = group.children?.length
|
|
1426
|
-
? await Promise.all(group.children.map((child) => mapGroup(child)))
|
|
1427
|
-
: undefined;
|
|
1376
|
+
const children = group.children?.length ? await Promise.all(group.children.map((child) => mapGroup(child))) : undefined;
|
|
1428
1377
|
return {
|
|
1429
1378
|
id: group.id,
|
|
1430
1379
|
kind: group.kind,
|
|
1431
1380
|
title,
|
|
1432
|
-
items: group.items.map((item) => ({
|
|
1381
|
+
items: await Promise.all(group.items.map(async (item) => ({
|
|
1433
1382
|
path: item.path,
|
|
1434
|
-
text: resolveLabel(translationService, item.title, item.fallback),
|
|
1435
|
-
|
|
1383
|
+
text: await resolveLabel(translationService, item.title, item.fallback),
|
|
1384
|
+
filterWidget: item.filterWidget,
|
|
1385
|
+
dataType: item.dataType,
|
|
1386
|
+
}))),
|
|
1436
1387
|
children,
|
|
1437
1388
|
};
|
|
1438
1389
|
};
|
|
@@ -1442,10 +1393,22 @@ async function formatRelatedGroupTitle(translationService, name) {
|
|
|
1442
1393
|
const translated = await translationService.translateAsync(CREATE_USER_QUERY_I18N.placeholders.relatedTo, { params: { name } });
|
|
1443
1394
|
return typeof translated === 'string' && translated.trim() ? translated.trim() : name;
|
|
1444
1395
|
}
|
|
1445
|
-
function resolveLabel(translationService, value, fallback) {
|
|
1396
|
+
async function resolveLabel(translationService, value, fallback) {
|
|
1446
1397
|
if (value == null || value === '') {
|
|
1447
1398
|
return fallback;
|
|
1448
1399
|
}
|
|
1400
|
+
if (typeof value === 'string') {
|
|
1401
|
+
const trimmed = value.trim();
|
|
1402
|
+
if (!trimmed) {
|
|
1403
|
+
return fallback;
|
|
1404
|
+
}
|
|
1405
|
+
if (trimmed.startsWith('@')) {
|
|
1406
|
+
const translated = await translationService.translateAsync(trimmed);
|
|
1407
|
+
const text = typeof translated === 'string' ? translated.trim() : '';
|
|
1408
|
+
return text && text !== trimmed ? text : fallback;
|
|
1409
|
+
}
|
|
1410
|
+
return trimmed;
|
|
1411
|
+
}
|
|
1449
1412
|
const resolved = translationService.resolve(value);
|
|
1450
1413
|
const text = typeof resolved === 'string' ? resolved.trim() : '';
|
|
1451
1414
|
return text || fallback;
|
|
@@ -1484,13 +1447,15 @@ function sourceStepIcon(sourceKind) {
|
|
|
1484
1447
|
//#endregion
|
|
1485
1448
|
//#region ----- Command -----
|
|
1486
1449
|
/**
|
|
1487
|
-
* Opens the user-query create wizard
|
|
1450
|
+
* Opens the user-query create wizard and persists an entity-source QueryDefinition.
|
|
1488
1451
|
*/
|
|
1489
1452
|
class AXMCreateUserQueryCommand {
|
|
1490
1453
|
constructor() {
|
|
1491
1454
|
//#region ----- Services & Dependencies -----
|
|
1492
1455
|
this.layoutBuilder = inject(AXPLayoutBuilderService);
|
|
1493
1456
|
this.entityResolver = inject(AXPEntityResolver);
|
|
1457
|
+
this.entityService = inject(AXPEntityService);
|
|
1458
|
+
this.commandService = inject(AXPCommandService);
|
|
1494
1459
|
this.toastService = inject(AXToastService);
|
|
1495
1460
|
this.translationService = inject(AXTranslationService);
|
|
1496
1461
|
}
|
|
@@ -1498,20 +1463,99 @@ class AXMCreateUserQueryCommand {
|
|
|
1498
1463
|
//#region ----- Execution -----
|
|
1499
1464
|
async execute(input = {}) {
|
|
1500
1465
|
const sourceKind = resolveSourceKind(input);
|
|
1501
|
-
await openCreateUserQueryWizard({
|
|
1466
|
+
const context = await openCreateUserQueryWizard({
|
|
1502
1467
|
layoutBuilder: this.layoutBuilder,
|
|
1503
1468
|
toastService: this.toastService,
|
|
1504
1469
|
translationService: this.translationService,
|
|
1505
1470
|
entityResolver: this.entityResolver,
|
|
1506
1471
|
sourceKind,
|
|
1507
1472
|
});
|
|
1473
|
+
if (!context) {
|
|
1474
|
+
return {
|
|
1475
|
+
success: true,
|
|
1476
|
+
kind: 'object',
|
|
1477
|
+
data: { sourceKind },
|
|
1478
|
+
metadata: { refresh: false },
|
|
1479
|
+
};
|
|
1480
|
+
}
|
|
1481
|
+
if (context.sourceKind !== 'entity' || !context.contract) {
|
|
1482
|
+
return {
|
|
1483
|
+
success: true,
|
|
1484
|
+
kind: 'object',
|
|
1485
|
+
data: context,
|
|
1486
|
+
metadata: { refresh: false },
|
|
1487
|
+
};
|
|
1488
|
+
}
|
|
1489
|
+
try {
|
|
1490
|
+
await this.persistEntityQuery(context);
|
|
1491
|
+
}
|
|
1492
|
+
catch (error) {
|
|
1493
|
+
const message = await this.translatePersistError(error);
|
|
1494
|
+
this.toastService.show({
|
|
1495
|
+
color: 'danger',
|
|
1496
|
+
content: message,
|
|
1497
|
+
closeButton: true,
|
|
1498
|
+
timeOut: 5000,
|
|
1499
|
+
timeOutProgress: true,
|
|
1500
|
+
});
|
|
1501
|
+
return {
|
|
1502
|
+
success: false,
|
|
1503
|
+
message: { text: message },
|
|
1504
|
+
};
|
|
1505
|
+
}
|
|
1506
|
+
const ok = await this.translationService.translateAsync(CREATE_USER_QUERY_I18N.placeholders.persistOk, {
|
|
1507
|
+
params: { name: context.contract.name },
|
|
1508
|
+
});
|
|
1509
|
+
this.toastService.show({
|
|
1510
|
+
color: 'success',
|
|
1511
|
+
content: ok,
|
|
1512
|
+
closeButton: true,
|
|
1513
|
+
timeOut: 4000,
|
|
1514
|
+
timeOutProgress: true,
|
|
1515
|
+
});
|
|
1508
1516
|
return {
|
|
1509
1517
|
success: true,
|
|
1510
1518
|
kind: 'object',
|
|
1511
|
-
data:
|
|
1512
|
-
metadata: { refresh:
|
|
1519
|
+
data: context,
|
|
1520
|
+
metadata: { refresh: true },
|
|
1513
1521
|
};
|
|
1514
1522
|
}
|
|
1523
|
+
//#endregion
|
|
1524
|
+
//#region ----- Persist -----
|
|
1525
|
+
async persistEntityQuery(context) {
|
|
1526
|
+
const name = context.contract?.name?.trim() ?? '';
|
|
1527
|
+
const catalog = this.entityService
|
|
1528
|
+
.withEntity(RootConfig.module.name, RootConfig.entities.queryDefinition.name)
|
|
1529
|
+
.data();
|
|
1530
|
+
const existing = await catalog.query({
|
|
1531
|
+
skip: 0,
|
|
1532
|
+
take: 1,
|
|
1533
|
+
filter: { field: 'name', operator: { type: 'equal' }, value: name },
|
|
1534
|
+
});
|
|
1535
|
+
if ((existing.items?.length ?? 0) > 0) {
|
|
1536
|
+
throw new DuplicateUserQueryNameError();
|
|
1537
|
+
}
|
|
1538
|
+
const available = (context.source?.entity?.fields ?? []).map((path) => ({ path, text: path }));
|
|
1539
|
+
const row = toUserQueryDefinitionRow(context, available);
|
|
1540
|
+
const result = await this.commandService.execute(ENTITY_INSERT_DEFAULT, {
|
|
1541
|
+
entity: `${RootConfig.module.name}.${RootConfig.entities.queryDefinition.name}`,
|
|
1542
|
+
data: row,
|
|
1543
|
+
});
|
|
1544
|
+
if (!result?.success) {
|
|
1545
|
+
throw result ?? new Error('insert');
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
async translatePersistError(error) {
|
|
1549
|
+
if (error instanceof DuplicateUserQueryNameError) {
|
|
1550
|
+
return this.translationService.translateAsync(CREATE_USER_QUERY_I18N.errors.persistDuplicate);
|
|
1551
|
+
}
|
|
1552
|
+
const info = extractRequestErrorInfo(error);
|
|
1553
|
+
const mapped = platformErrorI18nKey(info?.code);
|
|
1554
|
+
if (mapped) {
|
|
1555
|
+
return this.translationService.translateAsync(mapped);
|
|
1556
|
+
}
|
|
1557
|
+
return this.translationService.translateAsync(CREATE_USER_QUERY_I18N.errors.persistFailed);
|
|
1558
|
+
}
|
|
1515
1559
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMCreateUserQueryCommand, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1516
1560
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXMCreateUserQueryCommand, providedIn: 'root' }); }
|
|
1517
1561
|
}
|
|
@@ -1521,6 +1565,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
1521
1565
|
}] });
|
|
1522
1566
|
//#endregion
|
|
1523
1567
|
//#region ----- Helpers -----
|
|
1568
|
+
class DuplicateUserQueryNameError extends Error {
|
|
1569
|
+
constructor() {
|
|
1570
|
+
super('duplicate-query-name');
|
|
1571
|
+
this.name = 'DuplicateUserQueryNameError';
|
|
1572
|
+
}
|
|
1573
|
+
}
|
|
1524
1574
|
function resolveSourceKind(input) {
|
|
1525
1575
|
const resolved = resolveEntityActionCommandInput(input);
|
|
1526
1576
|
const data = entityActionDataRecord(resolved.data) ?? {};
|
|
@@ -1535,4 +1585,4 @@ function resolveSourceKind(input) {
|
|
|
1535
1585
|
}
|
|
1536
1586
|
|
|
1537
1587
|
export { AXMCreateUserQueryCommand };
|
|
1538
|
-
//# sourceMappingURL=acorex-platform-module-platform-management-client-create-user-query.command-
|
|
1588
|
+
//# sourceMappingURL=acorex-platform-module-platform-management-client-create-user-query.command-Bh49QHkl.mjs.map
|