@masterteam/properties 0.0.29 → 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,7 +18,6 @@ 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';
|
|
@@ -27,30 +27,20 @@ import { SelectField } from '@masterteam/components/select-field';
|
|
|
27
27
|
import { TextField } from '@masterteam/components/text-field';
|
|
28
28
|
import { ToggleField } from '@masterteam/components/toggle-field';
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
ctx.patchState({
|
|
45
|
-
loadingActive: loadingActive.filter((name) => name !== loadingName),
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
function setLoadingError(ctx, loadingName, message) {
|
|
49
|
-
const { errors } = ctx.getState();
|
|
50
|
-
ctx.patchState({
|
|
51
|
-
errors: { ...errors, [loadingName]: message },
|
|
52
|
-
});
|
|
53
|
-
}
|
|
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 = {}));
|
|
54
44
|
|
|
55
45
|
class GetProperties {
|
|
56
46
|
params;
|
|
@@ -198,7 +188,7 @@ const DEFAULT_STATE = {
|
|
|
198
188
|
breadcrumbItems: [],
|
|
199
189
|
defaultViewType: null,
|
|
200
190
|
};
|
|
201
|
-
let PropertiesState = class PropertiesState {
|
|
191
|
+
let PropertiesState = class PropertiesState extends CrudStateBase {
|
|
202
192
|
http = inject(HttpClient);
|
|
203
193
|
baseUrl = 'Properties';
|
|
204
194
|
lookupsUrl = 'Lookups';
|
|
@@ -207,6 +197,9 @@ let PropertiesState = class PropertiesState {
|
|
|
207
197
|
countriesUrl = '/assets/countries/countries.json';
|
|
208
198
|
apiTestUrl = 'app/testAPI';
|
|
209
199
|
apiDetectUrl = 'app/detect';
|
|
200
|
+
// ============================================================================
|
|
201
|
+
// Data Selectors - Individual for fine-grained reactivity
|
|
202
|
+
// ============================================================================
|
|
210
203
|
static properties(state) {
|
|
211
204
|
return state.properties;
|
|
212
205
|
}
|
|
@@ -241,7 +234,7 @@ let PropertiesState = class PropertiesState {
|
|
|
241
234
|
return state.apiProperties;
|
|
242
235
|
}
|
|
243
236
|
static propertyTypes(state) {
|
|
244
|
-
return state.propertyTypes ??
|
|
237
|
+
return state.propertyTypes ?? {};
|
|
245
238
|
}
|
|
246
239
|
static breadcrumbItems(state) {
|
|
247
240
|
return state.breadcrumbItems;
|
|
@@ -249,17 +242,25 @@ let PropertiesState = class PropertiesState {
|
|
|
249
242
|
static defaultViewType(state) {
|
|
250
243
|
return state.defaultViewType;
|
|
251
244
|
}
|
|
252
|
-
|
|
253
|
-
|
|
245
|
+
// ============================================================================
|
|
246
|
+
// Loading/Error Slice Selectors - REQUIRED for optimal performance
|
|
247
|
+
// ============================================================================
|
|
248
|
+
static getLoadingActive(state) {
|
|
249
|
+
return state.loadingActive;
|
|
254
250
|
}
|
|
255
|
-
static
|
|
256
|
-
return
|
|
251
|
+
static getErrors(state) {
|
|
252
|
+
return state.errors;
|
|
257
253
|
}
|
|
254
|
+
// ============================================================================
|
|
255
|
+
// Derived Selectors
|
|
256
|
+
// ============================================================================
|
|
258
257
|
static propertyById(state) {
|
|
259
258
|
return (id) => state.properties.find((property) => property.id === Number(id)) ?? null;
|
|
260
259
|
}
|
|
260
|
+
// ============================================================================
|
|
261
|
+
// CRUD Actions
|
|
262
|
+
// ============================================================================
|
|
261
263
|
getAll(ctx, action) {
|
|
262
|
-
startLoading(ctx, 'getAll');
|
|
263
264
|
const state = ctx.getState();
|
|
264
265
|
const moduleType = state.moduleType ?? undefined;
|
|
265
266
|
const moduleId = state.moduleId ?? undefined;
|
|
@@ -268,67 +269,57 @@ let PropertiesState = class PropertiesState {
|
|
|
268
269
|
ctx.patchState({
|
|
269
270
|
lastQueryParams: params ?? null,
|
|
270
271
|
});
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
error?.message ??
|
|
281
|
-
'Failed to load properties';
|
|
282
|
-
setLoadingError(ctx, 'getAll', message);
|
|
283
|
-
return of(null);
|
|
284
|
-
}), 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
|
+
});
|
|
285
281
|
}
|
|
286
282
|
getOne(ctx, action) {
|
|
287
|
-
startLoading(ctx, 'getOne');
|
|
288
283
|
const params = { mode: action.mode ?? 'edit' };
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
'Failed to load property';
|
|
299
|
-
setLoadingError(ctx, 'getOne', message);
|
|
300
|
-
return of(null);
|
|
301
|
-
}), 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
|
+
});
|
|
302
293
|
}
|
|
303
294
|
getLookups(ctx, _action) {
|
|
304
295
|
const state = ctx.getState();
|
|
305
296
|
if (state.lookups.length) {
|
|
306
297
|
return of(state.lookups);
|
|
307
298
|
}
|
|
308
|
-
|
|
309
|
-
return
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
})
|
|
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
|
+
});
|
|
317
308
|
}
|
|
318
309
|
getGroups(ctx, _action) {
|
|
319
310
|
const state = ctx.getState();
|
|
320
311
|
if (state.groups.length) {
|
|
321
312
|
return of(state.groups);
|
|
322
313
|
}
|
|
323
|
-
|
|
324
|
-
return
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
})
|
|
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
|
+
});
|
|
332
323
|
}
|
|
333
324
|
getConfigAsType(ctx, action) {
|
|
334
325
|
const state = ctx.getState();
|
|
@@ -336,41 +327,41 @@ let PropertiesState = class PropertiesState {
|
|
|
336
327
|
if (state.configScopes.length) {
|
|
337
328
|
return of(state.configScopes);
|
|
338
329
|
}
|
|
339
|
-
startLoading(ctx, 'getConfigAsType');
|
|
340
330
|
const url = `${this.baseUrl}/${action.viewType}/GetViewTypeProperties`;
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
ctx
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
}), 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
|
+
});
|
|
351
340
|
}
|
|
352
341
|
getCountries(ctx, _action) {
|
|
353
342
|
const state = ctx.getState();
|
|
354
343
|
if (state.countries.length) {
|
|
355
344
|
return of(state.countries);
|
|
356
345
|
}
|
|
357
|
-
|
|
358
|
-
return
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
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
|
+
});
|
|
366
356
|
}
|
|
367
357
|
testApiConfiguration(ctx, action) {
|
|
368
|
-
startLoading(ctx, 'testApiConfiguration');
|
|
369
358
|
ctx.patchState({
|
|
370
359
|
apiSchema: null,
|
|
371
360
|
apiProperties: [],
|
|
372
361
|
});
|
|
373
|
-
|
|
362
|
+
const req$ = this.http
|
|
363
|
+
.post(this.apiTestUrl, action.payload)
|
|
364
|
+
.pipe(switchMap((testResponse) => {
|
|
374
365
|
const rawData = testResponse?.data;
|
|
375
366
|
if (!rawData) {
|
|
376
367
|
return of(null);
|
|
@@ -387,49 +378,29 @@ let PropertiesState = class PropertiesState {
|
|
|
387
378
|
apiProperties,
|
|
388
379
|
});
|
|
389
380
|
}));
|
|
390
|
-
})
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
resetApiConfiguration(ctx) {
|
|
397
|
-
ctx.patchState({
|
|
398
|
-
apiSchema: null,
|
|
399
|
-
apiProperties: [],
|
|
400
|
-
});
|
|
401
|
-
}
|
|
402
|
-
mapSchemaToOptions(schema) {
|
|
403
|
-
if (!schema?.properties) {
|
|
404
|
-
return [];
|
|
405
|
-
}
|
|
406
|
-
return Object.entries(schema.properties).map(([key, definition]) => {
|
|
407
|
-
const typeLabel = definition?.type ? ` | ${definition.type}` : '';
|
|
408
|
-
return {
|
|
409
|
-
key,
|
|
410
|
-
name: `${key}${typeLabel}`,
|
|
411
|
-
type: definition?.type,
|
|
412
|
-
};
|
|
381
|
+
}));
|
|
382
|
+
return handleApiRequest({
|
|
383
|
+
ctx,
|
|
384
|
+
key: PropertiesActionKey.TestApiConfiguration,
|
|
385
|
+
request$: req$,
|
|
386
|
+
onSuccess: () => ({}),
|
|
413
387
|
});
|
|
414
388
|
}
|
|
415
389
|
getPropertiesForConfigType(ctx, action) {
|
|
416
|
-
startLoading(ctx, 'getConfigProperties');
|
|
417
390
|
const { moduleType, moduleId } = action;
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
error?.message ??
|
|
428
|
-
'Failed to load properties';
|
|
429
|
-
setLoadingError(ctx, 'getConfigProperties', message);
|
|
430
|
-
return of([]);
|
|
431
|
-
}), 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
|
+
});
|
|
432
400
|
}
|
|
401
|
+
// ============================================================================
|
|
402
|
+
// Simple State Updates (No HTTP)
|
|
403
|
+
// ============================================================================
|
|
433
404
|
resetConfigProperties(ctx) {
|
|
434
405
|
ctx.patchState({ configTypeProperties: [] });
|
|
435
406
|
}
|
|
@@ -439,6 +410,12 @@ let PropertiesState = class PropertiesState {
|
|
|
439
410
|
resetSelectedProperty(ctx) {
|
|
440
411
|
ctx.patchState({ selectedProperty: null });
|
|
441
412
|
}
|
|
413
|
+
resetApiConfiguration(ctx) {
|
|
414
|
+
ctx.patchState({
|
|
415
|
+
apiSchema: null,
|
|
416
|
+
apiProperties: [],
|
|
417
|
+
});
|
|
418
|
+
}
|
|
442
419
|
setModuleInfo(ctx, action) {
|
|
443
420
|
let parentPath = '';
|
|
444
421
|
if (action.parentModuleType && action.parentModuleId) {
|
|
@@ -455,106 +432,107 @@ let PropertiesState = class PropertiesState {
|
|
|
455
432
|
parentPath: parentPath ?? '',
|
|
456
433
|
});
|
|
457
434
|
}
|
|
458
|
-
|
|
459
|
-
|
|
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) {
|
|
460
451
|
const state = ctx.getState();
|
|
461
452
|
const moduleType = state.moduleType ?? undefined;
|
|
462
453
|
const moduleId = state.moduleId ?? undefined;
|
|
463
454
|
const parentPath = state.parentPath ?? '';
|
|
464
455
|
if (!moduleType || moduleId === undefined || moduleId === null) {
|
|
465
|
-
|
|
466
|
-
setLoadingError(ctx, 'create', message);
|
|
467
|
-
endLoading(ctx, 'create');
|
|
456
|
+
console.error('Missing module context for creating property');
|
|
468
457
|
return of(null);
|
|
469
458
|
}
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
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
|
+
});
|
|
483
474
|
}
|
|
484
|
-
|
|
485
|
-
startLoading(ctx, 'update');
|
|
475
|
+
updateProperty(ctx, action) {
|
|
486
476
|
const state = ctx.getState();
|
|
487
477
|
const moduleType = state.moduleType ?? undefined;
|
|
488
478
|
const moduleId = state.moduleId ?? undefined;
|
|
489
479
|
const parentPath = state.parentPath ?? '';
|
|
490
480
|
if (!moduleType || moduleId === undefined || moduleId === null) {
|
|
491
|
-
|
|
492
|
-
setLoadingError(ctx, 'update', message);
|
|
493
|
-
endLoading(ctx, 'update');
|
|
481
|
+
console.error('Missing module context for updating property');
|
|
494
482
|
return of(null);
|
|
495
483
|
}
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
selectedProperty: updated,
|
|
511
|
-
});
|
|
512
|
-
}), catchError((error) => {
|
|
513
|
-
const message = error?.error?.message ??
|
|
514
|
-
error?.message ??
|
|
515
|
-
'Failed to update property';
|
|
516
|
-
setLoadingError(ctx, 'update', message);
|
|
517
|
-
return of(null);
|
|
518
|
-
}), finalize(() => endLoading(ctx, 'update')));
|
|
519
|
-
}
|
|
520
|
-
delete(ctx, action) {
|
|
521
|
-
startLoading(ctx, 'delete');
|
|
522
|
-
return this.http
|
|
523
|
-
.delete(`${this.baseUrl}/${encodeURIComponent(String(action.id))}`)
|
|
524
|
-
.pipe(tap(() => {
|
|
525
|
-
const { properties, selectedProperty } = ctx.getState();
|
|
526
|
-
const remaining = properties.filter((item) => item.id !== Number(action.id));
|
|
527
|
-
const nextSelected = selectedProperty && selectedProperty.id === Number(action.id)
|
|
528
|
-
? null
|
|
529
|
-
: selectedProperty;
|
|
530
|
-
ctx.patchState({
|
|
531
|
-
properties: remaining,
|
|
532
|
-
selectedProperty: nextSelected,
|
|
533
|
-
});
|
|
534
|
-
}), catchError((error) => {
|
|
535
|
-
const message = error?.error?.message ??
|
|
536
|
-
error?.message ??
|
|
537
|
-
'Failed to delete property';
|
|
538
|
-
setLoadingError(ctx, 'delete', message);
|
|
539
|
-
return of(null);
|
|
540
|
-
}), finalize(() => endLoading(ctx, 'delete')));
|
|
541
|
-
}
|
|
542
|
-
SetPropertyTypes(ctx, action) {
|
|
543
|
-
ctx.patchState({
|
|
544
|
-
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
|
+
},
|
|
545
498
|
});
|
|
546
499
|
}
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
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
|
+
},
|
|
550
517
|
});
|
|
551
518
|
}
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
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
|
+
};
|
|
555
533
|
});
|
|
556
534
|
}
|
|
557
|
-
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 });
|
|
558
536
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: PropertiesState });
|
|
559
537
|
};
|
|
560
538
|
__decorate([
|
|
@@ -578,9 +556,6 @@ __decorate([
|
|
|
578
556
|
__decorate([
|
|
579
557
|
Action(TestApiConfiguration)
|
|
580
558
|
], PropertiesState.prototype, "testApiConfiguration", null);
|
|
581
|
-
__decorate([
|
|
582
|
-
Action(ResetApiConfiguration)
|
|
583
|
-
], PropertiesState.prototype, "resetApiConfiguration", null);
|
|
584
559
|
__decorate([
|
|
585
560
|
Action(GetPropertiesForConfigType)
|
|
586
561
|
], PropertiesState.prototype, "getPropertiesForConfigType", null);
|
|
@@ -593,18 +568,12 @@ __decorate([
|
|
|
593
568
|
__decorate([
|
|
594
569
|
Action(ResetSelectedProperty)
|
|
595
570
|
], PropertiesState.prototype, "resetSelectedProperty", null);
|
|
571
|
+
__decorate([
|
|
572
|
+
Action(ResetApiConfiguration)
|
|
573
|
+
], PropertiesState.prototype, "resetApiConfiguration", null);
|
|
596
574
|
__decorate([
|
|
597
575
|
Action(SetPropertiesModuleInfo)
|
|
598
576
|
], PropertiesState.prototype, "setModuleInfo", null);
|
|
599
|
-
__decorate([
|
|
600
|
-
Action(CreateProperty)
|
|
601
|
-
], PropertiesState.prototype, "create", null);
|
|
602
|
-
__decorate([
|
|
603
|
-
Action(UpdateProperty)
|
|
604
|
-
], PropertiesState.prototype, "update", null);
|
|
605
|
-
__decorate([
|
|
606
|
-
Action(DeleteProperty)
|
|
607
|
-
], PropertiesState.prototype, "delete", null);
|
|
608
577
|
__decorate([
|
|
609
578
|
Action(SetPropertyTypes)
|
|
610
579
|
], PropertiesState.prototype, "SetPropertyTypes", null);
|
|
@@ -614,6 +583,15 @@ __decorate([
|
|
|
614
583
|
__decorate([
|
|
615
584
|
Action(SetDefaultViewType)
|
|
616
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);
|
|
617
595
|
__decorate([
|
|
618
596
|
Selector()
|
|
619
597
|
], PropertiesState, "properties", null);
|
|
@@ -658,10 +636,10 @@ __decorate([
|
|
|
658
636
|
], PropertiesState, "defaultViewType", null);
|
|
659
637
|
__decorate([
|
|
660
638
|
Selector()
|
|
661
|
-
], PropertiesState, "
|
|
639
|
+
], PropertiesState, "getLoadingActive", null);
|
|
662
640
|
__decorate([
|
|
663
641
|
Selector()
|
|
664
|
-
], PropertiesState, "
|
|
642
|
+
], PropertiesState, "getErrors", null);
|
|
665
643
|
__decorate([
|
|
666
644
|
Selector()
|
|
667
645
|
], PropertiesState, "propertyById", null);
|
|
@@ -673,10 +651,13 @@ PropertiesState = __decorate([
|
|
|
673
651
|
], PropertiesState);
|
|
674
652
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: PropertiesState, decorators: [{
|
|
675
653
|
type: Injectable
|
|
676
|
-
}], 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: [] } });
|
|
677
655
|
|
|
678
656
|
class PropertiesFacade {
|
|
679
657
|
store = inject(Store);
|
|
658
|
+
// ============================================================================
|
|
659
|
+
// Data Selectors - Memoized by NGXS (fine-grained reactivity)
|
|
660
|
+
// ============================================================================
|
|
680
661
|
list = select(PropertiesState.properties);
|
|
681
662
|
propertyTypes = select(PropertiesState.propertyTypes);
|
|
682
663
|
selected = select(PropertiesState.selectedProperty);
|
|
@@ -691,12 +672,47 @@ class PropertiesFacade {
|
|
|
691
672
|
apiProperties = select(PropertiesState.apiProperties);
|
|
692
673
|
breadcrumbItems = select(PropertiesState.breadcrumbItems);
|
|
693
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
|
+
// ============================================================================
|
|
694
711
|
systemProperties = computed(() => this.list().filter((property) => Boolean(property.isSystem)), ...(ngDevMode ? [{ debugName: "systemProperties" }] : []));
|
|
695
712
|
customProperties = computed(() => this.list().filter((property) => !Boolean(property.isSystem)), ...(ngDevMode ? [{ debugName: "customProperties" }] : []));
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
}
|
|
713
|
+
// ============================================================================
|
|
714
|
+
// Action Dispatchers
|
|
715
|
+
// ============================================================================
|
|
700
716
|
loadAll(params) {
|
|
701
717
|
return this.store.dispatch(new GetProperties(params));
|
|
702
718
|
}
|
|
@@ -843,7 +859,7 @@ class PropertiesList {
|
|
|
843
859
|
], ...(ngDevMode ? [{ debugName: "propertyTypes" }] : []));
|
|
844
860
|
tableColumns = signal([
|
|
845
861
|
{
|
|
846
|
-
key: 'name',
|
|
862
|
+
key: 'name.display',
|
|
847
863
|
label: this.transloco.translate('properties.list.columnName'),
|
|
848
864
|
filterConfig: {
|
|
849
865
|
type: 'text',
|
|
@@ -911,7 +927,7 @@ class PropertiesList {
|
|
|
911
927
|
loading: (row) => this.deletingRowIds().includes(row.id),
|
|
912
928
|
},
|
|
913
929
|
], ...(ngDevMode ? [{ debugName: "rowActions" }] : []));
|
|
914
|
-
loading = this.facade.
|
|
930
|
+
loading = this.facade.isLoadingAll;
|
|
915
931
|
tableData = computed(() => {
|
|
916
932
|
const tab = this.activeTab();
|
|
917
933
|
const allProperties = this.facade.list();
|
|
@@ -939,7 +955,7 @@ class PropertiesList {
|
|
|
939
955
|
this.deletingRowIds.update((ids) => [...ids, row.id]);
|
|
940
956
|
this.facade
|
|
941
957
|
.delete(row.id)
|
|
942
|
-
.pipe(finalize
|
|
958
|
+
.pipe(finalize(() => {
|
|
943
959
|
this.deletingRowIds.update((ids) => ids.filter((id) => id !== row.id));
|
|
944
960
|
}))
|
|
945
961
|
.subscribe();
|
|
@@ -996,7 +1012,7 @@ class ApiConfiguration {
|
|
|
996
1012
|
schema = signal(null, ...(ngDevMode ? [{ debugName: "schema" }] : []));
|
|
997
1013
|
isWriting = false;
|
|
998
1014
|
touched = false;
|
|
999
|
-
isTesting = this.facade.
|
|
1015
|
+
isTesting = this.facade.isTestingApi;
|
|
1000
1016
|
apiProperties = this.facade.apiProperties;
|
|
1001
1017
|
hasDetectedSchema = computed(() => this.apiProperties().length > 0, ...(ngDevMode ? [{ debugName: "hasDetectedSchema" }] : []));
|
|
1002
1018
|
form = new FormGroup({
|
|
@@ -1215,7 +1231,7 @@ class CheckListFormConfiguration {
|
|
|
1215
1231
|
key: 'properties',
|
|
1216
1232
|
cssClass: 'md:col-span-2',
|
|
1217
1233
|
options: this.configProperties(),
|
|
1218
|
-
optionLabel: 'name',
|
|
1234
|
+
optionLabel: 'name.display',
|
|
1219
1235
|
optionValue: 'key',
|
|
1220
1236
|
sourceHeader: this.transloco.translate('properties.form.availableProperties'),
|
|
1221
1237
|
targetHeader: this.transloco.translate('properties.form.selectedProperties'),
|
|
@@ -1291,7 +1307,7 @@ class DynamicListConfiguration {
|
|
|
1291
1307
|
key: 'properties',
|
|
1292
1308
|
cssClass: 'md:col-span-2',
|
|
1293
1309
|
options: this.configProperties(),
|
|
1294
|
-
optionLabel: 'name',
|
|
1310
|
+
optionLabel: 'name.display',
|
|
1295
1311
|
optionValue: 'key',
|
|
1296
1312
|
sourceHeader: this.transloco.translate('properties.form.availableProperties'),
|
|
1297
1313
|
targetHeader: this.transloco.translate('properties.form.selectedProperties'),
|
|
@@ -1367,7 +1383,7 @@ class EditableListViewConfiguration {
|
|
|
1367
1383
|
key: 'Properties',
|
|
1368
1384
|
cssClass: 'md:col-span-2',
|
|
1369
1385
|
options: this.configProperties(),
|
|
1370
|
-
optionLabel: 'name',
|
|
1386
|
+
optionLabel: 'name.display',
|
|
1371
1387
|
optionValue: 'key',
|
|
1372
1388
|
sourceHeader: this.transloco.translate('properties.form.availableProperties'),
|
|
1373
1389
|
targetHeader: this.transloco.translate('properties.form.selectedProperties'),
|
|
@@ -1463,7 +1479,7 @@ class InternalModuleConfiguration {
|
|
|
1463
1479
|
type: 'select',
|
|
1464
1480
|
key: 'property',
|
|
1465
1481
|
label: this.transloco.translate('properties.form.valueProperty'),
|
|
1466
|
-
optionLabel: 'name',
|
|
1482
|
+
optionLabel: 'name.display',
|
|
1467
1483
|
optionValue: 'key',
|
|
1468
1484
|
options: this.configProperties(),
|
|
1469
1485
|
},
|
|
@@ -1471,7 +1487,7 @@ class InternalModuleConfiguration {
|
|
|
1471
1487
|
cssClass: 'md:col-span-2 mt-2',
|
|
1472
1488
|
key: 'propertyDetails',
|
|
1473
1489
|
options: this.configProperties(),
|
|
1474
|
-
optionLabel: 'name',
|
|
1490
|
+
optionLabel: 'name.display',
|
|
1475
1491
|
optionValue: 'key',
|
|
1476
1492
|
sourceHeader: this.transloco.translate('properties.form.availableProperties'),
|
|
1477
1493
|
targetHeader: this.transloco.translate('properties.form.selectedProperties'),
|
|
@@ -1582,7 +1598,7 @@ class LookupConfiguration {
|
|
|
1582
1598
|
key: 'lookup',
|
|
1583
1599
|
type: 'select',
|
|
1584
1600
|
label: this.transloco.translate('properties.form.selectLookup'),
|
|
1585
|
-
optionLabel: 'name',
|
|
1601
|
+
optionLabel: 'name.display',
|
|
1586
1602
|
optionValue: 'id',
|
|
1587
1603
|
options: this.lookups(),
|
|
1588
1604
|
filter: true,
|
|
@@ -1663,7 +1679,7 @@ class UserConfiguration {
|
|
|
1663
1679
|
key: 'group',
|
|
1664
1680
|
type: 'select',
|
|
1665
1681
|
label: this.transloco.translate('properties.form.selectGroup'),
|
|
1666
|
-
optionLabel: 'name',
|
|
1682
|
+
optionLabel: 'name.display',
|
|
1667
1683
|
optionValue: 'id',
|
|
1668
1684
|
options: this.groups(),
|
|
1669
1685
|
filter: true,
|
|
@@ -1869,9 +1885,9 @@ class PropertyForm {
|
|
|
1869
1885
|
mainControl = this.propertyForm.get('main');
|
|
1870
1886
|
configurationControl = this.propertyForm.get('configuration');
|
|
1871
1887
|
formulaControl = this.propertyForm.get('formula');
|
|
1872
|
-
creating = this.facade.
|
|
1873
|
-
updating = this.facade.
|
|
1874
|
-
loading = this.facade.
|
|
1888
|
+
creating = this.facade.isCreating;
|
|
1889
|
+
updating = this.facade.isUpdating;
|
|
1890
|
+
loading = this.facade.isLoadingOne;
|
|
1875
1891
|
submitting = computed(() => this.creating() || this.updating(), ...(ngDevMode ? [{ debugName: "submitting" }] : []));
|
|
1876
1892
|
propertyType = toSignal(this.mainControl.valueChanges.pipe(map((v) => v?.viewType), distinctUntilChanged()));
|
|
1877
1893
|
isCalculated = toSignal(this.mainControl.valueChanges.pipe(map((v) => Boolean(v?.isCalculated)), distinctUntilChanged()), {
|
|
@@ -2240,5 +2256,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
|
|
|
2240
2256
|
* Generated bundle index. Do not edit.
|
|
2241
2257
|
*/
|
|
2242
2258
|
|
|
2243
|
-
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 };
|
|
2244
2260
|
//# sourceMappingURL=masterteam-properties.mjs.map
|