@masterteam/form-builder 0.0.50 → 0.0.51
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.
|
@@ -29,10 +29,10 @@ import { DynamicForm } from '@masterteam/forms/dynamic-form';
|
|
|
29
29
|
import { ToggleField } from '@masterteam/components/toggle-field';
|
|
30
30
|
import { ModalRef } from '@masterteam/components/dialog';
|
|
31
31
|
import { CONDITION_FUNCTION_CATEGORIES, CONDITION_OPERATORS, FormulaToolbar, FormulaEditor, serializeTokens, tokenizeFormulaTemplate, serializeTokensForDisplay } from '@masterteam/components/formula';
|
|
32
|
+
import { of, map, catchError, tap, startWith } from 'rxjs';
|
|
32
33
|
import { Tooltip } from '@masterteam/components/tooltip';
|
|
33
34
|
import { ClientForm } from '@masterteam/forms/client-form';
|
|
34
35
|
import { Table } from '@masterteam/components/table';
|
|
35
|
-
import { startWith, of, map, catchError } from 'rxjs';
|
|
36
36
|
import { RadioCardsField } from '@masterteam/components/radio-cards-field';
|
|
37
37
|
import { FormulaBuilder } from '@masterteam/formula-builder';
|
|
38
38
|
|
|
@@ -1227,6 +1227,120 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
|
|
|
1227
1227
|
args: [{ providedIn: 'root' }]
|
|
1228
1228
|
}] });
|
|
1229
1229
|
|
|
1230
|
+
/**
|
|
1231
|
+
* View types whose values the backend can serve. Matched after lower-casing
|
|
1232
|
+
* and stripping spaces/underscores/dashes, and kept in step with the backend
|
|
1233
|
+
* gate (`PropertyItemsLookupSourceResolver.IsLookupBacked` plus `Status`) —
|
|
1234
|
+
* every other view type is rejected with a validation error.
|
|
1235
|
+
*/
|
|
1236
|
+
const VALUE_BACKED_VIEW_TYPES = new Set([
|
|
1237
|
+
'lookup',
|
|
1238
|
+
'lookupmultiselect',
|
|
1239
|
+
'lookupmatrix',
|
|
1240
|
+
'status',
|
|
1241
|
+
]);
|
|
1242
|
+
/** Whether a property's values can be picked from a source instead of typed. */
|
|
1243
|
+
function isValueBackedViewType(viewType) {
|
|
1244
|
+
if (!viewType)
|
|
1245
|
+
return false;
|
|
1246
|
+
return VALUE_BACKED_VIEW_TYPES.has(viewType.toLowerCase().replace(/[ _-]/g, ''));
|
|
1247
|
+
}
|
|
1248
|
+
class FormBuilderContextService {
|
|
1249
|
+
http = inject(HttpClient);
|
|
1250
|
+
baseUrl = 'context';
|
|
1251
|
+
propertyItemsCache = new Map();
|
|
1252
|
+
/**
|
|
1253
|
+
* Resolves context data including navigation paths and properties.
|
|
1254
|
+
* No caching - always fetches fresh data.
|
|
1255
|
+
*/
|
|
1256
|
+
resolveContext(contextKey, options = {}) {
|
|
1257
|
+
if (!contextKey)
|
|
1258
|
+
return of(null);
|
|
1259
|
+
return this.http
|
|
1260
|
+
.post(`${this.baseUrl}/resolve`, {
|
|
1261
|
+
contextKey,
|
|
1262
|
+
displayTags: options.displayTags,
|
|
1263
|
+
propertyFlags: options.propertyFlags,
|
|
1264
|
+
matchAllTags: options.matchAllTags,
|
|
1265
|
+
includeVirtual: options.includeVirtual,
|
|
1266
|
+
includeNavigationPaths: options.includeNavigationPaths,
|
|
1267
|
+
includeConnectionMetadata: options.includeConnectionMetadata,
|
|
1268
|
+
includeRelatedContextValues: options.includeRelatedContextValues,
|
|
1269
|
+
relatedContextsToInclude: options.relatedContextsToInclude,
|
|
1270
|
+
// Consumer-supplied fields win on collision with any field above.
|
|
1271
|
+
...options.extraParams,
|
|
1272
|
+
})
|
|
1273
|
+
.pipe(map((response) => this.normalizeResponse(response)), catchError((error) => {
|
|
1274
|
+
console.warn('Failed to resolve context:', error);
|
|
1275
|
+
return of(null);
|
|
1276
|
+
}));
|
|
1277
|
+
}
|
|
1278
|
+
/**
|
|
1279
|
+
* Gets properties for a context.
|
|
1280
|
+
* No caching - always fetches fresh data.
|
|
1281
|
+
*/
|
|
1282
|
+
getProperties(contextKey, options = {}) {
|
|
1283
|
+
if (!contextKey)
|
|
1284
|
+
return of([]);
|
|
1285
|
+
return this.resolveContext(contextKey, options).pipe(map((resolved) => resolved?.properties ?? []));
|
|
1286
|
+
}
|
|
1287
|
+
/**
|
|
1288
|
+
* Selectable values of a lookup / lookup-matrix / status property, used by
|
|
1289
|
+
* the condition builder so a compared value is picked rather than typed.
|
|
1290
|
+
*
|
|
1291
|
+
* The backend answers 400 for any other view type, which we swallow into an
|
|
1292
|
+
* empty list — callers already gate on `isValueBackedViewType`, so empty
|
|
1293
|
+
* simply means "nothing to pick".
|
|
1294
|
+
*/
|
|
1295
|
+
getPropertyItems(propertyKey) {
|
|
1296
|
+
if (!propertyKey)
|
|
1297
|
+
return of([]);
|
|
1298
|
+
const cached = this.propertyItemsCache.get(propertyKey);
|
|
1299
|
+
if (cached)
|
|
1300
|
+
return of(cached);
|
|
1301
|
+
return this.http
|
|
1302
|
+
.get(`formulas/builder/property-items/${encodeURIComponent(propertyKey)}`)
|
|
1303
|
+
.pipe(map((response) => {
|
|
1304
|
+
const payload = response && 'data' in response ? response.data : response;
|
|
1305
|
+
return payload?.items ?? [];
|
|
1306
|
+
}), tap((items) => this.propertyItemsCache.set(propertyKey, items)), catchError((error) => {
|
|
1307
|
+
console.warn('Failed to load property items:', error);
|
|
1308
|
+
return of([]);
|
|
1309
|
+
}));
|
|
1310
|
+
}
|
|
1311
|
+
normalizeResponse(response) {
|
|
1312
|
+
const payload = response?.data ?? response;
|
|
1313
|
+
if (!payload)
|
|
1314
|
+
return null;
|
|
1315
|
+
const properties = this.normalizeProperties(payload.properties ?? []);
|
|
1316
|
+
return {
|
|
1317
|
+
...payload,
|
|
1318
|
+
properties,
|
|
1319
|
+
};
|
|
1320
|
+
}
|
|
1321
|
+
normalizeProperties(raw) {
|
|
1322
|
+
return (raw ?? [])
|
|
1323
|
+
.map((prop) => {
|
|
1324
|
+
const key = prop?.key ?? prop?.propertyKey;
|
|
1325
|
+
if (!key)
|
|
1326
|
+
return null;
|
|
1327
|
+
const name = prop?.name ?? prop?.displayName ?? key;
|
|
1328
|
+
return {
|
|
1329
|
+
...prop,
|
|
1330
|
+
key,
|
|
1331
|
+
name,
|
|
1332
|
+
};
|
|
1333
|
+
})
|
|
1334
|
+
.filter((prop) => Boolean(prop));
|
|
1335
|
+
}
|
|
1336
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: FormBuilderContextService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1337
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: FormBuilderContextService, providedIn: 'root' });
|
|
1338
|
+
}
|
|
1339
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: FormBuilderContextService, decorators: [{
|
|
1340
|
+
type: Injectable,
|
|
1341
|
+
args: [{ providedIn: 'root' }]
|
|
1342
|
+
}] });
|
|
1343
|
+
|
|
1230
1344
|
/**
|
|
1231
1345
|
* Field Conditions Dialog
|
|
1232
1346
|
*
|
|
@@ -1235,6 +1349,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
|
|
|
1235
1349
|
*/
|
|
1236
1350
|
class FBFieldConditions {
|
|
1237
1351
|
modalService = inject(ModalService);
|
|
1352
|
+
contextService = inject(FormBuilderContextService);
|
|
1238
1353
|
ref = inject(ModalRef);
|
|
1239
1354
|
transloco = inject(TranslocoService);
|
|
1240
1355
|
destroyRef = inject(DestroyRef);
|
|
@@ -1253,11 +1368,16 @@ class FBFieldConditions {
|
|
|
1253
1368
|
// Condition-specific functions and operators
|
|
1254
1369
|
functionCategories = CONDITION_FUNCTION_CATEGORIES;
|
|
1255
1370
|
operators = CONDITION_OPERATORS;
|
|
1371
|
+
/** Values already loaded, keyed by property key. */
|
|
1372
|
+
propertyValues = signal({}, ...(ngDevMode ? [{ debugName: "propertyValues" }] : /* istanbul ignore next */ []));
|
|
1373
|
+
/** Property key whose values are being fetched right now. */
|
|
1374
|
+
loadingValuesFor = signal(null, ...(ngDevMode ? [{ debugName: "loadingValuesFor" }] : /* istanbul ignore next */ []));
|
|
1256
1375
|
/** Property display items for toolbar; keys remain the persisted formula value. */
|
|
1257
1376
|
propertyItems = computed(() => this.availableFields().map((field) => ({
|
|
1258
1377
|
key: field.key,
|
|
1259
1378
|
name: field.name,
|
|
1260
1379
|
description: field.type ? `${field.name} (${field.type})` : field.name,
|
|
1380
|
+
hasValues: isValueBackedViewType(field.type),
|
|
1261
1381
|
})), ...(ngDevMode ? [{ debugName: "propertyItems" }] : /* istanbul ignore next */ []));
|
|
1262
1382
|
/** Toolbar labels */
|
|
1263
1383
|
toolbarLabels = computed(() => {
|
|
@@ -1267,6 +1387,8 @@ class FBFieldConditions {
|
|
|
1267
1387
|
properties: this.transloco.translate('formBuilder.toolbar-fields'),
|
|
1268
1388
|
operators: this.transloco.translate('formBuilder.toolbar-operators'),
|
|
1269
1389
|
noPropertiesAvailable: this.transloco.translate('formBuilder.toolbar-no-fields'),
|
|
1390
|
+
values: this.transloco.translate('formBuilder.toolbar-values'),
|
|
1391
|
+
noValuesAvailable: this.transloco.translate('formBuilder.toolbar-no-values'),
|
|
1270
1392
|
};
|
|
1271
1393
|
}, ...(ngDevMode ? [{ debugName: "toolbarLabels" }] : /* istanbul ignore next */ []));
|
|
1272
1394
|
constructor() {
|
|
@@ -1289,6 +1411,28 @@ class FBFieldConditions {
|
|
|
1289
1411
|
}
|
|
1290
1412
|
}
|
|
1291
1413
|
}
|
|
1414
|
+
/**
|
|
1415
|
+
* Load the selectable values of a lookup / status field the first time its
|
|
1416
|
+
* value list is opened, so the compared value is picked from the real source
|
|
1417
|
+
* instead of typed as free text.
|
|
1418
|
+
*/
|
|
1419
|
+
onPropertyValuesRequest(propertyKey) {
|
|
1420
|
+
if (this.propertyValues()[propertyKey] !== undefined)
|
|
1421
|
+
return;
|
|
1422
|
+
this.loadingValuesFor.set(propertyKey);
|
|
1423
|
+
this.contextService
|
|
1424
|
+
.getPropertyItems(propertyKey)
|
|
1425
|
+
.pipe(takeUntilDestroyed(this.destroyRef))
|
|
1426
|
+
.subscribe((items) => {
|
|
1427
|
+
this.propertyValues.update((current) => ({
|
|
1428
|
+
...current,
|
|
1429
|
+
[propertyKey]: items,
|
|
1430
|
+
}));
|
|
1431
|
+
if (this.loadingValuesFor() === propertyKey) {
|
|
1432
|
+
this.loadingValuesFor.set(null);
|
|
1433
|
+
}
|
|
1434
|
+
});
|
|
1435
|
+
}
|
|
1292
1436
|
/** Handle block insert from toolbar */
|
|
1293
1437
|
onBlockInsert(block) {
|
|
1294
1438
|
const editor = this.editorRef();
|
|
@@ -1326,7 +1470,7 @@ class FBFieldConditions {
|
|
|
1326
1470
|
return raw.trim();
|
|
1327
1471
|
}
|
|
1328
1472
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: FBFieldConditions, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1329
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.8", type: FBFieldConditions, isStandalone: true, selector: "mt-fb-field-conditions", inputs: { initialFormula: { classPropertyName: "initialFormula", publicName: "initialFormula", isSignal: true, isRequired: false, transformFunction: null }, availableFields: { classPropertyName: "availableFields", publicName: "availableFields", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "editorRef", first: true, predicate: ["editor"], descendants: true, isSignal: true }], ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'formBuilder'\">\
|
|
1473
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.8", type: FBFieldConditions, isStandalone: true, selector: "mt-fb-field-conditions", inputs: { initialFormula: { classPropertyName: "initialFormula", publicName: "initialFormula", isSignal: true, isRequired: false, transformFunction: null }, availableFields: { classPropertyName: "availableFields", publicName: "availableFields", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "editorRef", first: true, predicate: ["editor"], descendants: true, isSignal: true }], ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'formBuilder'\">\n <div\n [class]=\"[\n modalService.contentClass,\n 'min-w-0',\n 'p-4',\n 'overflow-y-hidden!',\n 'max-[640px]:p-3',\n ]\"\n >\n <div class=\"mt-4 flex h-full min-h-0 flex-col gap-3 overflow-y-auto pb-10\">\n <!-- Formula Toolbar -->\n <mt-formula-toolbar\n [knownProperties]=\"propertyItems()\"\n [propertyValues]=\"propertyValues()\"\n [loadingValuesFor]=\"loadingValuesFor()\"\n [functionCategories]=\"functionCategories\"\n [operators]=\"operators\"\n [labels]=\"toolbarLabels()\"\n (onBlockInsert)=\"onBlockInsert($event)\"\n (onPropertyValuesRequest)=\"onPropertyValuesRequest($event)\"\n />\n <!-- Formula Editor -->\n <mt-formula-editor\n #editor\n [placeholder]=\"t('build-condition-formula')\"\n [formControl]=\"formulaControl\"\n />\n </div>\n </div>\n\n <div\n [class]=\"[\n modalService.footerClass,\n '!h-auto',\n 'min-h-0',\n 'flex-col',\n 'gap-2',\n 'sm:flex-row',\n 'sm:items-center',\n 'sm:justify-end',\n ]\"\n >\n <mt-button\n [label]=\"t('cancel')\"\n variant=\"outlined\"\n [disabled]=\"submitting()\"\n styleClass=\"w-full sm:w-auto\"\n (onClick)=\"onCancel()\"\n />\n <mt-button\n [label]=\"t('save')\"\n severity=\"primary\"\n [loading]=\"submitting()\"\n styleClass=\"w-full sm:w-auto\"\n (onClick)=\"onSave()\"\n />\n </div>\n</ng-container>\n", dependencies: [{ kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs", "ariaLabel"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: FormulaToolbar, selector: "mt-formula-toolbar", inputs: ["knownProperties", "propertiesTemplate", "propertyValues", "loadingValuesFor", "functionCategories", "operators", "initialTab", "visibleTabs", "searchPlaceholder", "labels"], outputs: ["onBlockInsert", "onTabChange", "onPropertyValuesRequest"] }, { kind: "component", type: FormulaEditor, selector: "mt-formula-editor", inputs: ["placeholder", "initialTokens", "disabled", "borderless"], outputs: ["formulaChange", "tokensChange", "onBlur", "onFocus"] }] });
|
|
1330
1474
|
}
|
|
1331
1475
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: FBFieldConditions, decorators: [{
|
|
1332
1476
|
type: Component,
|
|
@@ -1336,7 +1480,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
|
|
|
1336
1480
|
Button,
|
|
1337
1481
|
FormulaToolbar,
|
|
1338
1482
|
FormulaEditor,
|
|
1339
|
-
], template: "<ng-container *transloco=\"let t; prefix: 'formBuilder'\">\
|
|
1483
|
+
], template: "<ng-container *transloco=\"let t; prefix: 'formBuilder'\">\n <div\n [class]=\"[\n modalService.contentClass,\n 'min-w-0',\n 'p-4',\n 'overflow-y-hidden!',\n 'max-[640px]:p-3',\n ]\"\n >\n <div class=\"mt-4 flex h-full min-h-0 flex-col gap-3 overflow-y-auto pb-10\">\n <!-- Formula Toolbar -->\n <mt-formula-toolbar\n [knownProperties]=\"propertyItems()\"\n [propertyValues]=\"propertyValues()\"\n [loadingValuesFor]=\"loadingValuesFor()\"\n [functionCategories]=\"functionCategories\"\n [operators]=\"operators\"\n [labels]=\"toolbarLabels()\"\n (onBlockInsert)=\"onBlockInsert($event)\"\n (onPropertyValuesRequest)=\"onPropertyValuesRequest($event)\"\n />\n <!-- Formula Editor -->\n <mt-formula-editor\n #editor\n [placeholder]=\"t('build-condition-formula')\"\n [formControl]=\"formulaControl\"\n />\n </div>\n </div>\n\n <div\n [class]=\"[\n modalService.footerClass,\n '!h-auto',\n 'min-h-0',\n 'flex-col',\n 'gap-2',\n 'sm:flex-row',\n 'sm:items-center',\n 'sm:justify-end',\n ]\"\n >\n <mt-button\n [label]=\"t('cancel')\"\n variant=\"outlined\"\n [disabled]=\"submitting()\"\n styleClass=\"w-full sm:w-auto\"\n (onClick)=\"onCancel()\"\n />\n <mt-button\n [label]=\"t('save')\"\n severity=\"primary\"\n [loading]=\"submitting()\"\n styleClass=\"w-full sm:w-auto\"\n (onClick)=\"onSave()\"\n />\n </div>\n</ng-container>\n" }]
|
|
1340
1484
|
}], ctorParameters: () => [], propDecorators: { initialFormula: [{ type: i0.Input, args: [{ isSignal: true, alias: "initialFormula", required: false }] }], availableFields: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableFields", required: false }] }], editorRef: [{ type: i0.ViewChild, args: ['editor', { isSignal: true }] }] } });
|
|
1341
1485
|
|
|
1342
1486
|
class FBFieldForm {
|
|
@@ -2453,77 +2597,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
|
|
|
2453
2597
|
args: [{ selector: 'mt-fb-validation-rules', standalone: true, imports: [TranslocoDirective, Table, Button], template: "<ng-container *transloco=\"let t; prefix: 'formBuilder'\">\r\n <div\r\n [class]=\"[\r\n modalService.contentClass,\r\n 'min-w-0',\r\n 'p-4',\r\n 'overflow-y-auto',\r\n 'max-[640px]:p-3',\r\n ]\"\r\n >\r\n <div class=\"flex justify-end pb-4 max-[640px]:justify-stretch\">\r\n <mt-button\r\n [label]=\"t('add-validation-rule')\"\r\n severity=\"primary\"\r\n variant=\"outlined\"\r\n styleClass=\"w-full sm:w-auto\"\r\n (onClick)=\"openCreate()\"\r\n ></mt-button>\r\n </div>\r\n <mt-table\r\n noCard\r\n [data]=\"tableRows()\"\r\n [columns]=\"tableColumns()\"\r\n [rowActions]=\"rowActions()\"\r\n storageKey=\"fb-validation-rules-table\"\r\n (cellChange)=\"onCellChange($event)\"\r\n ></mt-table>\r\n </div>\r\n</ng-container>\r\n" }]
|
|
2454
2598
|
}], ctorParameters: () => [] });
|
|
2455
2599
|
|
|
2456
|
-
class FormBuilderContextService {
|
|
2457
|
-
http = inject(HttpClient);
|
|
2458
|
-
baseUrl = 'context';
|
|
2459
|
-
/**
|
|
2460
|
-
* Resolves context data including navigation paths and properties.
|
|
2461
|
-
* No caching - always fetches fresh data.
|
|
2462
|
-
*/
|
|
2463
|
-
resolveContext(contextKey, options = {}) {
|
|
2464
|
-
if (!contextKey)
|
|
2465
|
-
return of(null);
|
|
2466
|
-
return this.http
|
|
2467
|
-
.post(`${this.baseUrl}/resolve`, {
|
|
2468
|
-
contextKey,
|
|
2469
|
-
displayTags: options.displayTags,
|
|
2470
|
-
propertyFlags: options.propertyFlags,
|
|
2471
|
-
matchAllTags: options.matchAllTags,
|
|
2472
|
-
includeVirtual: options.includeVirtual,
|
|
2473
|
-
includeNavigationPaths: options.includeNavigationPaths,
|
|
2474
|
-
includeConnectionMetadata: options.includeConnectionMetadata,
|
|
2475
|
-
includeRelatedContextValues: options.includeRelatedContextValues,
|
|
2476
|
-
relatedContextsToInclude: options.relatedContextsToInclude,
|
|
2477
|
-
// Consumer-supplied fields win on collision with any field above.
|
|
2478
|
-
...options.extraParams,
|
|
2479
|
-
})
|
|
2480
|
-
.pipe(map((response) => this.normalizeResponse(response)), catchError((error) => {
|
|
2481
|
-
console.warn('Failed to resolve context:', error);
|
|
2482
|
-
return of(null);
|
|
2483
|
-
}));
|
|
2484
|
-
}
|
|
2485
|
-
/**
|
|
2486
|
-
* Gets properties for a context.
|
|
2487
|
-
* No caching - always fetches fresh data.
|
|
2488
|
-
*/
|
|
2489
|
-
getProperties(contextKey, options = {}) {
|
|
2490
|
-
if (!contextKey)
|
|
2491
|
-
return of([]);
|
|
2492
|
-
return this.resolveContext(contextKey, options).pipe(map((resolved) => resolved?.properties ?? []));
|
|
2493
|
-
}
|
|
2494
|
-
normalizeResponse(response) {
|
|
2495
|
-
const payload = response?.data ?? response;
|
|
2496
|
-
if (!payload)
|
|
2497
|
-
return null;
|
|
2498
|
-
const properties = this.normalizeProperties(payload.properties ?? []);
|
|
2499
|
-
return {
|
|
2500
|
-
...payload,
|
|
2501
|
-
properties,
|
|
2502
|
-
};
|
|
2503
|
-
}
|
|
2504
|
-
normalizeProperties(raw) {
|
|
2505
|
-
return (raw ?? [])
|
|
2506
|
-
.map((prop) => {
|
|
2507
|
-
const key = prop?.key ?? prop?.propertyKey;
|
|
2508
|
-
if (!key)
|
|
2509
|
-
return null;
|
|
2510
|
-
const name = prop?.name ?? prop?.displayName ?? key;
|
|
2511
|
-
return {
|
|
2512
|
-
...prop,
|
|
2513
|
-
key,
|
|
2514
|
-
name,
|
|
2515
|
-
};
|
|
2516
|
-
})
|
|
2517
|
-
.filter((prop) => Boolean(prop));
|
|
2518
|
-
}
|
|
2519
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: FormBuilderContextService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2520
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: FormBuilderContextService, providedIn: 'root' });
|
|
2521
|
-
}
|
|
2522
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: FormBuilderContextService, decorators: [{
|
|
2523
|
-
type: Injectable,
|
|
2524
|
-
args: [{ providedIn: 'root' }]
|
|
2525
|
-
}] });
|
|
2526
|
-
|
|
2527
2600
|
const SECTIONS_DROP_LIST_ID = 'sections-list';
|
|
2528
2601
|
const SCOPE_ORDER = [
|
|
2529
2602
|
'Current',
|