@masterteam/properties 0.0.28 → 0.0.30
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.
|
@@ -5,8 +5,9 @@ import { Table } from '@masterteam/components/table';
|
|
|
5
5
|
import { Router, ActivatedRoute } from '@angular/router';
|
|
6
6
|
import { HttpClient, HttpContextToken } from '@angular/common/http';
|
|
7
7
|
import { Action, Selector, State, Store, select } from '@ngxs/store';
|
|
8
|
-
import { of, finalize
|
|
9
|
-
import {
|
|
8
|
+
import { of, finalize, startWith, map, distinctUntilChanged, Subscription } from 'rxjs';
|
|
9
|
+
import { switchMap, tap } from 'rxjs/operators';
|
|
10
|
+
import { CrudStateBase, handleApiRequest, PickListFieldConfig, ValidatorConfig } from '@masterteam/components';
|
|
10
11
|
import { Breadcrumb } from '@masterteam/components/breadcrumb';
|
|
11
12
|
import { Card } from '@masterteam/components/card';
|
|
12
13
|
import { Avatar } from '@masterteam/components/avatar';
|
|
@@ -17,39 +18,29 @@ import { TranslocoService, TranslocoModule } from '@jsverse/transloco';
|
|
|
17
18
|
import { toSignal } from '@angular/core/rxjs-interop';
|
|
18
19
|
import { Page } from '@masterteam/components/page';
|
|
19
20
|
import { DynamicForm } from '@masterteam/forms/dynamic-form';
|
|
20
|
-
import { PickListFieldConfig, ValidatorConfig } from '@masterteam/components';
|
|
21
21
|
import * as i1$1 from '@angular/forms';
|
|
22
22
|
import { FormGroup, FormControl, FormArray, Validators, ReactiveFormsModule, NG_VALUE_ACCESSOR, ControlContainer, FormGroupDirective } from '@angular/forms';
|
|
23
23
|
import * as i2 from 'primeng/skeleton';
|
|
24
24
|
import { SkeletonModule } from 'primeng/skeleton';
|
|
25
|
+
import { FormulaBuilder } from '@masterteam/formula-builder';
|
|
25
26
|
import { SelectField } from '@masterteam/components/select-field';
|
|
26
27
|
import { TextField } from '@masterteam/components/text-field';
|
|
27
28
|
import { ToggleField } from '@masterteam/components/toggle-field';
|
|
28
29
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
ctx.patchState({
|
|
44
|
-
loadingActive: loadingActive.filter((name) => name !== loadingName),
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
function setLoadingError(ctx, loadingName, message) {
|
|
48
|
-
const { errors } = ctx.getState();
|
|
49
|
-
ctx.patchState({
|
|
50
|
-
errors: { ...errors, [loadingName]: message },
|
|
51
|
-
});
|
|
52
|
-
}
|
|
30
|
+
var PropertiesActionKey;
|
|
31
|
+
(function (PropertiesActionKey) {
|
|
32
|
+
PropertiesActionKey["GetAll"] = "getAll";
|
|
33
|
+
PropertiesActionKey["GetOne"] = "getOne";
|
|
34
|
+
PropertiesActionKey["Create"] = "create";
|
|
35
|
+
PropertiesActionKey["Update"] = "update";
|
|
36
|
+
PropertiesActionKey["Delete"] = "delete";
|
|
37
|
+
PropertiesActionKey["GetLookups"] = "getLookups";
|
|
38
|
+
PropertiesActionKey["GetGroups"] = "getGroups";
|
|
39
|
+
PropertiesActionKey["GetConfigProperties"] = "getConfigProperties";
|
|
40
|
+
PropertiesActionKey["GetConfigAsType"] = "getConfigAsType";
|
|
41
|
+
PropertiesActionKey["GetCountries"] = "getCountries";
|
|
42
|
+
PropertiesActionKey["TestApiConfiguration"] = "testApiConfiguration";
|
|
43
|
+
})(PropertiesActionKey || (PropertiesActionKey = {}));
|
|
53
44
|
|
|
54
45
|
class GetProperties {
|
|
55
46
|
params;
|
|
@@ -197,7 +188,7 @@ const DEFAULT_STATE = {
|
|
|
197
188
|
breadcrumbItems: [],
|
|
198
189
|
defaultViewType: null,
|
|
199
190
|
};
|
|
200
|
-
let PropertiesState = class PropertiesState {
|
|
191
|
+
let PropertiesState = class PropertiesState extends CrudStateBase {
|
|
201
192
|
http = inject(HttpClient);
|
|
202
193
|
baseUrl = 'Properties';
|
|
203
194
|
lookupsUrl = 'Lookups';
|
|
@@ -206,12 +197,21 @@ let PropertiesState = class PropertiesState {
|
|
|
206
197
|
countriesUrl = '/assets/countries/countries.json';
|
|
207
198
|
apiTestUrl = 'app/testAPI';
|
|
208
199
|
apiDetectUrl = 'app/detect';
|
|
200
|
+
// ============================================================================
|
|
201
|
+
// Data Selectors - Individual for fine-grained reactivity
|
|
202
|
+
// ============================================================================
|
|
209
203
|
static properties(state) {
|
|
210
204
|
return state.properties;
|
|
211
205
|
}
|
|
212
206
|
static selectedProperty(state) {
|
|
213
207
|
return state.selectedProperty;
|
|
214
208
|
}
|
|
209
|
+
static moduleId(state) {
|
|
210
|
+
return state.moduleId;
|
|
211
|
+
}
|
|
212
|
+
static parentModuleId(state) {
|
|
213
|
+
return state.parentModuleId ?? null;
|
|
214
|
+
}
|
|
215
215
|
static lookups(state) {
|
|
216
216
|
return state.lookups;
|
|
217
217
|
}
|
|
@@ -234,7 +234,7 @@ let PropertiesState = class PropertiesState {
|
|
|
234
234
|
return state.apiProperties;
|
|
235
235
|
}
|
|
236
236
|
static propertyTypes(state) {
|
|
237
|
-
return state.propertyTypes ??
|
|
237
|
+
return state.propertyTypes ?? {};
|
|
238
238
|
}
|
|
239
239
|
static breadcrumbItems(state) {
|
|
240
240
|
return state.breadcrumbItems;
|
|
@@ -242,17 +242,25 @@ let PropertiesState = class PropertiesState {
|
|
|
242
242
|
static defaultViewType(state) {
|
|
243
243
|
return state.defaultViewType;
|
|
244
244
|
}
|
|
245
|
-
|
|
246
|
-
|
|
245
|
+
// ============================================================================
|
|
246
|
+
// Loading/Error Slice Selectors - REQUIRED for optimal performance
|
|
247
|
+
// ============================================================================
|
|
248
|
+
static getLoadingActive(state) {
|
|
249
|
+
return state.loadingActive;
|
|
247
250
|
}
|
|
248
|
-
static
|
|
249
|
-
return
|
|
251
|
+
static getErrors(state) {
|
|
252
|
+
return state.errors;
|
|
250
253
|
}
|
|
254
|
+
// ============================================================================
|
|
255
|
+
// Derived Selectors
|
|
256
|
+
// ============================================================================
|
|
251
257
|
static propertyById(state) {
|
|
252
258
|
return (id) => state.properties.find((property) => property.id === Number(id)) ?? null;
|
|
253
259
|
}
|
|
260
|
+
// ============================================================================
|
|
261
|
+
// CRUD Actions
|
|
262
|
+
// ============================================================================
|
|
254
263
|
getAll(ctx, action) {
|
|
255
|
-
startLoading(ctx, 'getAll');
|
|
256
264
|
const state = ctx.getState();
|
|
257
265
|
const moduleType = state.moduleType ?? undefined;
|
|
258
266
|
const moduleId = state.moduleId ?? undefined;
|
|
@@ -261,67 +269,57 @@ let PropertiesState = class PropertiesState {
|
|
|
261
269
|
ctx.patchState({
|
|
262
270
|
lastQueryParams: params ?? null,
|
|
263
271
|
});
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
error?.message ??
|
|
274
|
-
'Failed to load properties';
|
|
275
|
-
setLoadingError(ctx, 'getAll', message);
|
|
276
|
-
return of(null);
|
|
277
|
-
}), finalize(() => endLoading(ctx, 'getAll')));
|
|
272
|
+
const req$ = this.http.get(`${this.baseUrl}${parentPath}/${moduleType}/${moduleId}`, { params });
|
|
273
|
+
return handleApiRequest({
|
|
274
|
+
ctx,
|
|
275
|
+
key: PropertiesActionKey.GetAll,
|
|
276
|
+
request$: req$,
|
|
277
|
+
onSuccess: (response) => ({
|
|
278
|
+
properties: response.data ?? [],
|
|
279
|
+
}),
|
|
280
|
+
});
|
|
278
281
|
}
|
|
279
282
|
getOne(ctx, action) {
|
|
280
|
-
startLoading(ctx, 'getOne');
|
|
281
283
|
const params = { mode: action.mode ?? 'edit' };
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
'Failed to load property';
|
|
292
|
-
setLoadingError(ctx, 'getOne', message);
|
|
293
|
-
return of(null);
|
|
294
|
-
}), finalize(() => endLoading(ctx, 'getOne')));
|
|
284
|
+
const req$ = this.http.get(`${this.baseUrl}/${action.id}`, { params });
|
|
285
|
+
return handleApiRequest({
|
|
286
|
+
ctx,
|
|
287
|
+
key: PropertiesActionKey.GetOne,
|
|
288
|
+
request$: req$,
|
|
289
|
+
onSuccess: (response) => ({
|
|
290
|
+
selectedProperty: response.data ?? null,
|
|
291
|
+
}),
|
|
292
|
+
});
|
|
295
293
|
}
|
|
296
294
|
getLookups(ctx, _action) {
|
|
297
295
|
const state = ctx.getState();
|
|
298
296
|
if (state.lookups.length) {
|
|
299
297
|
return of(state.lookups);
|
|
300
298
|
}
|
|
301
|
-
|
|
302
|
-
return
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
})
|
|
299
|
+
const req$ = this.http.get(this.lookupsUrl);
|
|
300
|
+
return handleApiRequest({
|
|
301
|
+
ctx,
|
|
302
|
+
key: PropertiesActionKey.GetLookups,
|
|
303
|
+
request$: req$,
|
|
304
|
+
onSuccess: (response) => ({
|
|
305
|
+
lookups: response.data ?? [],
|
|
306
|
+
}),
|
|
307
|
+
});
|
|
310
308
|
}
|
|
311
309
|
getGroups(ctx, _action) {
|
|
312
310
|
const state = ctx.getState();
|
|
313
311
|
if (state.groups.length) {
|
|
314
312
|
return of(state.groups);
|
|
315
313
|
}
|
|
316
|
-
|
|
317
|
-
return
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
})
|
|
314
|
+
const req$ = this.http.get(this.groupsUrl);
|
|
315
|
+
return handleApiRequest({
|
|
316
|
+
ctx,
|
|
317
|
+
key: PropertiesActionKey.GetGroups,
|
|
318
|
+
request$: req$,
|
|
319
|
+
onSuccess: (response) => ({
|
|
320
|
+
groups: response.data ?? [],
|
|
321
|
+
}),
|
|
322
|
+
});
|
|
325
323
|
}
|
|
326
324
|
getConfigAsType(ctx, action) {
|
|
327
325
|
const state = ctx.getState();
|
|
@@ -329,41 +327,41 @@ let PropertiesState = class PropertiesState {
|
|
|
329
327
|
if (state.configScopes.length) {
|
|
330
328
|
return of(state.configScopes);
|
|
331
329
|
}
|
|
332
|
-
startLoading(ctx, 'getConfigAsType');
|
|
333
330
|
const url = `${this.baseUrl}/${action.viewType}/GetViewTypeProperties`;
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
ctx
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
}), finalize(() => endLoading(ctx, 'getConfigAsType')));
|
|
331
|
+
const req$ = this.http.get(url);
|
|
332
|
+
return handleApiRequest({
|
|
333
|
+
ctx,
|
|
334
|
+
key: PropertiesActionKey.GetConfigAsType,
|
|
335
|
+
request$: req$,
|
|
336
|
+
onSuccess: (response) => ({
|
|
337
|
+
configScopes: response.data ?? [],
|
|
338
|
+
}),
|
|
339
|
+
});
|
|
344
340
|
}
|
|
345
341
|
getCountries(ctx, _action) {
|
|
346
342
|
const state = ctx.getState();
|
|
347
343
|
if (state.countries.length) {
|
|
348
344
|
return of(state.countries);
|
|
349
345
|
}
|
|
350
|
-
|
|
351
|
-
return
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
346
|
+
const req$ = this.http.get(this.countriesUrl);
|
|
347
|
+
return handleApiRequest({
|
|
348
|
+
ctx,
|
|
349
|
+
key: PropertiesActionKey.GetCountries,
|
|
350
|
+
request$: req$,
|
|
351
|
+
onSuccess: (response) => ({
|
|
352
|
+
countries: Array.isArray(response) ? response : [],
|
|
353
|
+
}),
|
|
354
|
+
errorMessage: 'Failed to load countries',
|
|
355
|
+
});
|
|
359
356
|
}
|
|
360
357
|
testApiConfiguration(ctx, action) {
|
|
361
|
-
startLoading(ctx, 'testApiConfiguration');
|
|
362
358
|
ctx.patchState({
|
|
363
359
|
apiSchema: null,
|
|
364
360
|
apiProperties: [],
|
|
365
361
|
});
|
|
366
|
-
|
|
362
|
+
const req$ = this.http
|
|
363
|
+
.post(this.apiTestUrl, action.payload)
|
|
364
|
+
.pipe(switchMap((testResponse) => {
|
|
367
365
|
const rawData = testResponse?.data;
|
|
368
366
|
if (!rawData) {
|
|
369
367
|
return of(null);
|
|
@@ -380,49 +378,29 @@ let PropertiesState = class PropertiesState {
|
|
|
380
378
|
apiProperties,
|
|
381
379
|
});
|
|
382
380
|
}));
|
|
383
|
-
})
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
resetApiConfiguration(ctx) {
|
|
390
|
-
ctx.patchState({
|
|
391
|
-
apiSchema: null,
|
|
392
|
-
apiProperties: [],
|
|
393
|
-
});
|
|
394
|
-
}
|
|
395
|
-
mapSchemaToOptions(schema) {
|
|
396
|
-
if (!schema?.properties) {
|
|
397
|
-
return [];
|
|
398
|
-
}
|
|
399
|
-
return Object.entries(schema.properties).map(([key, definition]) => {
|
|
400
|
-
const typeLabel = definition?.type ? ` | ${definition.type}` : '';
|
|
401
|
-
return {
|
|
402
|
-
key,
|
|
403
|
-
name: `${key}${typeLabel}`,
|
|
404
|
-
type: definition?.type,
|
|
405
|
-
};
|
|
381
|
+
}));
|
|
382
|
+
return handleApiRequest({
|
|
383
|
+
ctx,
|
|
384
|
+
key: PropertiesActionKey.TestApiConfiguration,
|
|
385
|
+
request$: req$,
|
|
386
|
+
onSuccess: () => ({}),
|
|
406
387
|
});
|
|
407
388
|
}
|
|
408
389
|
getPropertiesForConfigType(ctx, action) {
|
|
409
|
-
startLoading(ctx, 'getConfigProperties');
|
|
410
390
|
const { moduleType, moduleId } = action;
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
error?.message ??
|
|
421
|
-
'Failed to load properties';
|
|
422
|
-
setLoadingError(ctx, 'getConfigProperties', message);
|
|
423
|
-
return of([]);
|
|
424
|
-
}), finalize(() => endLoading(ctx, 'getConfigProperties')));
|
|
391
|
+
const req$ = this.http.get(`${this.configPropertiesUrl}/${moduleType}/${moduleId}`);
|
|
392
|
+
return handleApiRequest({
|
|
393
|
+
ctx,
|
|
394
|
+
key: PropertiesActionKey.GetConfigProperties,
|
|
395
|
+
request$: req$,
|
|
396
|
+
onSuccess: (response) => ({
|
|
397
|
+
configTypeProperties: response.data ?? [],
|
|
398
|
+
}),
|
|
399
|
+
});
|
|
425
400
|
}
|
|
401
|
+
// ============================================================================
|
|
402
|
+
// Simple State Updates (No HTTP)
|
|
403
|
+
// ============================================================================
|
|
426
404
|
resetConfigProperties(ctx) {
|
|
427
405
|
ctx.patchState({ configTypeProperties: [] });
|
|
428
406
|
}
|
|
@@ -432,6 +410,12 @@ let PropertiesState = class PropertiesState {
|
|
|
432
410
|
resetSelectedProperty(ctx) {
|
|
433
411
|
ctx.patchState({ selectedProperty: null });
|
|
434
412
|
}
|
|
413
|
+
resetApiConfiguration(ctx) {
|
|
414
|
+
ctx.patchState({
|
|
415
|
+
apiSchema: null,
|
|
416
|
+
apiProperties: [],
|
|
417
|
+
});
|
|
418
|
+
}
|
|
435
419
|
setModuleInfo(ctx, action) {
|
|
436
420
|
let parentPath = '';
|
|
437
421
|
if (action.parentModuleType && action.parentModuleId) {
|
|
@@ -448,106 +432,107 @@ let PropertiesState = class PropertiesState {
|
|
|
448
432
|
parentPath: parentPath ?? '',
|
|
449
433
|
});
|
|
450
434
|
}
|
|
451
|
-
|
|
452
|
-
|
|
435
|
+
SetPropertyTypes(ctx, action) {
|
|
436
|
+
ctx.patchState({
|
|
437
|
+
propertyTypes: action.payload,
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
setBreadcrumb(ctx, action) {
|
|
441
|
+
ctx.patchState({
|
|
442
|
+
breadcrumbItems: action.items,
|
|
443
|
+
});
|
|
444
|
+
}
|
|
445
|
+
setDefaultViewType(ctx, action) {
|
|
446
|
+
ctx.patchState({
|
|
447
|
+
defaultViewType: action.viewType,
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
createProperty(ctx, action) {
|
|
453
451
|
const state = ctx.getState();
|
|
454
452
|
const moduleType = state.moduleType ?? undefined;
|
|
455
453
|
const moduleId = state.moduleId ?? undefined;
|
|
456
454
|
const parentPath = state.parentPath ?? '';
|
|
457
455
|
if (!moduleType || moduleId === undefined || moduleId === null) {
|
|
458
|
-
|
|
459
|
-
setLoadingError(ctx, 'create', message);
|
|
460
|
-
endLoading(ctx, 'create');
|
|
456
|
+
console.error('Missing module context for creating property');
|
|
461
457
|
return of(null);
|
|
462
458
|
}
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
459
|
+
const req$ = this.http.post(`${this.baseUrl}${parentPath}/${moduleType}/${moduleId}`, action.payload);
|
|
460
|
+
return handleApiRequest({
|
|
461
|
+
ctx,
|
|
462
|
+
key: PropertiesActionKey.Create,
|
|
463
|
+
request$: req$,
|
|
464
|
+
onSuccess: (response, state) => {
|
|
465
|
+
const created = response.data;
|
|
466
|
+
if (!created)
|
|
467
|
+
return {};
|
|
468
|
+
return {
|
|
469
|
+
properties: this.adapter.addOne(state.properties, created),
|
|
470
|
+
selectedProperty: created,
|
|
471
|
+
};
|
|
472
|
+
},
|
|
473
|
+
});
|
|
476
474
|
}
|
|
477
|
-
|
|
478
|
-
startLoading(ctx, 'update');
|
|
475
|
+
updateProperty(ctx, action) {
|
|
479
476
|
const state = ctx.getState();
|
|
480
477
|
const moduleType = state.moduleType ?? undefined;
|
|
481
478
|
const moduleId = state.moduleId ?? undefined;
|
|
482
479
|
const parentPath = state.parentPath ?? '';
|
|
483
480
|
if (!moduleType || moduleId === undefined || moduleId === null) {
|
|
484
|
-
|
|
485
|
-
setLoadingError(ctx, 'update', message);
|
|
486
|
-
endLoading(ctx, 'update');
|
|
481
|
+
console.error('Missing module context for updating property');
|
|
487
482
|
return of(null);
|
|
488
483
|
}
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
selectedProperty: updated,
|
|
504
|
-
});
|
|
505
|
-
}), catchError((error) => {
|
|
506
|
-
const message = error?.error?.message ??
|
|
507
|
-
error?.message ??
|
|
508
|
-
'Failed to update property';
|
|
509
|
-
setLoadingError(ctx, 'update', message);
|
|
510
|
-
return of(null);
|
|
511
|
-
}), finalize(() => endLoading(ctx, 'update')));
|
|
512
|
-
}
|
|
513
|
-
delete(ctx, action) {
|
|
514
|
-
startLoading(ctx, 'delete');
|
|
515
|
-
return this.http
|
|
516
|
-
.delete(`${this.baseUrl}/${encodeURIComponent(String(action.id))}`)
|
|
517
|
-
.pipe(tap(() => {
|
|
518
|
-
const { properties, selectedProperty } = ctx.getState();
|
|
519
|
-
const remaining = properties.filter((item) => item.id !== Number(action.id));
|
|
520
|
-
const nextSelected = selectedProperty && selectedProperty.id === Number(action.id)
|
|
521
|
-
? null
|
|
522
|
-
: selectedProperty;
|
|
523
|
-
ctx.patchState({
|
|
524
|
-
properties: remaining,
|
|
525
|
-
selectedProperty: nextSelected,
|
|
526
|
-
});
|
|
527
|
-
}), catchError((error) => {
|
|
528
|
-
const message = error?.error?.message ??
|
|
529
|
-
error?.message ??
|
|
530
|
-
'Failed to delete property';
|
|
531
|
-
setLoadingError(ctx, 'delete', message);
|
|
532
|
-
return of(null);
|
|
533
|
-
}), finalize(() => endLoading(ctx, 'delete')));
|
|
534
|
-
}
|
|
535
|
-
SetPropertyTypes(ctx, action) {
|
|
536
|
-
ctx.patchState({
|
|
537
|
-
propertyTypes: action.payload,
|
|
484
|
+
const req$ = this.http.put(`${this.baseUrl}${parentPath}/${moduleType}/${moduleId}/${action.id}`, action.payload);
|
|
485
|
+
return handleApiRequest({
|
|
486
|
+
ctx,
|
|
487
|
+
key: PropertiesActionKey.Update,
|
|
488
|
+
request$: req$,
|
|
489
|
+
onSuccess: (response, state) => {
|
|
490
|
+
const updated = response.data;
|
|
491
|
+
if (!updated)
|
|
492
|
+
return {};
|
|
493
|
+
return {
|
|
494
|
+
properties: this.adapter.upsertOne(state.properties, updated, 'id'),
|
|
495
|
+
selectedProperty: updated,
|
|
496
|
+
};
|
|
497
|
+
},
|
|
538
498
|
});
|
|
539
499
|
}
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
500
|
+
deleteProperty(ctx, action) {
|
|
501
|
+
const req$ = this.http.delete(`${this.baseUrl}/${encodeURIComponent(String(action.id))}`);
|
|
502
|
+
return handleApiRequest({
|
|
503
|
+
ctx,
|
|
504
|
+
key: PropertiesActionKey.Delete,
|
|
505
|
+
request$: req$,
|
|
506
|
+
onSuccess: (_, state) => {
|
|
507
|
+
const remaining = this.adapter.removeOne(state.properties, Number(action.id), 'id');
|
|
508
|
+
const nextSelected = state.selectedProperty &&
|
|
509
|
+
state.selectedProperty.id === Number(action.id)
|
|
510
|
+
? null
|
|
511
|
+
: state.selectedProperty;
|
|
512
|
+
return {
|
|
513
|
+
properties: remaining,
|
|
514
|
+
selectedProperty: nextSelected,
|
|
515
|
+
};
|
|
516
|
+
},
|
|
543
517
|
});
|
|
544
518
|
}
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
519
|
+
// ============================================================================
|
|
520
|
+
// Helper Methods
|
|
521
|
+
// ============================================================================
|
|
522
|
+
mapSchemaToOptions(schema) {
|
|
523
|
+
if (!schema?.properties) {
|
|
524
|
+
return [];
|
|
525
|
+
}
|
|
526
|
+
return Object.entries(schema.properties).map(([key, definition]) => {
|
|
527
|
+
const typeLabel = definition?.type ? ` | ${definition.type}` : '';
|
|
528
|
+
return {
|
|
529
|
+
key,
|
|
530
|
+
name: `${key}${typeLabel}`,
|
|
531
|
+
type: definition?.type,
|
|
532
|
+
};
|
|
548
533
|
});
|
|
549
534
|
}
|
|
550
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: PropertiesState, deps:
|
|
535
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: PropertiesState, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
|
|
551
536
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: PropertiesState });
|
|
552
537
|
};
|
|
553
538
|
__decorate([
|
|
@@ -571,9 +556,6 @@ __decorate([
|
|
|
571
556
|
__decorate([
|
|
572
557
|
Action(TestApiConfiguration)
|
|
573
558
|
], PropertiesState.prototype, "testApiConfiguration", null);
|
|
574
|
-
__decorate([
|
|
575
|
-
Action(ResetApiConfiguration)
|
|
576
|
-
], PropertiesState.prototype, "resetApiConfiguration", null);
|
|
577
559
|
__decorate([
|
|
578
560
|
Action(GetPropertiesForConfigType)
|
|
579
561
|
], PropertiesState.prototype, "getPropertiesForConfigType", null);
|
|
@@ -586,18 +568,12 @@ __decorate([
|
|
|
586
568
|
__decorate([
|
|
587
569
|
Action(ResetSelectedProperty)
|
|
588
570
|
], PropertiesState.prototype, "resetSelectedProperty", null);
|
|
571
|
+
__decorate([
|
|
572
|
+
Action(ResetApiConfiguration)
|
|
573
|
+
], PropertiesState.prototype, "resetApiConfiguration", null);
|
|
589
574
|
__decorate([
|
|
590
575
|
Action(SetPropertiesModuleInfo)
|
|
591
576
|
], PropertiesState.prototype, "setModuleInfo", null);
|
|
592
|
-
__decorate([
|
|
593
|
-
Action(CreateProperty)
|
|
594
|
-
], PropertiesState.prototype, "create", null);
|
|
595
|
-
__decorate([
|
|
596
|
-
Action(UpdateProperty)
|
|
597
|
-
], PropertiesState.prototype, "update", null);
|
|
598
|
-
__decorate([
|
|
599
|
-
Action(DeleteProperty)
|
|
600
|
-
], PropertiesState.prototype, "delete", null);
|
|
601
577
|
__decorate([
|
|
602
578
|
Action(SetPropertyTypes)
|
|
603
579
|
], PropertiesState.prototype, "SetPropertyTypes", null);
|
|
@@ -607,12 +583,27 @@ __decorate([
|
|
|
607
583
|
__decorate([
|
|
608
584
|
Action(SetDefaultViewType)
|
|
609
585
|
], PropertiesState.prototype, "setDefaultViewType", null);
|
|
586
|
+
__decorate([
|
|
587
|
+
Action(CreateProperty)
|
|
588
|
+
], PropertiesState.prototype, "createProperty", null);
|
|
589
|
+
__decorate([
|
|
590
|
+
Action(UpdateProperty)
|
|
591
|
+
], PropertiesState.prototype, "updateProperty", null);
|
|
592
|
+
__decorate([
|
|
593
|
+
Action(DeleteProperty)
|
|
594
|
+
], PropertiesState.prototype, "deleteProperty", null);
|
|
610
595
|
__decorate([
|
|
611
596
|
Selector()
|
|
612
597
|
], PropertiesState, "properties", null);
|
|
613
598
|
__decorate([
|
|
614
599
|
Selector()
|
|
615
600
|
], PropertiesState, "selectedProperty", null);
|
|
601
|
+
__decorate([
|
|
602
|
+
Selector()
|
|
603
|
+
], PropertiesState, "moduleId", null);
|
|
604
|
+
__decorate([
|
|
605
|
+
Selector()
|
|
606
|
+
], PropertiesState, "parentModuleId", null);
|
|
616
607
|
__decorate([
|
|
617
608
|
Selector()
|
|
618
609
|
], PropertiesState, "lookups", null);
|
|
@@ -645,10 +636,10 @@ __decorate([
|
|
|
645
636
|
], PropertiesState, "defaultViewType", null);
|
|
646
637
|
__decorate([
|
|
647
638
|
Selector()
|
|
648
|
-
], PropertiesState, "
|
|
639
|
+
], PropertiesState, "getLoadingActive", null);
|
|
649
640
|
__decorate([
|
|
650
641
|
Selector()
|
|
651
|
-
], PropertiesState, "
|
|
642
|
+
], PropertiesState, "getErrors", null);
|
|
652
643
|
__decorate([
|
|
653
644
|
Selector()
|
|
654
645
|
], PropertiesState, "propertyById", null);
|
|
@@ -660,13 +651,18 @@ PropertiesState = __decorate([
|
|
|
660
651
|
], PropertiesState);
|
|
661
652
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: PropertiesState, decorators: [{
|
|
662
653
|
type: Injectable
|
|
663
|
-
}], propDecorators: { getAll: [], getOne: [], getLookups: [], getGroups: [], getConfigAsType: [], getCountries: [], testApiConfiguration: [],
|
|
654
|
+
}], propDecorators: { getAll: [], getOne: [], getLookups: [], getGroups: [], getConfigAsType: [], getCountries: [], testApiConfiguration: [], getPropertiesForConfigType: [], resetConfigProperties: [], resetConfigScopes: [], resetSelectedProperty: [], resetApiConfiguration: [], setModuleInfo: [], SetPropertyTypes: [], setBreadcrumb: [], setDefaultViewType: [], createProperty: [], updateProperty: [], deleteProperty: [] } });
|
|
664
655
|
|
|
665
656
|
class PropertiesFacade {
|
|
666
657
|
store = inject(Store);
|
|
658
|
+
// ============================================================================
|
|
659
|
+
// Data Selectors - Memoized by NGXS (fine-grained reactivity)
|
|
660
|
+
// ============================================================================
|
|
667
661
|
list = select(PropertiesState.properties);
|
|
668
662
|
propertyTypes = select(PropertiesState.propertyTypes);
|
|
669
663
|
selected = select(PropertiesState.selectedProperty);
|
|
664
|
+
moduleId = select(PropertiesState.moduleId);
|
|
665
|
+
parentModuleId = select(PropertiesState.parentModuleId);
|
|
670
666
|
lookups = select(PropertiesState.lookups);
|
|
671
667
|
configProperties = select(PropertiesState.configTypeProperties);
|
|
672
668
|
groups = select(PropertiesState.groups);
|
|
@@ -676,12 +672,47 @@ class PropertiesFacade {
|
|
|
676
672
|
apiProperties = select(PropertiesState.apiProperties);
|
|
677
673
|
breadcrumbItems = select(PropertiesState.breadcrumbItems);
|
|
678
674
|
defaultViewType = select(PropertiesState.defaultViewType);
|
|
675
|
+
// ============================================================================
|
|
676
|
+
// Loading/Error Slices - Memoized by NGXS
|
|
677
|
+
// ============================================================================
|
|
678
|
+
loadingActive = select(PropertiesState.getLoadingActive);
|
|
679
|
+
errors = select(PropertiesState.getErrors);
|
|
680
|
+
// ============================================================================
|
|
681
|
+
// Loading Signals - Computed from slice (minimal reactivity)
|
|
682
|
+
// ============================================================================
|
|
683
|
+
isLoadingAll = computed(() => this.loadingActive().includes(PropertiesActionKey.GetAll), ...(ngDevMode ? [{ debugName: "isLoadingAll" }] : []));
|
|
684
|
+
isLoadingOne = computed(() => this.loadingActive().includes(PropertiesActionKey.GetOne), ...(ngDevMode ? [{ debugName: "isLoadingOne" }] : []));
|
|
685
|
+
isCreating = computed(() => this.loadingActive().includes(PropertiesActionKey.Create), ...(ngDevMode ? [{ debugName: "isCreating" }] : []));
|
|
686
|
+
isUpdating = computed(() => this.loadingActive().includes(PropertiesActionKey.Update), ...(ngDevMode ? [{ debugName: "isUpdating" }] : []));
|
|
687
|
+
isDeleting = computed(() => this.loadingActive().includes(PropertiesActionKey.Delete), ...(ngDevMode ? [{ debugName: "isDeleting" }] : []));
|
|
688
|
+
isLoadingLookups = computed(() => this.loadingActive().includes(PropertiesActionKey.GetLookups), ...(ngDevMode ? [{ debugName: "isLoadingLookups" }] : []));
|
|
689
|
+
isLoadingGroups = computed(() => this.loadingActive().includes(PropertiesActionKey.GetGroups), ...(ngDevMode ? [{ debugName: "isLoadingGroups" }] : []));
|
|
690
|
+
isLoadingConfigProperties = computed(() => this.loadingActive().includes(PropertiesActionKey.GetConfigProperties), ...(ngDevMode ? [{ debugName: "isLoadingConfigProperties" }] : []));
|
|
691
|
+
isLoadingConfigAsType = computed(() => this.loadingActive().includes(PropertiesActionKey.GetConfigAsType), ...(ngDevMode ? [{ debugName: "isLoadingConfigAsType" }] : []));
|
|
692
|
+
isLoadingCountries = computed(() => this.loadingActive().includes(PropertiesActionKey.GetCountries), ...(ngDevMode ? [{ debugName: "isLoadingCountries" }] : []));
|
|
693
|
+
isTestingApi = computed(() => this.loadingActive().includes(PropertiesActionKey.TestApiConfiguration), ...(ngDevMode ? [{ debugName: "isTestingApi" }] : []));
|
|
694
|
+
// ============================================================================
|
|
695
|
+
// Error Signals - Computed from slice (minimal reactivity)
|
|
696
|
+
// ============================================================================
|
|
697
|
+
allError = computed(() => this.errors()[PropertiesActionKey.GetAll] ?? null, ...(ngDevMode ? [{ debugName: "allError" }] : []));
|
|
698
|
+
oneError = computed(() => this.errors()[PropertiesActionKey.GetOne] ?? null, ...(ngDevMode ? [{ debugName: "oneError" }] : []));
|
|
699
|
+
createError = computed(() => this.errors()[PropertiesActionKey.Create] ?? null, ...(ngDevMode ? [{ debugName: "createError" }] : []));
|
|
700
|
+
updateError = computed(() => this.errors()[PropertiesActionKey.Update] ?? null, ...(ngDevMode ? [{ debugName: "updateError" }] : []));
|
|
701
|
+
deleteError = computed(() => this.errors()[PropertiesActionKey.Delete] ?? null, ...(ngDevMode ? [{ debugName: "deleteError" }] : []));
|
|
702
|
+
lookupsError = computed(() => this.errors()[PropertiesActionKey.GetLookups] ?? null, ...(ngDevMode ? [{ debugName: "lookupsError" }] : []));
|
|
703
|
+
groupsError = computed(() => this.errors()[PropertiesActionKey.GetGroups] ?? null, ...(ngDevMode ? [{ debugName: "groupsError" }] : []));
|
|
704
|
+
configPropertiesError = computed(() => this.errors()[PropertiesActionKey.GetConfigProperties] ?? null, ...(ngDevMode ? [{ debugName: "configPropertiesError" }] : []));
|
|
705
|
+
configAsTypeError = computed(() => this.errors()[PropertiesActionKey.GetConfigAsType] ?? null, ...(ngDevMode ? [{ debugName: "configAsTypeError" }] : []));
|
|
706
|
+
countriesError = computed(() => this.errors()[PropertiesActionKey.GetCountries] ?? null, ...(ngDevMode ? [{ debugName: "countriesError" }] : []));
|
|
707
|
+
apiTestError = computed(() => this.errors()[PropertiesActionKey.TestApiConfiguration] ?? null, ...(ngDevMode ? [{ debugName: "apiTestError" }] : []));
|
|
708
|
+
// ============================================================================
|
|
709
|
+
// Derived Data - Computed from data selectors
|
|
710
|
+
// ============================================================================
|
|
679
711
|
systemProperties = computed(() => this.list().filter((property) => Boolean(property.isSystem)), ...(ngDevMode ? [{ debugName: "systemProperties" }] : []));
|
|
680
712
|
customProperties = computed(() => this.list().filter((property) => !Boolean(property.isSystem)), ...(ngDevMode ? [{ debugName: "customProperties" }] : []));
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
}
|
|
713
|
+
// ============================================================================
|
|
714
|
+
// Action Dispatchers
|
|
715
|
+
// ============================================================================
|
|
685
716
|
loadAll(params) {
|
|
686
717
|
return this.store.dispatch(new GetProperties(params));
|
|
687
718
|
}
|
|
@@ -828,7 +859,7 @@ class PropertiesList {
|
|
|
828
859
|
], ...(ngDevMode ? [{ debugName: "propertyTypes" }] : []));
|
|
829
860
|
tableColumns = signal([
|
|
830
861
|
{
|
|
831
|
-
key: 'name',
|
|
862
|
+
key: 'name.display',
|
|
832
863
|
label: this.transloco.translate('properties.list.columnName'),
|
|
833
864
|
filterConfig: {
|
|
834
865
|
type: 'text',
|
|
@@ -896,7 +927,7 @@ class PropertiesList {
|
|
|
896
927
|
loading: (row) => this.deletingRowIds().includes(row.id),
|
|
897
928
|
},
|
|
898
929
|
], ...(ngDevMode ? [{ debugName: "rowActions" }] : []));
|
|
899
|
-
loading = this.facade.
|
|
930
|
+
loading = this.facade.isLoadingAll;
|
|
900
931
|
tableData = computed(() => {
|
|
901
932
|
const tab = this.activeTab();
|
|
902
933
|
const allProperties = this.facade.list();
|
|
@@ -924,7 +955,7 @@ class PropertiesList {
|
|
|
924
955
|
this.deletingRowIds.update((ids) => [...ids, row.id]);
|
|
925
956
|
this.facade
|
|
926
957
|
.delete(row.id)
|
|
927
|
-
.pipe(finalize
|
|
958
|
+
.pipe(finalize(() => {
|
|
928
959
|
this.deletingRowIds.update((ids) => ids.filter((id) => id !== row.id));
|
|
929
960
|
}))
|
|
930
961
|
.subscribe();
|
|
@@ -981,7 +1012,7 @@ class ApiConfiguration {
|
|
|
981
1012
|
schema = signal(null, ...(ngDevMode ? [{ debugName: "schema" }] : []));
|
|
982
1013
|
isWriting = false;
|
|
983
1014
|
touched = false;
|
|
984
|
-
isTesting = this.facade.
|
|
1015
|
+
isTesting = this.facade.isTestingApi;
|
|
985
1016
|
apiProperties = this.facade.apiProperties;
|
|
986
1017
|
hasDetectedSchema = computed(() => this.apiProperties().length > 0, ...(ngDevMode ? [{ debugName: "hasDetectedSchema" }] : []));
|
|
987
1018
|
form = new FormGroup({
|
|
@@ -1200,7 +1231,7 @@ class CheckListFormConfiguration {
|
|
|
1200
1231
|
key: 'properties',
|
|
1201
1232
|
cssClass: 'md:col-span-2',
|
|
1202
1233
|
options: this.configProperties(),
|
|
1203
|
-
optionLabel: 'name',
|
|
1234
|
+
optionLabel: 'name.display',
|
|
1204
1235
|
optionValue: 'key',
|
|
1205
1236
|
sourceHeader: this.transloco.translate('properties.form.availableProperties'),
|
|
1206
1237
|
targetHeader: this.transloco.translate('properties.form.selectedProperties'),
|
|
@@ -1276,7 +1307,7 @@ class DynamicListConfiguration {
|
|
|
1276
1307
|
key: 'properties',
|
|
1277
1308
|
cssClass: 'md:col-span-2',
|
|
1278
1309
|
options: this.configProperties(),
|
|
1279
|
-
optionLabel: 'name',
|
|
1310
|
+
optionLabel: 'name.display',
|
|
1280
1311
|
optionValue: 'key',
|
|
1281
1312
|
sourceHeader: this.transloco.translate('properties.form.availableProperties'),
|
|
1282
1313
|
targetHeader: this.transloco.translate('properties.form.selectedProperties'),
|
|
@@ -1352,7 +1383,7 @@ class EditableListViewConfiguration {
|
|
|
1352
1383
|
key: 'Properties',
|
|
1353
1384
|
cssClass: 'md:col-span-2',
|
|
1354
1385
|
options: this.configProperties(),
|
|
1355
|
-
optionLabel: 'name',
|
|
1386
|
+
optionLabel: 'name.display',
|
|
1356
1387
|
optionValue: 'key',
|
|
1357
1388
|
sourceHeader: this.transloco.translate('properties.form.availableProperties'),
|
|
1358
1389
|
targetHeader: this.transloco.translate('properties.form.selectedProperties'),
|
|
@@ -1448,7 +1479,7 @@ class InternalModuleConfiguration {
|
|
|
1448
1479
|
type: 'select',
|
|
1449
1480
|
key: 'property',
|
|
1450
1481
|
label: this.transloco.translate('properties.form.valueProperty'),
|
|
1451
|
-
optionLabel: 'name',
|
|
1482
|
+
optionLabel: 'name.display',
|
|
1452
1483
|
optionValue: 'key',
|
|
1453
1484
|
options: this.configProperties(),
|
|
1454
1485
|
},
|
|
@@ -1456,7 +1487,7 @@ class InternalModuleConfiguration {
|
|
|
1456
1487
|
cssClass: 'md:col-span-2 mt-2',
|
|
1457
1488
|
key: 'propertyDetails',
|
|
1458
1489
|
options: this.configProperties(),
|
|
1459
|
-
optionLabel: 'name',
|
|
1490
|
+
optionLabel: 'name.display',
|
|
1460
1491
|
optionValue: 'key',
|
|
1461
1492
|
sourceHeader: this.transloco.translate('properties.form.availableProperties'),
|
|
1462
1493
|
targetHeader: this.transloco.translate('properties.form.selectedProperties'),
|
|
@@ -1567,7 +1598,7 @@ class LookupConfiguration {
|
|
|
1567
1598
|
key: 'lookup',
|
|
1568
1599
|
type: 'select',
|
|
1569
1600
|
label: this.transloco.translate('properties.form.selectLookup'),
|
|
1570
|
-
optionLabel: 'name',
|
|
1601
|
+
optionLabel: 'name.display',
|
|
1571
1602
|
optionValue: 'id',
|
|
1572
1603
|
options: this.lookups(),
|
|
1573
1604
|
filter: true,
|
|
@@ -1648,7 +1679,7 @@ class UserConfiguration {
|
|
|
1648
1679
|
key: 'group',
|
|
1649
1680
|
type: 'select',
|
|
1650
1681
|
label: this.transloco.translate('properties.form.selectGroup'),
|
|
1651
|
-
optionLabel: 'name',
|
|
1682
|
+
optionLabel: 'name.display',
|
|
1652
1683
|
optionValue: 'id',
|
|
1653
1684
|
options: this.groups(),
|
|
1654
1685
|
filter: true,
|
|
@@ -1849,14 +1880,20 @@ class PropertyForm {
|
|
|
1849
1880
|
description: '',
|
|
1850
1881
|
}),
|
|
1851
1882
|
configuration: new FormControl(null),
|
|
1883
|
+
formula: new FormControl(null),
|
|
1852
1884
|
});
|
|
1853
1885
|
mainControl = this.propertyForm.get('main');
|
|
1854
1886
|
configurationControl = this.propertyForm.get('configuration');
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1887
|
+
formulaControl = this.propertyForm.get('formula');
|
|
1888
|
+
creating = this.facade.isCreating;
|
|
1889
|
+
updating = this.facade.isUpdating;
|
|
1890
|
+
loading = this.facade.isLoadingOne;
|
|
1858
1891
|
submitting = computed(() => this.creating() || this.updating(), ...(ngDevMode ? [{ debugName: "submitting" }] : []));
|
|
1859
1892
|
propertyType = toSignal(this.mainControl.valueChanges.pipe(map((v) => v?.viewType), distinctUntilChanged()));
|
|
1893
|
+
isCalculated = toSignal(this.mainControl.valueChanges.pipe(map((v) => Boolean(v?.isCalculated)), distinctUntilChanged()), {
|
|
1894
|
+
initialValue: Boolean(this.mainControl.value?.isCalculated),
|
|
1895
|
+
});
|
|
1896
|
+
formulaSchemaId = computed(() => this.resolveSchemaId(this.facade.parentModuleId() ?? this.facade.moduleId()), ...(ngDevMode ? [{ debugName: "formulaSchemaId" }] : []));
|
|
1860
1897
|
selectedPropertyTypeConfiguration = computed(() => {
|
|
1861
1898
|
const propertyTypesSetting = this.propertyTypes();
|
|
1862
1899
|
const selectedViewType = this.propertyType();
|
|
@@ -2135,12 +2172,20 @@ class PropertyForm {
|
|
|
2135
2172
|
// Direct component type
|
|
2136
2173
|
this.configurationComponentType.set(result);
|
|
2137
2174
|
}
|
|
2175
|
+
resolveSchemaId(value) {
|
|
2176
|
+
if (value === null || value === undefined) {
|
|
2177
|
+
return undefined;
|
|
2178
|
+
}
|
|
2179
|
+
const parsed = typeof value === 'string' ? Number(value) : value;
|
|
2180
|
+
return Number.isFinite(parsed) ? parsed : undefined;
|
|
2181
|
+
}
|
|
2138
2182
|
createOrEditProperty() {
|
|
2139
2183
|
const mainValue = this.mainControl.value;
|
|
2140
2184
|
if (!mainValue)
|
|
2141
2185
|
return;
|
|
2142
2186
|
const payload = {
|
|
2143
2187
|
...mainValue,
|
|
2188
|
+
formula: mainValue.isCalculated ? this.formulaControl.value : null,
|
|
2144
2189
|
Configuration: this.configurationControl.value ?? mainValue.Configuration ?? null,
|
|
2145
2190
|
};
|
|
2146
2191
|
const request$ = this.propertyId()
|
|
@@ -2155,6 +2200,9 @@ class PropertyForm {
|
|
|
2155
2200
|
emitEvent: false,
|
|
2156
2201
|
});
|
|
2157
2202
|
this.configurationControl.setValue(property?.configuration);
|
|
2203
|
+
this.formulaControl.setValue(property.formula ?? null, {
|
|
2204
|
+
emitEvent: false,
|
|
2205
|
+
});
|
|
2158
2206
|
}
|
|
2159
2207
|
goBack() {
|
|
2160
2208
|
const path = this.isEditing()
|
|
@@ -2171,15 +2219,17 @@ class PropertyForm {
|
|
|
2171
2219
|
this.destroyConfigurationComponent();
|
|
2172
2220
|
}
|
|
2173
2221
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: PropertyForm, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2174
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: PropertyForm, isStandalone: true, selector: "mt-property-form", inputs: { propertyId: { classPropertyName: "propertyId", publicName: "propertyId", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "configurationHost", first: true, predicate: ["configurationHost"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "<mt-page\r\n [title]=\"\r\n propertyId()\r\n ? ('properties.form.editProperty' | transloco)\r\n : ('properties.form.createNewProperty' | transloco)\r\n \"\r\n avatarIcon=\"custom.products-and-services\"\r\n [avatarStyle]=\"{\r\n '--p-avatar-background': 'var(--p-sky-50)',\r\n '--p-avatar-color': 'var(--p-sky-700)',\r\n }\"\r\n (backButtonClick)=\"goBack()\"\r\n backButton\r\n class=\"h-full\"\r\n>\r\n <ng-template #headerEnd>\r\n <mt-button\r\n class=\"mx-2\"\r\n [label]=\"submitLabel()\"\r\n [icon]=\"isEditing() ? 'custom.pencil' : 'general.plus'\"\r\n [loading]=\"submitting()\"\r\n [disabled]=\"submitDisabled() || this.propertyForm.invalid\"\r\n (click)=\"createOrEditProperty()\"\r\n />\r\n </ng-template>\r\n <div\r\n [formGroup]=\"propertyForm\"\r\n class=\"h-full py-4 h-full overflow-y-auto flex justify-center\"\r\n >\r\n <div class=\"w-
|
|
2222
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: PropertyForm, isStandalone: true, selector: "mt-property-form", inputs: { propertyId: { classPropertyName: "propertyId", publicName: "propertyId", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "configurationHost", first: true, predicate: ["configurationHost"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "<mt-page\r\n [title]=\"\r\n propertyId()\r\n ? ('properties.form.editProperty' | transloco)\r\n : ('properties.form.createNewProperty' | transloco)\r\n \"\r\n avatarIcon=\"custom.products-and-services\"\r\n [avatarStyle]=\"{\r\n '--p-avatar-background': 'var(--p-sky-50)',\r\n '--p-avatar-color': 'var(--p-sky-700)',\r\n }\"\r\n (backButtonClick)=\"goBack()\"\r\n backButton\r\n class=\"h-full\"\r\n>\r\n <ng-template #headerEnd>\r\n <mt-button\r\n class=\"mx-2\"\r\n [label]=\"submitLabel()\"\r\n [icon]=\"isEditing() ? 'custom.pencil' : 'general.plus'\"\r\n [loading]=\"submitting()\"\r\n [disabled]=\"submitDisabled() || this.propertyForm.invalid\"\r\n (click)=\"createOrEditProperty()\"\r\n />\r\n </ng-template>\r\n <div\r\n [formGroup]=\"propertyForm\"\r\n class=\"h-full py-4 h-full overflow-y-auto flex justify-center\"\r\n >\r\n <div class=\"w-2/3 flex flex-col gap-6\">\r\n @if (loading()) {\r\n <!-- Skeleton Loading State -->\r\n <div class=\"rounded-xl bg-white shadow-sm p-6 space-y-4\">\r\n <div class=\"flex justify-between items-center gap-6\">\r\n <p-skeleton width=\"50%\" height=\"3rem\"></p-skeleton>\r\n <p-skeleton width=\"8rem\" height=\"2.5rem\"></p-skeleton>\r\n </div>\r\n </div>\r\n\r\n <div class=\"rounded-xl bg-white shadow-sm p-6 space-y-4\">\r\n <p-skeleton\r\n width=\"12rem\"\r\n height=\"1.5rem\"\r\n styleClass=\"mb-4\"\r\n ></p-skeleton>\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n <p-skeleton height=\"3rem\"></p-skeleton>\r\n <p-skeleton height=\"3rem\"></p-skeleton>\r\n <p-skeleton height=\"6rem\" styleClass=\"md:col-span-2\"></p-skeleton>\r\n <p-skeleton height=\"3rem\" styleClass=\"md:col-span-2\"></p-skeleton>\r\n </div>\r\n </div>\r\n\r\n <div class=\"rounded-xl bg-white shadow-sm p-6 space-y-4\">\r\n <p-skeleton\r\n width=\"10rem\"\r\n height=\"1.5rem\"\r\n styleClass=\"mb-4\"\r\n ></p-skeleton>\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n <p-skeleton height=\"3rem\"></p-skeleton>\r\n <p-skeleton height=\"3rem\"></p-skeleton>\r\n <p-skeleton height=\"8rem\" styleClass=\"md:col-span-2\"></p-skeleton>\r\n </div>\r\n </div>\r\n } @else {\r\n <mt-dynamic-form\r\n [formConfig]=\"dynamicFormConfigMain()\"\r\n [formControlName]=\"'main'\"\r\n />\r\n @if (configurationFormConfig()) {\r\n <mt-dynamic-form\r\n formControlName=\"configuration\"\r\n [formConfig]=\"configurationFormConfig()!\"\r\n />\r\n } @else {\r\n <ng-container #configurationHost></ng-container>\r\n @if (!configurationComponentExists()) {\r\n @switch (propertyType()) {\r\n @case (\"User\") {\r\n <mt-user-configuration />\r\n }\r\n @case (\"Percentage\") {\r\n <mt-percentage-configuration />\r\n }\r\n @case (\"Lookup\") {\r\n <mt-lookup-configuration />\r\n }\r\n @case (\"LookupMultiSelect\") {\r\n <mt-lookup-configuration />\r\n }\r\n @case (\"InternalModule\") {\r\n <mt-internal-module-configuration />\r\n }\r\n @case (\"DynamicList\") {\r\n <mt-dynamic-list-configuration />\r\n }\r\n @case (\"API\") {\r\n <mt-api-configuration formControlName=\"configuration\" />\r\n }\r\n <!-- @case('ViewList') { REMOVED FOR NOW\r\n <mt-view-list-configuration />\r\n } -->\r\n @case (\"Attachment\") {\r\n <mt-attachment-configuration />\r\n }\r\n <!-- @case('ReferenceProperty') { REMOVED FOR NOW\r\n } -->\r\n @case (\"EditableListView\") {\r\n <mt-editable-list-view-configuration />\r\n }\r\n @case (\"LookupLog\") {\r\n <mt-check-list-form-configuration />\r\n }\r\n <!-- @case('LookupMatrix') { REMOVED FOR NOW\r\n <mt-lookup-configuration />\r\n } -->\r\n @case (\"Location\") {\r\n <mt-location-configuration />\r\n }\r\n }\r\n }\r\n }\r\n @if (isCalculated()) {\r\n <mt-card title=\"Formula\">\r\n <mt-formula-builder\r\n formControlName=\"formula\"\r\n [levelSchemaId]=\"formulaSchemaId()\"\r\n />\r\n </mt-card>\r\n }\r\n }\r\n </div>\r\n </div>\r\n</mt-page>\r\n", styles: [""], dependencies: [{ kind: "component", type: Page, selector: "mt-page", inputs: ["backButton", "backButtonIcon", "avatarIcon", "avatarStyle", "avatarShape", "title", "tabs", "activeTab", "contentClass", "contentId"], outputs: ["backButtonClick", "tabChange"] }, { 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"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: FormulaBuilder, selector: "mt-formula-builder", inputs: ["propertiesByPath", "levelSchemaId", "templateId", "placeholder", "hideToolbar", "hideStatusBar"], outputs: ["validationChange", "tokensChange"] }, { kind: "component", type: ApiConfiguration, selector: "mt-api-configuration" }, { kind: "component", type: CheckListFormConfiguration, selector: "mt-check-list-form-configuration" }, { kind: "component", type: DynamicListConfiguration, selector: "mt-dynamic-list-configuration" }, { kind: "component", type: EditableListViewConfiguration, selector: "mt-editable-list-view-configuration" }, { kind: "component", type: InternalModuleConfiguration, selector: "mt-internal-module-configuration" }, { kind: "component", type: LocationConfiguration, selector: "mt-location-configuration" }, { kind: "component", type: LookupConfiguration, selector: "mt-lookup-configuration" }, { kind: "component", type: PercentageConfiguration, selector: "mt-percentage-configuration" }, { kind: "component", type: UserConfiguration, selector: "mt-user-configuration" }, { kind: "component", type: AttachmentConfiguration, selector: "mt-attachment-configuration" }, { kind: "ngmodule", type: SkeletonModule }, { kind: "component", type: i2.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "ngmodule", type: TranslocoModule }, { kind: "pipe", type: i1.TranslocoPipe, name: "transloco" }] });
|
|
2175
2223
|
}
|
|
2176
2224
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: PropertyForm, decorators: [{
|
|
2177
2225
|
type: Component,
|
|
2178
2226
|
args: [{ selector: 'mt-property-form', imports: [
|
|
2179
2227
|
Page,
|
|
2180
2228
|
Button,
|
|
2229
|
+
Card,
|
|
2181
2230
|
DynamicForm,
|
|
2182
2231
|
ReactiveFormsModule,
|
|
2232
|
+
FormulaBuilder,
|
|
2183
2233
|
ApiConfiguration,
|
|
2184
2234
|
CheckListFormConfiguration,
|
|
2185
2235
|
DynamicListConfiguration,
|
|
@@ -2192,7 +2242,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
2192
2242
|
AttachmentConfiguration,
|
|
2193
2243
|
SkeletonModule,
|
|
2194
2244
|
TranslocoModule,
|
|
2195
|
-
], template: "<mt-page\r\n [title]=\"\r\n propertyId()\r\n ? ('properties.form.editProperty' | transloco)\r\n : ('properties.form.createNewProperty' | transloco)\r\n \"\r\n avatarIcon=\"custom.products-and-services\"\r\n [avatarStyle]=\"{\r\n '--p-avatar-background': 'var(--p-sky-50)',\r\n '--p-avatar-color': 'var(--p-sky-700)',\r\n }\"\r\n (backButtonClick)=\"goBack()\"\r\n backButton\r\n class=\"h-full\"\r\n>\r\n <ng-template #headerEnd>\r\n <mt-button\r\n class=\"mx-2\"\r\n [label]=\"submitLabel()\"\r\n [icon]=\"isEditing() ? 'custom.pencil' : 'general.plus'\"\r\n [loading]=\"submitting()\"\r\n [disabled]=\"submitDisabled() || this.propertyForm.invalid\"\r\n (click)=\"createOrEditProperty()\"\r\n />\r\n </ng-template>\r\n <div\r\n [formGroup]=\"propertyForm\"\r\n class=\"h-full py-4 h-full overflow-y-auto flex justify-center\"\r\n >\r\n <div class=\"w-
|
|
2245
|
+
], template: "<mt-page\r\n [title]=\"\r\n propertyId()\r\n ? ('properties.form.editProperty' | transloco)\r\n : ('properties.form.createNewProperty' | transloco)\r\n \"\r\n avatarIcon=\"custom.products-and-services\"\r\n [avatarStyle]=\"{\r\n '--p-avatar-background': 'var(--p-sky-50)',\r\n '--p-avatar-color': 'var(--p-sky-700)',\r\n }\"\r\n (backButtonClick)=\"goBack()\"\r\n backButton\r\n class=\"h-full\"\r\n>\r\n <ng-template #headerEnd>\r\n <mt-button\r\n class=\"mx-2\"\r\n [label]=\"submitLabel()\"\r\n [icon]=\"isEditing() ? 'custom.pencil' : 'general.plus'\"\r\n [loading]=\"submitting()\"\r\n [disabled]=\"submitDisabled() || this.propertyForm.invalid\"\r\n (click)=\"createOrEditProperty()\"\r\n />\r\n </ng-template>\r\n <div\r\n [formGroup]=\"propertyForm\"\r\n class=\"h-full py-4 h-full overflow-y-auto flex justify-center\"\r\n >\r\n <div class=\"w-2/3 flex flex-col gap-6\">\r\n @if (loading()) {\r\n <!-- Skeleton Loading State -->\r\n <div class=\"rounded-xl bg-white shadow-sm p-6 space-y-4\">\r\n <div class=\"flex justify-between items-center gap-6\">\r\n <p-skeleton width=\"50%\" height=\"3rem\"></p-skeleton>\r\n <p-skeleton width=\"8rem\" height=\"2.5rem\"></p-skeleton>\r\n </div>\r\n </div>\r\n\r\n <div class=\"rounded-xl bg-white shadow-sm p-6 space-y-4\">\r\n <p-skeleton\r\n width=\"12rem\"\r\n height=\"1.5rem\"\r\n styleClass=\"mb-4\"\r\n ></p-skeleton>\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n <p-skeleton height=\"3rem\"></p-skeleton>\r\n <p-skeleton height=\"3rem\"></p-skeleton>\r\n <p-skeleton height=\"6rem\" styleClass=\"md:col-span-2\"></p-skeleton>\r\n <p-skeleton height=\"3rem\" styleClass=\"md:col-span-2\"></p-skeleton>\r\n </div>\r\n </div>\r\n\r\n <div class=\"rounded-xl bg-white shadow-sm p-6 space-y-4\">\r\n <p-skeleton\r\n width=\"10rem\"\r\n height=\"1.5rem\"\r\n styleClass=\"mb-4\"\r\n ></p-skeleton>\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n <p-skeleton height=\"3rem\"></p-skeleton>\r\n <p-skeleton height=\"3rem\"></p-skeleton>\r\n <p-skeleton height=\"8rem\" styleClass=\"md:col-span-2\"></p-skeleton>\r\n </div>\r\n </div>\r\n } @else {\r\n <mt-dynamic-form\r\n [formConfig]=\"dynamicFormConfigMain()\"\r\n [formControlName]=\"'main'\"\r\n />\r\n @if (configurationFormConfig()) {\r\n <mt-dynamic-form\r\n formControlName=\"configuration\"\r\n [formConfig]=\"configurationFormConfig()!\"\r\n />\r\n } @else {\r\n <ng-container #configurationHost></ng-container>\r\n @if (!configurationComponentExists()) {\r\n @switch (propertyType()) {\r\n @case (\"User\") {\r\n <mt-user-configuration />\r\n }\r\n @case (\"Percentage\") {\r\n <mt-percentage-configuration />\r\n }\r\n @case (\"Lookup\") {\r\n <mt-lookup-configuration />\r\n }\r\n @case (\"LookupMultiSelect\") {\r\n <mt-lookup-configuration />\r\n }\r\n @case (\"InternalModule\") {\r\n <mt-internal-module-configuration />\r\n }\r\n @case (\"DynamicList\") {\r\n <mt-dynamic-list-configuration />\r\n }\r\n @case (\"API\") {\r\n <mt-api-configuration formControlName=\"configuration\" />\r\n }\r\n <!-- @case('ViewList') { REMOVED FOR NOW\r\n <mt-view-list-configuration />\r\n } -->\r\n @case (\"Attachment\") {\r\n <mt-attachment-configuration />\r\n }\r\n <!-- @case('ReferenceProperty') { REMOVED FOR NOW\r\n } -->\r\n @case (\"EditableListView\") {\r\n <mt-editable-list-view-configuration />\r\n }\r\n @case (\"LookupLog\") {\r\n <mt-check-list-form-configuration />\r\n }\r\n <!-- @case('LookupMatrix') { REMOVED FOR NOW\r\n <mt-lookup-configuration />\r\n } -->\r\n @case (\"Location\") {\r\n <mt-location-configuration />\r\n }\r\n }\r\n }\r\n }\r\n @if (isCalculated()) {\r\n <mt-card title=\"Formula\">\r\n <mt-formula-builder\r\n formControlName=\"formula\"\r\n [levelSchemaId]=\"formulaSchemaId()\"\r\n />\r\n </mt-card>\r\n }\r\n }\r\n </div>\r\n </div>\r\n</mt-page>\r\n" }]
|
|
2196
2246
|
}], ctorParameters: () => [], propDecorators: { propertyId: [{ type: i0.Input, args: [{ isSignal: true, alias: "propertyId", required: false }] }], configurationHost: [{
|
|
2197
2247
|
type: ViewChild,
|
|
2198
2248
|
args: ['configurationHost', { read: ViewContainerRef }]
|
|
@@ -2206,5 +2256,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
2206
2256
|
* Generated bundle index. Do not edit.
|
|
2207
2257
|
*/
|
|
2208
2258
|
|
|
2209
|
-
export { CreateProperty, DeleteProperty, GetConfigAsType, GetCountries, GetGroups, GetLookups, GetProperties, GetPropertiesForConfigType, GetProperty, PropertiesFacade, PropertiesList, PropertiesState, PropertyForm, REQUEST_CONTEXT, ResetApiConfiguration, ResetConfigProperties, ResetConfigScopes, ResetSelectedProperty, SetBreadcrumb, SetDefaultViewType, SetPropertiesModuleInfo, SetPropertyTypes, TestApiConfiguration, UpdateProperty };
|
|
2259
|
+
export { CreateProperty, DeleteProperty, GetConfigAsType, GetCountries, GetGroups, GetLookups, GetProperties, GetPropertiesForConfigType, GetProperty, PropertiesActionKey, PropertiesFacade, PropertiesList, PropertiesState, PropertyForm, REQUEST_CONTEXT, ResetApiConfiguration, ResetConfigProperties, ResetConfigScopes, ResetSelectedProperty, SetBreadcrumb, SetDefaultViewType, SetPropertiesModuleInfo, SetPropertyTypes, TestApiConfiguration, UpdateProperty };
|
|
2210
2260
|
//# sourceMappingURL=masterteam-properties.mjs.map
|