@masterteam/properties 0.0.1

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.
@@ -0,0 +1,1959 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, Injectable, computed, signal, Component, DestroyRef, effect, forwardRef, ChangeDetectionStrategy, linkedSignal, input, EnvironmentInjector, ViewContainerRef, ViewChild } from '@angular/core';
3
+ import { CommonModule, NgComponentOutlet } from '@angular/common';
4
+ import { Table } from '@masterteam/components/table';
5
+ import { Router, ActivatedRoute } from '@angular/router';
6
+ import { HttpClient, HttpContextToken } from '@angular/common/http';
7
+ import { Action, Selector, State, Store, select } from '@ngxs/store';
8
+ import { of, startWith, map, distinctUntilChanged, Subscription } from 'rxjs';
9
+ import { tap, catchError, finalize, switchMap } from 'rxjs/operators';
10
+ import { Button } from '@masterteam/components/button';
11
+ import { toSignal } from '@angular/core/rxjs-interop';
12
+ import { Card } from '@masterteam/components/card';
13
+ import { Avatar } from '@masterteam/components/avatar';
14
+ import { DynamicForm } from '@masterteam/forms/dynamic-form';
15
+ import { PickListFieldConfig, ValidatorConfig } from '@masterteam/components';
16
+ import * as i1 from '@angular/forms';
17
+ import { FormGroup, FormControl, FormArray, Validators, ReactiveFormsModule, NG_VALUE_ACCESSOR, ControlContainer, FormGroupDirective } from '@angular/forms';
18
+ import { SelectField } from '@masterteam/components/select-field';
19
+ import { TextField } from '@masterteam/components/text-field';
20
+ import { ToggleField } from '@masterteam/components/toggle-field';
21
+
22
+ function startLoading(ctx, loadingName) {
23
+ const { loadingActive, errors } = ctx.getState();
24
+ if (!loadingActive.includes(loadingName)) {
25
+ ctx.patchState({
26
+ loadingActive: [...loadingActive, loadingName],
27
+ });
28
+ }
29
+ if (errors && errors[loadingName]) {
30
+ const { [loadingName]: _removed, ...rest } = errors;
31
+ ctx.patchState({ errors: rest });
32
+ }
33
+ }
34
+ function endLoading(ctx, loadingName) {
35
+ const { loadingActive } = ctx.getState();
36
+ ctx.patchState({
37
+ loadingActive: loadingActive.filter((name) => name !== loadingName),
38
+ });
39
+ }
40
+ function setLoadingError(ctx, loadingName, message) {
41
+ const { errors } = ctx.getState();
42
+ ctx.patchState({
43
+ errors: { ...errors, [loadingName]: message },
44
+ });
45
+ }
46
+
47
+ class GetProperties {
48
+ params;
49
+ static type = '[Properties] Get All';
50
+ constructor(params) {
51
+ this.params = params;
52
+ }
53
+ }
54
+ class GetProperty {
55
+ id;
56
+ mode;
57
+ static type = '[Properties] Get One';
58
+ constructor(id, mode = 'edit') {
59
+ this.id = id;
60
+ this.mode = mode;
61
+ }
62
+ }
63
+ class GetLookups {
64
+ static type = '[Properties] Get Lookups';
65
+ }
66
+ class GetGroups {
67
+ static type = '[Properties] Get Groups';
68
+ }
69
+ class GetLogs {
70
+ static type = '[Properties] Get Logs';
71
+ }
72
+ class GetCountries {
73
+ static type = '[Properties] Get Countries';
74
+ }
75
+ class TestApiConfiguration {
76
+ payload;
77
+ static type = '[Properties] Test API Configuration';
78
+ constructor(payload) {
79
+ this.payload = payload;
80
+ }
81
+ }
82
+ class ResetApiConfiguration {
83
+ static type = '[Properties] Reset API Configuration';
84
+ }
85
+ class GetPropertiesForConfigType {
86
+ moduleType;
87
+ moduleId;
88
+ params;
89
+ static type = '[Properties] Get By Config Type';
90
+ constructor(moduleType, moduleId, params) {
91
+ this.moduleType = moduleType;
92
+ this.moduleId = moduleId;
93
+ this.params = params;
94
+ }
95
+ }
96
+ class ResetConfigProperties {
97
+ static type = '[Properties] Reset Config Properties';
98
+ }
99
+ class ResetSelectedProperty {
100
+ static type = '[Properties] Reset Selected Property';
101
+ }
102
+ class DeleteProperty {
103
+ id;
104
+ static type = '[Properties] Delete';
105
+ constructor(id) {
106
+ this.id = id;
107
+ }
108
+ }
109
+ class CreateProperty {
110
+ payload;
111
+ static type = '[Properties] Create';
112
+ constructor(payload) {
113
+ this.payload = payload;
114
+ }
115
+ }
116
+ class UpdateProperty {
117
+ id;
118
+ payload;
119
+ static type = '[Properties] Update';
120
+ constructor(id, payload) {
121
+ this.id = id;
122
+ this.payload = payload;
123
+ }
124
+ }
125
+ class SetPropertiesModuleInfo {
126
+ moduleType;
127
+ moduleId;
128
+ static type = '[Properties] Set Module Info';
129
+ constructor(moduleType, moduleId) {
130
+ this.moduleType = moduleType;
131
+ this.moduleId = moduleId;
132
+ }
133
+ }
134
+ class SetPropertyTypes {
135
+ payload;
136
+ static type = '[Properties] Set Property Types';
137
+ constructor(payload) {
138
+ this.payload = payload;
139
+ }
140
+ }
141
+
142
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
143
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
144
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
145
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
146
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
147
+ };
148
+ const DEFAULT_STATE = {
149
+ properties: [],
150
+ selectedProperty: null,
151
+ loadingActive: [],
152
+ errors: {},
153
+ moduleType: null,
154
+ moduleId: null,
155
+ lastQueryParams: null,
156
+ lookups: [],
157
+ configTypeProperties: [],
158
+ groups: [],
159
+ logs: [],
160
+ countries: [],
161
+ apiSchema: null,
162
+ apiProperties: [],
163
+ };
164
+ let PropertiesState = class PropertiesState {
165
+ http = inject(HttpClient);
166
+ baseUrl = 'Properties';
167
+ lookupsUrl = 'Lookups';
168
+ configPropertiesUrl = 'Properties';
169
+ groupsUrl = 'identity/Groups';
170
+ logsUrl = 'Logs';
171
+ countriesUrl = '/assets/countries/countries.json';
172
+ apiTestUrl = 'app/testAPI';
173
+ apiDetectUrl = 'app/detect';
174
+ static properties(state) {
175
+ return state.properties;
176
+ }
177
+ static selectedProperty(state) {
178
+ return state.selectedProperty;
179
+ }
180
+ static lookups(state) {
181
+ return state.lookups;
182
+ }
183
+ static configTypeProperties(state) {
184
+ return state.configTypeProperties;
185
+ }
186
+ static groups(state) {
187
+ return state.groups;
188
+ }
189
+ static logs(state) {
190
+ return state.logs;
191
+ }
192
+ static countries(state) {
193
+ return state.countries;
194
+ }
195
+ static apiSchema(state) {
196
+ return state.apiSchema;
197
+ }
198
+ static apiProperties(state) {
199
+ return state.apiProperties;
200
+ }
201
+ static propertyTypes(state) {
202
+ return state.propertyTypes ?? [];
203
+ }
204
+ static isLoadingFactory(state) {
205
+ return (loadingName) => state.loadingActive.includes(loadingName);
206
+ }
207
+ static errorFactory(state) {
208
+ return (loadingName) => state.errors?.[loadingName] ?? null;
209
+ }
210
+ static propertyById(state) {
211
+ return (id) => state.properties.find((property) => property.id === Number(id)) ?? null;
212
+ }
213
+ getAll(ctx, action) {
214
+ startLoading(ctx, 'getAll');
215
+ const state = ctx.getState();
216
+ const moduleType = state.moduleType ?? undefined;
217
+ const moduleId = state.moduleId ?? undefined;
218
+ const params = { ...action.params };
219
+ ctx.patchState({
220
+ lastQueryParams: params ?? null,
221
+ });
222
+ return this.http
223
+ .get(`${this.baseUrl}/${moduleType}/${moduleId}`, {
224
+ params: params,
225
+ })
226
+ .pipe(tap((response) => {
227
+ const properties = Array.isArray(response?.data) ? response.data : [];
228
+ ctx.patchState({ properties });
229
+ }), catchError((error) => {
230
+ const message = error?.error?.message ??
231
+ error?.message ??
232
+ 'Failed to load properties';
233
+ setLoadingError(ctx, 'getAll', message);
234
+ return of(null);
235
+ }), finalize(() => endLoading(ctx, 'getAll')));
236
+ }
237
+ getOne(ctx, action) {
238
+ startLoading(ctx, 'getOne');
239
+ const params = { mode: action.mode ?? 'edit' };
240
+ return this.http
241
+ .get(`${this.baseUrl}/${action.id}`, { params })
242
+ .pipe(tap((response) => {
243
+ ctx.patchState({
244
+ selectedProperty: response?.data ?? null,
245
+ });
246
+ }), catchError((error) => {
247
+ const message = error?.error?.message ??
248
+ error?.message ??
249
+ 'Failed to load property';
250
+ setLoadingError(ctx, 'getOne', message);
251
+ return of(null);
252
+ }), finalize(() => endLoading(ctx, 'getOne')));
253
+ }
254
+ getLookups(ctx, _action) {
255
+ const state = ctx.getState();
256
+ if (state.lookups.length) {
257
+ return of(state.lookups);
258
+ }
259
+ startLoading(ctx, 'getLookups');
260
+ return this.http.get(this.lookupsUrl).pipe(tap((response) => {
261
+ const lookups = Array.isArray(response?.data) ? response.data : [];
262
+ ctx.patchState({ lookups });
263
+ }), catchError((error) => {
264
+ const message = error?.error?.message ?? error?.message ?? 'Failed to load lookups';
265
+ setLoadingError(ctx, 'getLookups', message);
266
+ return of([]);
267
+ }), finalize(() => endLoading(ctx, 'getLookups')));
268
+ }
269
+ getGroups(ctx, _action) {
270
+ const state = ctx.getState();
271
+ if (state.groups.length) {
272
+ return of(state.groups);
273
+ }
274
+ startLoading(ctx, 'getGroups');
275
+ return this.http.get(this.groupsUrl).pipe(tap((response) => {
276
+ const groups = Array.isArray(response?.data) ? response.data : [];
277
+ ctx.patchState({ groups });
278
+ }), catchError((error) => {
279
+ const message = error?.error?.message ?? error?.message ?? 'Failed to load groups';
280
+ setLoadingError(ctx, 'getGroups', message);
281
+ return of([]);
282
+ }), finalize(() => endLoading(ctx, 'getGroups')));
283
+ }
284
+ getLogs(ctx, _action) {
285
+ const state = ctx.getState();
286
+ if (state.logs.length) {
287
+ return of(state.logs);
288
+ }
289
+ startLoading(ctx, 'getLogs');
290
+ return this.http.get(this.logsUrl).pipe(tap((response) => {
291
+ const logs = Array.isArray(response?.data) ? response.data : [];
292
+ ctx.patchState({ logs });
293
+ }), catchError((error) => {
294
+ const message = error?.error?.message ?? error?.message ?? 'Failed to load logs';
295
+ setLoadingError(ctx, 'getLogs', message);
296
+ return of([]);
297
+ }), finalize(() => endLoading(ctx, 'getLogs')));
298
+ }
299
+ getCountries(ctx, _action) {
300
+ const state = ctx.getState();
301
+ if (state.countries.length) {
302
+ return of(state.countries);
303
+ }
304
+ startLoading(ctx, 'getCountries');
305
+ return this.http.get(this.countriesUrl).pipe(tap((response) => {
306
+ const countries = Array.isArray(response) ? response : [];
307
+ ctx.patchState({ countries });
308
+ }), catchError((error) => {
309
+ const message = error?.error?.message ?? error?.message ?? 'Failed to load countries';
310
+ setLoadingError(ctx, 'getCountries', message);
311
+ return of([]);
312
+ }), finalize(() => endLoading(ctx, 'getCountries')));
313
+ }
314
+ testApiConfiguration(ctx, action) {
315
+ startLoading(ctx, 'testApiConfiguration');
316
+ ctx.patchState({
317
+ apiSchema: null,
318
+ apiProperties: [],
319
+ });
320
+ return this.http.post(this.apiTestUrl, action.payload).pipe(switchMap((testResponse) => {
321
+ const rawData = testResponse?.data;
322
+ if (!rawData) {
323
+ return of(null);
324
+ }
325
+ const formData = new FormData();
326
+ formData.append('jsonData', JSON.stringify(rawData));
327
+ return this.http
328
+ .post(this.apiDetectUrl, formData)
329
+ .pipe(tap((detectResponse) => {
330
+ const schema = detectResponse?.data ?? null;
331
+ const apiProperties = this.mapSchemaToOptions(schema);
332
+ ctx.patchState({
333
+ apiSchema: schema,
334
+ apiProperties,
335
+ });
336
+ }));
337
+ }), catchError((error) => {
338
+ const message = error?.error?.message ?? error?.message ?? 'Failed to test API';
339
+ setLoadingError(ctx, 'testApiConfiguration', message);
340
+ return of(null);
341
+ }), finalize(() => endLoading(ctx, 'testApiConfiguration')));
342
+ }
343
+ resetApiConfiguration(ctx) {
344
+ ctx.patchState({
345
+ apiSchema: null,
346
+ apiProperties: [],
347
+ });
348
+ }
349
+ resolveApiSchema(response) {
350
+ if (!response) {
351
+ return null;
352
+ }
353
+ if (response.schema) {
354
+ return response.schema;
355
+ }
356
+ return this.buildSchemaFromData(response.data);
357
+ }
358
+ buildSchemaFromData(data) {
359
+ const sample = Array.isArray(data) ? data[0] : data;
360
+ if (!sample || Array.isArray(sample) || typeof sample !== 'object') {
361
+ return null;
362
+ }
363
+ const entries = Object.entries(sample);
364
+ if (!entries.length) {
365
+ return null;
366
+ }
367
+ const properties = entries.reduce((acc, [key, value]) => {
368
+ acc[key] = { type: this.resolveValueType(value) };
369
+ return acc;
370
+ }, {});
371
+ return { properties };
372
+ }
373
+ resolveValueType(value) {
374
+ if (Array.isArray(value)) {
375
+ return 'array';
376
+ }
377
+ if (value === null) {
378
+ return 'null';
379
+ }
380
+ return typeof value;
381
+ }
382
+ mapSchemaToOptions(schema) {
383
+ if (!schema?.properties) {
384
+ return [];
385
+ }
386
+ return Object.entries(schema.properties).map(([key, definition]) => {
387
+ const typeLabel = definition?.type ? ` | ${definition.type}` : '';
388
+ return {
389
+ key,
390
+ name: `${key}${typeLabel}`,
391
+ type: definition?.type,
392
+ };
393
+ });
394
+ }
395
+ getPropertiesForConfigType(ctx, action) {
396
+ startLoading(ctx, 'getConfigProperties');
397
+ const { moduleType, moduleId, params } = action;
398
+ const httpParams = params
399
+ ? Object.entries(params)
400
+ .filter(([, value]) => value !== undefined && value !== null)
401
+ .reduce((acc, [key, value]) => {
402
+ acc[key] = String(value);
403
+ return acc;
404
+ }, {})
405
+ : undefined;
406
+ return this.http
407
+ .get(`${this.configPropertiesUrl}/${encodeURIComponent(moduleType)}/${encodeURIComponent(String(moduleId))}`, httpParams ? { params: httpParams } : undefined)
408
+ .pipe(tap((response) => {
409
+ const configTypeProperties = Array.isArray(response?.data)
410
+ ? response.data
411
+ : [];
412
+ ctx.patchState({ configTypeProperties });
413
+ }), catchError((error) => {
414
+ const message = error?.error?.message ??
415
+ error?.message ??
416
+ 'Failed to load properties';
417
+ setLoadingError(ctx, 'getConfigProperties', message);
418
+ return of([]);
419
+ }), finalize(() => endLoading(ctx, 'getConfigProperties')));
420
+ }
421
+ resetConfigProperties(ctx) {
422
+ ctx.patchState({ configTypeProperties: [] });
423
+ }
424
+ resetSelectedProperty(ctx) {
425
+ ctx.patchState({ selectedProperty: null });
426
+ }
427
+ setModuleInfo(ctx, action) {
428
+ ctx.patchState({
429
+ moduleType: encodeURIComponent(action.moduleType),
430
+ moduleId: encodeURIComponent(String(action.moduleId)),
431
+ });
432
+ }
433
+ create(ctx, action) {
434
+ startLoading(ctx, 'create');
435
+ const state = ctx.getState();
436
+ const moduleType = state.moduleType ?? undefined;
437
+ const moduleId = state.moduleId ?? undefined;
438
+ if (!moduleType || moduleId === undefined || moduleId === null) {
439
+ const message = 'Missing module context for creating property';
440
+ setLoadingError(ctx, 'create', message);
441
+ endLoading(ctx, 'create');
442
+ return of(null);
443
+ }
444
+ return this.http
445
+ .post(`${this.baseUrl}/${moduleType}/${moduleId}`, action.payload)
446
+ .pipe(tap((response) => {
447
+ const created = response?.data;
448
+ if (!created) {
449
+ return;
450
+ }
451
+ const state = ctx.getState();
452
+ ctx.patchState({
453
+ properties: [...state.properties, created],
454
+ selectedProperty: created,
455
+ });
456
+ }), finalize(() => endLoading(ctx, 'create')));
457
+ }
458
+ update(ctx, action) {
459
+ startLoading(ctx, 'update');
460
+ const state = ctx.getState();
461
+ const moduleType = state.moduleType ?? undefined;
462
+ const moduleId = state.moduleId ?? undefined;
463
+ if (!moduleType || moduleId === undefined || moduleId === null) {
464
+ const message = 'Missing module context for updating property';
465
+ setLoadingError(ctx, 'update', message);
466
+ endLoading(ctx, 'update');
467
+ return of(null);
468
+ }
469
+ return this.http
470
+ .put(`${this.baseUrl}/${moduleType}/${moduleId}/${encodeURIComponent(String(action.id))}`, action.payload)
471
+ .pipe(tap((response) => {
472
+ const updated = response?.data;
473
+ if (!updated) {
474
+ return;
475
+ }
476
+ const updatedId = updated.id ?? Number(action.id);
477
+ const state = ctx.getState();
478
+ const properties = state.properties.some((item) => item.id === updatedId)
479
+ ? state.properties.map((item) => item.id === updatedId ? { ...item, ...updated } : item)
480
+ : [...state.properties, updated];
481
+ ctx.patchState({
482
+ properties,
483
+ selectedProperty: updated,
484
+ });
485
+ }), catchError((error) => {
486
+ const message = error?.error?.message ??
487
+ error?.message ??
488
+ 'Failed to update property';
489
+ setLoadingError(ctx, 'update', message);
490
+ return of(null);
491
+ }), finalize(() => endLoading(ctx, 'update')));
492
+ }
493
+ delete(ctx, action) {
494
+ startLoading(ctx, 'delete');
495
+ return this.http
496
+ .delete(`${this.baseUrl}/${encodeURIComponent(String(action.id))}`)
497
+ .pipe(tap(() => {
498
+ const { properties, selectedProperty } = ctx.getState();
499
+ const remaining = properties.filter((item) => item.id !== Number(action.id));
500
+ const nextSelected = selectedProperty && selectedProperty.id === Number(action.id)
501
+ ? null
502
+ : selectedProperty;
503
+ ctx.patchState({
504
+ properties: remaining,
505
+ selectedProperty: nextSelected,
506
+ });
507
+ }), catchError((error) => {
508
+ const message = error?.error?.message ??
509
+ error?.message ??
510
+ 'Failed to delete property';
511
+ setLoadingError(ctx, 'delete', message);
512
+ return of(null);
513
+ }), finalize(() => endLoading(ctx, 'delete')));
514
+ }
515
+ SetPropertyTypes(ctx, action) {
516
+ ctx.patchState({
517
+ propertyTypes: action.payload,
518
+ });
519
+ }
520
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: PropertiesState, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
521
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: PropertiesState });
522
+ };
523
+ __decorate([
524
+ Action(GetProperties)
525
+ ], PropertiesState.prototype, "getAll", null);
526
+ __decorate([
527
+ Action(GetProperty)
528
+ ], PropertiesState.prototype, "getOne", null);
529
+ __decorate([
530
+ Action(GetLookups)
531
+ ], PropertiesState.prototype, "getLookups", null);
532
+ __decorate([
533
+ Action(GetGroups)
534
+ ], PropertiesState.prototype, "getGroups", null);
535
+ __decorate([
536
+ Action(GetLogs)
537
+ ], PropertiesState.prototype, "getLogs", null);
538
+ __decorate([
539
+ Action(GetCountries)
540
+ ], PropertiesState.prototype, "getCountries", null);
541
+ __decorate([
542
+ Action(TestApiConfiguration)
543
+ ], PropertiesState.prototype, "testApiConfiguration", null);
544
+ __decorate([
545
+ Action(ResetApiConfiguration)
546
+ ], PropertiesState.prototype, "resetApiConfiguration", null);
547
+ __decorate([
548
+ Action(GetPropertiesForConfigType)
549
+ ], PropertiesState.prototype, "getPropertiesForConfigType", null);
550
+ __decorate([
551
+ Action(ResetConfigProperties)
552
+ ], PropertiesState.prototype, "resetConfigProperties", null);
553
+ __decorate([
554
+ Action(ResetSelectedProperty)
555
+ ], PropertiesState.prototype, "resetSelectedProperty", null);
556
+ __decorate([
557
+ Action(SetPropertiesModuleInfo)
558
+ ], PropertiesState.prototype, "setModuleInfo", null);
559
+ __decorate([
560
+ Action(CreateProperty)
561
+ ], PropertiesState.prototype, "create", null);
562
+ __decorate([
563
+ Action(UpdateProperty)
564
+ ], PropertiesState.prototype, "update", null);
565
+ __decorate([
566
+ Action(DeleteProperty)
567
+ ], PropertiesState.prototype, "delete", null);
568
+ __decorate([
569
+ Action(SetPropertyTypes)
570
+ ], PropertiesState.prototype, "SetPropertyTypes", null);
571
+ __decorate([
572
+ Selector()
573
+ ], PropertiesState, "properties", null);
574
+ __decorate([
575
+ Selector()
576
+ ], PropertiesState, "selectedProperty", null);
577
+ __decorate([
578
+ Selector()
579
+ ], PropertiesState, "lookups", null);
580
+ __decorate([
581
+ Selector()
582
+ ], PropertiesState, "configTypeProperties", null);
583
+ __decorate([
584
+ Selector()
585
+ ], PropertiesState, "groups", null);
586
+ __decorate([
587
+ Selector()
588
+ ], PropertiesState, "logs", null);
589
+ __decorate([
590
+ Selector()
591
+ ], PropertiesState, "countries", null);
592
+ __decorate([
593
+ Selector()
594
+ ], PropertiesState, "apiSchema", null);
595
+ __decorate([
596
+ Selector()
597
+ ], PropertiesState, "apiProperties", null);
598
+ __decorate([
599
+ Selector()
600
+ ], PropertiesState, "propertyTypes", null);
601
+ __decorate([
602
+ Selector()
603
+ ], PropertiesState, "isLoadingFactory", null);
604
+ __decorate([
605
+ Selector()
606
+ ], PropertiesState, "errorFactory", null);
607
+ __decorate([
608
+ Selector()
609
+ ], PropertiesState, "propertyById", null);
610
+ PropertiesState = __decorate([
611
+ State({
612
+ name: 'properties',
613
+ defaults: DEFAULT_STATE,
614
+ })
615
+ ], PropertiesState);
616
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: PropertiesState, decorators: [{
617
+ type: Injectable
618
+ }], propDecorators: { getAll: [], getOne: [], getLookups: [], getGroups: [], getLogs: [], getCountries: [], testApiConfiguration: [], resetApiConfiguration: [], getPropertiesForConfigType: [], resetConfigProperties: [], resetSelectedProperty: [], setModuleInfo: [], create: [], update: [], delete: [], SetPropertyTypes: [] } });
619
+
620
+ class PropertiesFacade {
621
+ store = inject(Store);
622
+ list = select(PropertiesState.properties);
623
+ propertyTypes = select(PropertiesState.propertyTypes);
624
+ selected = select(PropertiesState.selectedProperty);
625
+ lookups = select(PropertiesState.lookups);
626
+ configProperties = select(PropertiesState.configTypeProperties);
627
+ groups = select(PropertiesState.groups);
628
+ logs = select(PropertiesState.logs);
629
+ countries = select(PropertiesState.countries);
630
+ apiSchema = select(PropertiesState.apiSchema);
631
+ apiProperties = select(PropertiesState.apiProperties);
632
+ systemProperties = computed(() => this.list().filter((property) => Boolean(property.isSystem)), ...(ngDevMode ? [{ debugName: "systemProperties" }] : []));
633
+ customProperties = computed(() => this.list().filter((property) => !Boolean(property.isSystem)), ...(ngDevMode ? [{ debugName: "customProperties" }] : []));
634
+ isLoading(loadingName) {
635
+ const loadingFactory = select(PropertiesState.isLoadingFactory);
636
+ return computed(() => loadingFactory()(loadingName));
637
+ }
638
+ loadAll(params) {
639
+ return this.store.dispatch(new GetProperties(params));
640
+ }
641
+ loadOne(id, mode = 'edit') {
642
+ return this.store.dispatch(new GetProperty(id, mode));
643
+ }
644
+ delete(id) {
645
+ return this.store.dispatch(new DeleteProperty(id));
646
+ }
647
+ create(payload) {
648
+ return this.store.dispatch(new CreateProperty(payload));
649
+ }
650
+ update(id, payload) {
651
+ return this.store.dispatch(new UpdateProperty(id, payload));
652
+ }
653
+ setModuleInfo(moduleType, moduleId) {
654
+ return this.store.dispatch(new SetPropertiesModuleInfo(moduleType, moduleId));
655
+ }
656
+ loadLookups() {
657
+ return this.store.dispatch(new GetLookups());
658
+ }
659
+ loadGroups() {
660
+ return this.store.dispatch(new GetGroups());
661
+ }
662
+ loadLogs() {
663
+ return this.store.dispatch(new GetLogs());
664
+ }
665
+ loadCountries() {
666
+ return this.store.dispatch(new GetCountries());
667
+ }
668
+ testApiConfiguration(payload) {
669
+ return this.store.dispatch(new TestApiConfiguration(payload));
670
+ }
671
+ resetApiConfiguration() {
672
+ return this.store.dispatch(new ResetApiConfiguration());
673
+ }
674
+ setPropertyTypes(propertyTypes) {
675
+ return this.store.dispatch(new SetPropertyTypes(propertyTypes));
676
+ }
677
+ loadPropertiesForConfigType(moduleType, moduleId, params) {
678
+ return this.store.dispatch(new GetPropertiesForConfigType(moduleType, moduleId, params));
679
+ }
680
+ resetSelectedProperty() {
681
+ return this.store.dispatch(new ResetSelectedProperty());
682
+ }
683
+ resetConfigProperties() {
684
+ return this.store.dispatch(new ResetConfigProperties());
685
+ }
686
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: PropertiesFacade, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
687
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: PropertiesFacade, providedIn: 'root' });
688
+ }
689
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: PropertiesFacade, decorators: [{
690
+ type: Injectable,
691
+ args: [{
692
+ providedIn: 'root',
693
+ }]
694
+ }] });
695
+
696
+ // store/app.state.ts
697
+ const REQUEST_CONTEXT = new HttpContextToken(() => ({
698
+ useBaseUrl: false,
699
+ }));
700
+
701
+ // store/index.ts
702
+ // This file exports EVERYTHING - one import for all state needs
703
+ // States
704
+
705
+ class PropertiesList {
706
+ facade = inject(PropertiesFacade);
707
+ router = inject(Router);
708
+ route = inject(ActivatedRoute);
709
+ tabs = signal([
710
+ { label: 'All', value: 'all' },
711
+ { label: 'System', value: 'system' },
712
+ { label: 'Custom', value: 'custom' },
713
+ ], ...(ngDevMode ? [{ debugName: "tabs" }] : []));
714
+ activeTab = signal('all', ...(ngDevMode ? [{ debugName: "activeTab" }] : []));
715
+ tableColumns = signal([
716
+ { key: 'name', label: 'Name' },
717
+ { key: 'viewType', label: 'Type' },
718
+ { key: 'required', label: 'Required', type: 'boolean' },
719
+ ], ...(ngDevMode ? [{ debugName: "tableColumns" }] : []));
720
+ rowActions = signal([
721
+ {
722
+ icon: 'custom.pencil',
723
+ tooltip: 'Edit',
724
+ color: 'primary',
725
+ action: (row) => this.editRow(row),
726
+ },
727
+ {
728
+ icon: 'general.trash-01',
729
+ tooltip: 'Delete',
730
+ color: 'danger',
731
+ variant: 'outlined',
732
+ action: (row) => this.deleteRow(row),
733
+ },
734
+ ], ...(ngDevMode ? [{ debugName: "rowActions" }] : []));
735
+ loading = this.facade.isLoading('getAll');
736
+ tableData = computed(() => {
737
+ const tab = this.activeTab();
738
+ const allProperties = this.facade.list();
739
+ switch (tab) {
740
+ case 'system':
741
+ return this.facade.systemProperties();
742
+ case 'custom':
743
+ return this.facade.customProperties();
744
+ case 'all':
745
+ default:
746
+ return allProperties;
747
+ }
748
+ }, ...(ngDevMode ? [{ debugName: "tableData" }] : []));
749
+ editRow(row) {
750
+ if (!row?.id) {
751
+ return;
752
+ }
753
+ this.router.navigate(['../properties-form', row.id], {
754
+ relativeTo: this.route,
755
+ });
756
+ }
757
+ deleteRow(row) {
758
+ if (!row?.id) {
759
+ return;
760
+ }
761
+ this.facade.delete(row.id);
762
+ }
763
+ createProperty() {
764
+ this.router.navigate(['../properties-form'], {
765
+ relativeTo: this.route,
766
+ });
767
+ }
768
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: PropertiesList, deps: [], target: i0.ɵɵFactoryTarget.Component });
769
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.3", type: PropertiesList, isStandalone: true, selector: "mt-properties-list", ngImport: i0, template: "<div class=\"py-4 px-6 space-y-3\">\n <div class=\"flex items-center justify-between\">\n <div class=\"space-y-1\">\n <h1 class=\"text-xl font-semibold text-slate-900 tracking-tight\">\n All Properties\n </h1>\n <p class=\"text-sm text-slate-500\">PMO - Project - Properties</p>\n </div>\n <mt-button label=\"Create\" (click)=\"createProperty()\" />\n </div>\n\n <mt-table\n [tabs]=\"tabs()\"\n [(activeTab)]=\"activeTab\"\n [data]=\"tableData()\"\n [columns]=\"tableColumns()\"\n [rowActions]=\"rowActions()\"\n [generalSearch]=\"true\"\n [showFilters]=\"true\"\n [loading]=\"loading()\"\n paginatorPosition=\"center\"\n >\n </mt-table>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: Table, selector: "mt-table", inputs: ["data", "columns", "rowActions", "size", "showGridlines", "stripedRows", "selectableRows", "generalSearch", "showFilters", "loading", "tabs", "tabsOptionLabel", "tabsOptionValue", "activeTab", "actions", "paginatorPosition", "pageSize", "currentPage", "first", "filterTerm"], outputs: ["selectionChange", "activeTabChange", "onTabChange", "pageSizeChange", "currentPageChange", "firstChange", "filterTermChange"] }, { 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"] }] });
770
+ }
771
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: PropertiesList, decorators: [{
772
+ type: Component,
773
+ args: [{ selector: 'mt-properties-list', standalone: true, imports: [CommonModule, Table, Button], template: "<div class=\"py-4 px-6 space-y-3\">\n <div class=\"flex items-center justify-between\">\n <div class=\"space-y-1\">\n <h1 class=\"text-xl font-semibold text-slate-900 tracking-tight\">\n All Properties\n </h1>\n <p class=\"text-sm text-slate-500\">PMO - Project - Properties</p>\n </div>\n <mt-button label=\"Create\" (click)=\"createProperty()\" />\n </div>\n\n <mt-table\n [tabs]=\"tabs()\"\n [(activeTab)]=\"activeTab\"\n [data]=\"tableData()\"\n [columns]=\"tableColumns()\"\n [rowActions]=\"rowActions()\"\n [generalSearch]=\"true\"\n [showFilters]=\"true\"\n [loading]=\"loading()\"\n paginatorPosition=\"center\"\n >\n </mt-table>\n</div>\n" }]
774
+ }] });
775
+
776
+ class ApiConfiguration {
777
+ facade = inject(PropertiesFacade);
778
+ destroyRef = inject(DestroyRef);
779
+ schema = signal(null, ...(ngDevMode ? [{ debugName: "schema" }] : []));
780
+ isWriting = false;
781
+ touched = false;
782
+ isTesting = this.facade.isLoading('testApiConfiguration');
783
+ apiProperties = this.facade.apiProperties;
784
+ hasDetectedSchema = computed(() => this.apiProperties().length > 0, ...(ngDevMode ? [{ debugName: "hasDetectedSchema" }] : []));
785
+ form = new FormGroup({
786
+ endpoint: new FormControl('', {
787
+ nonNullable: true,
788
+ validators: [Validators.required],
789
+ }),
790
+ headers: new FormArray([]),
791
+ key: new FormControl(null),
792
+ value: new FormControl(null),
793
+ supportMultiSelect: new FormControl(false, { nonNullable: true }),
794
+ });
795
+ onChange = () => { };
796
+ onTouched = () => { };
797
+ formChanges = toSignal(this.form.valueChanges, {
798
+ initialValue: this.form.getRawValue(),
799
+ });
800
+ constructor() {
801
+ this.facade.resetApiConfiguration();
802
+ effect(() => {
803
+ this.formChanges();
804
+ this.emitValue();
805
+ });
806
+ effect(() => {
807
+ const latestSchema = this.facade.apiSchema();
808
+ if (latestSchema !== undefined) {
809
+ this.schema.set(latestSchema);
810
+ if (!this.isWriting) {
811
+ this.emitValue(false);
812
+ }
813
+ }
814
+ });
815
+ this.destroyRef.onDestroy(() => {
816
+ this.facade.resetApiConfiguration();
817
+ });
818
+ }
819
+ get headers() {
820
+ return this.form.controls.headers;
821
+ }
822
+ writeValue(value) {
823
+ this.isWriting = true;
824
+ try {
825
+ if (!value) {
826
+ this.form.reset({
827
+ endpoint: '',
828
+ key: null,
829
+ value: null,
830
+ supportMultiSelect: false,
831
+ }, { emitEvent: false });
832
+ this.setHeadersFromRecord({});
833
+ this.schema.set(null);
834
+ this.touched = false;
835
+ return;
836
+ }
837
+ this.schema.set(value.schema ?? null);
838
+ this.form.patchValue({
839
+ endpoint: value.endpoint ?? '',
840
+ key: value.key ?? null,
841
+ value: value.value ?? null,
842
+ supportMultiSelect: !!value.supportMultiSelect,
843
+ }, { emitEvent: false });
844
+ this.setHeadersFromRecord(value.headers ?? {});
845
+ this.touched = false;
846
+ }
847
+ finally {
848
+ this.isWriting = false;
849
+ this.emitValue(false);
850
+ }
851
+ }
852
+ registerOnChange(fn) {
853
+ this.onChange = fn;
854
+ }
855
+ registerOnTouched(fn) {
856
+ this.onTouched = fn;
857
+ }
858
+ setDisabledState(isDisabled) {
859
+ if (isDisabled) {
860
+ this.form.disable({ emitEvent: false });
861
+ }
862
+ else {
863
+ this.form.enable({ emitEvent: false });
864
+ }
865
+ }
866
+ addHeader() {
867
+ this.headers.push(this.createHeaderGroup());
868
+ }
869
+ removeHeader(index) {
870
+ this.headers.removeAt(index);
871
+ this.emitValue();
872
+ }
873
+ testApi() {
874
+ if (!this.form.controls.endpoint.valid) {
875
+ this.form.controls.endpoint.markAsTouched();
876
+ return;
877
+ }
878
+ const headers = this.headersToRecord();
879
+ const payload = {
880
+ endpoint: this.form.controls.endpoint.value,
881
+ headers: Object.keys(headers).length ? headers : undefined,
882
+ };
883
+ this.facade.testApiConfiguration(payload).subscribe();
884
+ }
885
+ emitValue(triggerTouched = true) {
886
+ if (this.isWriting) {
887
+ return;
888
+ }
889
+ const headers = this.headersToRecord();
890
+ const value = {
891
+ endpoint: this.form.controls.endpoint.value,
892
+ headers,
893
+ key: this.form.controls.key.value ?? undefined,
894
+ value: this.form.controls.value.value ?? undefined,
895
+ supportMultiSelect: this.form.controls.supportMultiSelect.value,
896
+ schema: this.schema(),
897
+ };
898
+ this.onChange(value);
899
+ if (triggerTouched && !this.touched) {
900
+ this.onTouched();
901
+ this.touched = true;
902
+ }
903
+ }
904
+ createHeaderGroup(initial = {}) {
905
+ return new FormGroup({
906
+ key: new FormControl(initial.key ?? '', { nonNullable: true }),
907
+ value: new FormControl(initial.value ?? '', { nonNullable: true }),
908
+ });
909
+ }
910
+ setHeadersFromRecord(headers) {
911
+ while (this.headers.length) {
912
+ this.headers.removeAt(0);
913
+ }
914
+ Object.entries(headers).forEach(([key, value]) => {
915
+ this.headers.push(this.createHeaderGroup({ key, value }));
916
+ });
917
+ }
918
+ headersToRecord() {
919
+ return this.headers.controls.reduce((acc, group) => {
920
+ const key = group.controls.key.value?.trim();
921
+ if (key) {
922
+ acc[key] = group.controls.value.value ?? '';
923
+ }
924
+ return acc;
925
+ }, {});
926
+ }
927
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: ApiConfiguration, deps: [], target: i0.ɵɵFactoryTarget.Component });
928
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.3", type: ApiConfiguration, isStandalone: true, selector: "mt-api-configuration", providers: [
929
+ {
930
+ provide: NG_VALUE_ACCESSOR,
931
+ useExisting: forwardRef(() => ApiConfiguration),
932
+ multi: true,
933
+ },
934
+ ], ngImport: i0, template: "<div [formGroup]=\"form\" class=\"space-y-6\">\n <div class=\"space-y-4 rounded-xl bg-white px-6 py-4 shadow-sm\">\n <div class=\"grid items-end gap-3 md:grid-cols-[minmax(0,1fr)_auto]\">\n <mt-text-field\n formControlName=\"endpoint\"\n label=\"Endpoint\"\n placeholder=\"https://api.example.com/items\"\n />\n <div class=\"flex justify-end gap-2\">\n <mt-button\n type=\"button\"\n [text]=\"true\"\n icon=\"general.plus\"\n label=\"Add Header\"\n (click)=\"addHeader()\"\n />\n <mt-button\n type=\"button\"\n label=\"Test API\"\n [loading]=\"isTesting()\"\n (click)=\"testApi()\"\n />\n </div>\n </div>\n\n @if (headers.controls.length) {\n <div class=\"space-y-3\">\n <div class=\"text-sm font-medium text-surface-500\">Headers</div>\n <div class=\"space-y-3\">\n @for (\n headerCtrl of headers.controls;\n track headerCtrl;\n let i = $index\n ) {\n <div\n [formGroup]=\"headerCtrl\"\n class=\"grid items-end gap-3 md:grid-cols-[minmax(0,1fr)_minmax(0,1fr)_auto]\"\n >\n <mt-text-field formControlName=\"key\" label=\"Key\" />\n <mt-text-field formControlName=\"value\" label=\"Value\" />\n <mt-button\n type=\"button\"\n [text]=\"true\"\n icon=\"general.trash-01\"\n (click)=\"removeHeader(i)\"\n />\n </div>\n }\n </div>\n </div>\n } @else {\n <p class=\"text-xs text-surface-400\">\n No headers added. Use \u201CAdd Header\u201D to include authentication or custom\n headers.\n </p>\n }\n </div>\n\n <div class=\"space-y-4 rounded-xl bg-white px-6 py-4 shadow-sm\">\n @if (hasDetectedSchema()) {\n <div class=\"grid gap-4 md:grid-cols-2\">\n <mt-select-field\n formControlName=\"key\"\n [options]=\"apiProperties()\"\n [showClear]=\"true\"\n optionLabel=\"name\"\n optionValue=\"key\"\n label=\"Key field\"\n />\n <mt-select-field\n formControlName=\"value\"\n [options]=\"apiProperties()\"\n [showClear]=\"true\"\n optionLabel=\"name\"\n optionValue=\"key\"\n label=\"Value field\"\n />\n </div>\n } @else {\n <p class=\"text-xs text-surface-400\">\n Run \u201CTest API\u201D to detect available fields.\n </p>\n }\n\n <div class=\"flex items-center justify-between gap-4\">\n <mt-toggle-field\n formControlName=\"supportMultiSelect\"\n label=\"Support multiple select\"\n />\n @if (isTesting()) {\n <span class=\"text-xs text-surface-400\">Testing...</span>\n }\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: TextField, selector: "mt-text-field", inputs: ["field", "hint", "label", "placeholder", "class", "type", "readonly", "pInputs", "required", "icon", "iconPosition"] }, { kind: "component", type: SelectField, selector: "mt-select-field", inputs: ["field", "label", "placeholder", "hasPlaceholderPrefix", "class", "readonly", "pInputs", "options", "optionValue", "optionLabel", "filter", "filterBy", "dataKey", "showClear", "clearAfterSelect", "required"], outputs: ["onChange"] }, { kind: "component", type: ToggleField, selector: "mt-toggle-field", inputs: ["label", "labelPosition", "placeholder", "readonly", "pInputs", "required"], outputs: ["onChange"] }, { 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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
935
+ }
936
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: ApiConfiguration, decorators: [{
937
+ type: Component,
938
+ args: [{ selector: 'mt-api-configuration', standalone: true, imports: [
939
+ CommonModule,
940
+ ReactiveFormsModule,
941
+ TextField,
942
+ SelectField,
943
+ ToggleField,
944
+ Button,
945
+ ], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
946
+ {
947
+ provide: NG_VALUE_ACCESSOR,
948
+ useExisting: forwardRef(() => ApiConfiguration),
949
+ multi: true,
950
+ },
951
+ ], template: "<div [formGroup]=\"form\" class=\"space-y-6\">\n <div class=\"space-y-4 rounded-xl bg-white px-6 py-4 shadow-sm\">\n <div class=\"grid items-end gap-3 md:grid-cols-[minmax(0,1fr)_auto]\">\n <mt-text-field\n formControlName=\"endpoint\"\n label=\"Endpoint\"\n placeholder=\"https://api.example.com/items\"\n />\n <div class=\"flex justify-end gap-2\">\n <mt-button\n type=\"button\"\n [text]=\"true\"\n icon=\"general.plus\"\n label=\"Add Header\"\n (click)=\"addHeader()\"\n />\n <mt-button\n type=\"button\"\n label=\"Test API\"\n [loading]=\"isTesting()\"\n (click)=\"testApi()\"\n />\n </div>\n </div>\n\n @if (headers.controls.length) {\n <div class=\"space-y-3\">\n <div class=\"text-sm font-medium text-surface-500\">Headers</div>\n <div class=\"space-y-3\">\n @for (\n headerCtrl of headers.controls;\n track headerCtrl;\n let i = $index\n ) {\n <div\n [formGroup]=\"headerCtrl\"\n class=\"grid items-end gap-3 md:grid-cols-[minmax(0,1fr)_minmax(0,1fr)_auto]\"\n >\n <mt-text-field formControlName=\"key\" label=\"Key\" />\n <mt-text-field formControlName=\"value\" label=\"Value\" />\n <mt-button\n type=\"button\"\n [text]=\"true\"\n icon=\"general.trash-01\"\n (click)=\"removeHeader(i)\"\n />\n </div>\n }\n </div>\n </div>\n } @else {\n <p class=\"text-xs text-surface-400\">\n No headers added. Use \u201CAdd Header\u201D to include authentication or custom\n headers.\n </p>\n }\n </div>\n\n <div class=\"space-y-4 rounded-xl bg-white px-6 py-4 shadow-sm\">\n @if (hasDetectedSchema()) {\n <div class=\"grid gap-4 md:grid-cols-2\">\n <mt-select-field\n formControlName=\"key\"\n [options]=\"apiProperties()\"\n [showClear]=\"true\"\n optionLabel=\"name\"\n optionValue=\"key\"\n label=\"Key field\"\n />\n <mt-select-field\n formControlName=\"value\"\n [options]=\"apiProperties()\"\n [showClear]=\"true\"\n optionLabel=\"name\"\n optionValue=\"key\"\n label=\"Value field\"\n />\n </div>\n } @else {\n <p class=\"text-xs text-surface-400\">\n Run \u201CTest API\u201D to detect available fields.\n </p>\n }\n\n <div class=\"flex items-center justify-between gap-4\">\n <mt-toggle-field\n formControlName=\"supportMultiSelect\"\n label=\"Support multiple select\"\n />\n @if (isTesting()) {\n <span class=\"text-xs text-surface-400\">Testing...</span>\n }\n </div>\n </div>\n</div>\n" }]
952
+ }], ctorParameters: () => [] });
953
+
954
+ class CheckListFormConfiguration {
955
+ propertiesFacade = inject(PropertiesFacade);
956
+ controlContainer = inject(ControlContainer);
957
+ parentGroup = this.controlContainer.control;
958
+ lookups = this.propertiesFacade.lookups;
959
+ logs = this.propertiesFacade.logs;
960
+ configProperties = this.propertiesFacade.configProperties;
961
+ prevLogId = signal(null, ...(ngDevMode ? [{ debugName: "prevLogId" }] : []));
962
+ configuration = toSignal(this.parentGroup.valueChanges.pipe(startWith(this.parentGroup.value), map((value) => value?.configuration), distinctUntilChanged()), { initialValue: this.parentGroup.value?.configuration });
963
+ formConfig = linkedSignal(() => ({
964
+ sections: [
965
+ {
966
+ key: 'configuration',
967
+ label: 'Configuration',
968
+ cssClass: ' rounded-xl bg-white \
969
+ shadow-sm \
970
+ px-6 py-4',
971
+ type: 'header',
972
+ bodyClass: 'grid grid-cols-1 md:grid-cols-2 gap-3',
973
+ fields: [
974
+ {
975
+ key: 'lookup',
976
+ type: 'select',
977
+ label: 'Select Lookup',
978
+ optionLabel: 'displayName',
979
+ optionValue: 'id',
980
+ options: this.lookups(),
981
+ },
982
+ {
983
+ key: 'log',
984
+ type: 'select',
985
+ label: 'Select Log',
986
+ optionLabel: 'name',
987
+ optionValue: 'id',
988
+ options: this.logs(),
989
+ },
990
+ new PickListFieldConfig({
991
+ key: 'properties',
992
+ cssClass: 'md:col-span-2',
993
+ options: this.configProperties(),
994
+ optionLabel: 'name',
995
+ optionValue: 'key',
996
+ sourceHeader: 'Available Properties',
997
+ targetHeader: 'Selected Properties',
998
+ }),
999
+ ],
1000
+ },
1001
+ ],
1002
+ }));
1003
+ constructor() {
1004
+ effect(() => {
1005
+ if (!this.lookups().length) {
1006
+ this.propertiesFacade.loadLookups();
1007
+ }
1008
+ });
1009
+ effect(() => {
1010
+ if (!this.logs().length) {
1011
+ this.propertiesFacade.loadLogs();
1012
+ }
1013
+ });
1014
+ effect(() => {
1015
+ const logId = this.configuration()?.log;
1016
+ if (logId) {
1017
+ if (this.prevLogId() == logId) {
1018
+ return;
1019
+ }
1020
+ this.prevLogId.set(logId);
1021
+ this.propertiesFacade.loadPropertiesForConfigType('Log', logId);
1022
+ }
1023
+ });
1024
+ }
1025
+ ngOnDestroy() {
1026
+ this.propertiesFacade.resetConfigProperties();
1027
+ }
1028
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: CheckListFormConfiguration, deps: [], target: i0.ɵɵFactoryTarget.Component });
1029
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.3", type: CheckListFormConfiguration, isStandalone: true, selector: "mt-check-list-form-configuration", ngImport: i0, template: "<mt-dynamic-form formControlName=\"configuration\" [formConfig]=\"formConfig()\" />\n", styles: [""], dependencies: [{ kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }], viewProviders: [
1030
+ { provide: ControlContainer, useExisting: FormGroupDirective },
1031
+ ] });
1032
+ }
1033
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: CheckListFormConfiguration, decorators: [{
1034
+ type: Component,
1035
+ args: [{ selector: 'mt-check-list-form-configuration', imports: [DynamicForm, ReactiveFormsModule], viewProviders: [
1036
+ { provide: ControlContainer, useExisting: FormGroupDirective },
1037
+ ], template: "<mt-dynamic-form formControlName=\"configuration\" [formConfig]=\"formConfig()\" />\n" }]
1038
+ }], ctorParameters: () => [] });
1039
+
1040
+ class DynamicListConfiguration {
1041
+ propertiesFacade = inject(PropertiesFacade);
1042
+ controlContainer = inject(ControlContainer);
1043
+ parentGroup = this.controlContainer.control;
1044
+ logs = this.propertiesFacade.logs;
1045
+ configProperties = this.propertiesFacade.configProperties;
1046
+ prevLogId = signal(null, ...(ngDevMode ? [{ debugName: "prevLogId" }] : []));
1047
+ configuration = toSignal(this.parentGroup.valueChanges.pipe(startWith(this.parentGroup.value), map((value) => value?.configuration), distinctUntilChanged()), { initialValue: this.parentGroup.value?.configuration });
1048
+ formConfig = linkedSignal(() => ({
1049
+ sections: [
1050
+ {
1051
+ key: 'configuration',
1052
+ label: 'Configuration',
1053
+ cssClass: ' rounded-xl bg-white \
1054
+ shadow-sm \
1055
+ px-6 py-4',
1056
+ type: 'header',
1057
+ bodyClass: 'grid grid-cols-1 md:grid-cols-2 gap-3',
1058
+ fields: [
1059
+ {
1060
+ key: 'logId',
1061
+ type: 'select',
1062
+ label: 'Select Log',
1063
+ optionLabel: 'name',
1064
+ optionValue: 'id',
1065
+ options: this.logs(),
1066
+ },
1067
+ new PickListFieldConfig({
1068
+ key: 'properties',
1069
+ cssClass: 'md:col-span-2',
1070
+ options: this.configProperties(),
1071
+ optionLabel: 'name',
1072
+ optionValue: 'key',
1073
+ sourceHeader: 'Available Properties',
1074
+ targetHeader: 'Selected Properties',
1075
+ }),
1076
+ {
1077
+ key: 'mapToActual',
1078
+ type: 'toggle',
1079
+ label: 'Map To Actual',
1080
+ cssClass: 'md:col-span-2',
1081
+ },
1082
+ ],
1083
+ },
1084
+ ],
1085
+ }));
1086
+ constructor() {
1087
+ effect(() => {
1088
+ if (!this.logs().length) {
1089
+ this.propertiesFacade.loadLogs();
1090
+ }
1091
+ });
1092
+ effect(() => {
1093
+ const logId = this.configuration()?.logId;
1094
+ if (logId) {
1095
+ if (this.prevLogId() == logId) {
1096
+ return;
1097
+ }
1098
+ this.prevLogId.set(logId);
1099
+ this.propertiesFacade.loadPropertiesForConfigType('Log', logId);
1100
+ }
1101
+ });
1102
+ }
1103
+ ngOnDestroy() {
1104
+ this.propertiesFacade.resetConfigProperties();
1105
+ }
1106
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: DynamicListConfiguration, deps: [], target: i0.ɵɵFactoryTarget.Component });
1107
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.3", type: DynamicListConfiguration, isStandalone: true, selector: "mt-dynamic-list-configuration", ngImport: i0, template: "<mt-dynamic-form formControlName=\"configuration\" [formConfig]=\"formConfig()\" />\n", styles: [""], dependencies: [{ kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }], viewProviders: [
1108
+ { provide: ControlContainer, useExisting: FormGroupDirective },
1109
+ ] });
1110
+ }
1111
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: DynamicListConfiguration, decorators: [{
1112
+ type: Component,
1113
+ args: [{ selector: 'mt-dynamic-list-configuration', imports: [DynamicForm, ReactiveFormsModule], viewProviders: [
1114
+ { provide: ControlContainer, useExisting: FormGroupDirective },
1115
+ ], template: "<mt-dynamic-form formControlName=\"configuration\" [formConfig]=\"formConfig()\" />\n" }]
1116
+ }], ctorParameters: () => [] });
1117
+
1118
+ class EditableListViewConfiguration {
1119
+ propertiesFacade = inject(PropertiesFacade);
1120
+ controlContainer = inject(ControlContainer);
1121
+ parentGroup = this.controlContainer.control;
1122
+ logs = this.propertiesFacade.logs;
1123
+ configProperties = this.propertiesFacade.configProperties;
1124
+ prevLogId = signal(null, ...(ngDevMode ? [{ debugName: "prevLogId" }] : []));
1125
+ configuration = toSignal(this.parentGroup.valueChanges.pipe(startWith(this.parentGroup.value), map((value) => value?.configuration), distinctUntilChanged()), { initialValue: this.parentGroup.value?.configuration });
1126
+ formConfig = linkedSignal(() => ({
1127
+ sections: [
1128
+ {
1129
+ key: 'configuration',
1130
+ label: 'Configuration',
1131
+ cssClass: ' rounded-xl bg-white \
1132
+ shadow-sm \
1133
+ px-6 py-4',
1134
+ type: 'header',
1135
+ bodyClass: 'grid grid-cols-1 md:grid-cols-2 gap-3',
1136
+ fields: [
1137
+ {
1138
+ key: 'logId',
1139
+ type: 'select',
1140
+ label: 'Select Log',
1141
+ optionLabel: 'name',
1142
+ optionValue: 'id',
1143
+ options: this.logs(),
1144
+ },
1145
+ new PickListFieldConfig({
1146
+ key: 'Properties',
1147
+ cssClass: 'md:col-span-2',
1148
+ options: this.configProperties(),
1149
+ optionLabel: 'name',
1150
+ optionValue: 'key',
1151
+ sourceHeader: 'Available Properties',
1152
+ targetHeader: 'Selected Properties',
1153
+ }),
1154
+ {
1155
+ key: 'isEditable',
1156
+ type: 'toggle',
1157
+ label: 'Is Editable',
1158
+ },
1159
+ {
1160
+ key: 'preserveValue',
1161
+ type: 'toggle',
1162
+ label: 'Preserve Value',
1163
+ },
1164
+ ],
1165
+ },
1166
+ ],
1167
+ }));
1168
+ constructor() {
1169
+ effect(() => {
1170
+ if (!this.logs().length) {
1171
+ this.propertiesFacade.loadLogs();
1172
+ }
1173
+ });
1174
+ effect(() => {
1175
+ const logId = this.configuration()?.logId;
1176
+ if (logId) {
1177
+ if (this.prevLogId() == logId) {
1178
+ return;
1179
+ }
1180
+ this.prevLogId.set(logId);
1181
+ this.propertiesFacade.loadPropertiesForConfigType('Log', logId);
1182
+ }
1183
+ });
1184
+ }
1185
+ ngOnDestroy() {
1186
+ this.propertiesFacade.resetConfigProperties();
1187
+ }
1188
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: EditableListViewConfiguration, deps: [], target: i0.ɵɵFactoryTarget.Component });
1189
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.3", type: EditableListViewConfiguration, isStandalone: true, selector: "mt-editable-list-view-configuration", ngImport: i0, template: "<mt-dynamic-form formControlName=\"configuration\" [formConfig]=\"formConfig()\" />\n", styles: [""], dependencies: [{ kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }], viewProviders: [
1190
+ { provide: ControlContainer, useExisting: FormGroupDirective },
1191
+ ] });
1192
+ }
1193
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: EditableListViewConfiguration, decorators: [{
1194
+ type: Component,
1195
+ args: [{ selector: 'mt-editable-list-view-configuration', imports: [DynamicForm, ReactiveFormsModule], viewProviders: [
1196
+ { provide: ControlContainer, useExisting: FormGroupDirective },
1197
+ ], template: "<mt-dynamic-form formControlName=\"configuration\" [formConfig]=\"formConfig()\" />\n" }]
1198
+ }], ctorParameters: () => [] });
1199
+
1200
+ class InternalModuleConfiguration {
1201
+ // private readonly workspaceStructureFacade = inject(WorkspaceStructureFacade);
1202
+ // = this.workspaceStructureFacade.workspaceNodes;
1203
+ levels;
1204
+ propertiesFacade = inject(PropertiesFacade);
1205
+ cc = inject(ControlContainer);
1206
+ parentGroup = this.cc.control;
1207
+ configProperties = this.propertiesFacade.configProperties;
1208
+ logs = this.propertiesFacade.logs;
1209
+ configuration = toSignal(this.parentGroup.valueChanges.pipe(startWith(this.parentGroup.value), map((v) => v?.configuration), distinctUntilChanged()), { initialValue: this.parentGroup.value?.configuration });
1210
+ PrevModuleId = signal(null, ...(ngDevMode ? [{ debugName: "PrevModuleId" }] : []));
1211
+ formConfig = linkedSignal(() => ({
1212
+ sections: [
1213
+ {
1214
+ key: 'configuration',
1215
+ label: 'Configuration',
1216
+ cssClass: ' rounded-xl bg-white \
1217
+ shadow-sm \
1218
+ px-6 py-4',
1219
+ type: 'header',
1220
+ bodyClass: 'grid grid-cols-1 md:grid-cols-2 gap-3 align-items-end ',
1221
+ fields: [
1222
+ {
1223
+ key: 'type',
1224
+ type: 'select',
1225
+ label: 'Type',
1226
+ optionLabel: 'label',
1227
+ optionValue: 'value',
1228
+ options: [
1229
+ { label: 'Level', value: 'Level' },
1230
+ { label: 'Log', value: 'Log' },
1231
+ ],
1232
+ },
1233
+ {
1234
+ key: 'levelId',
1235
+ type: 'select',
1236
+ hidden: true,
1237
+ label: 'Select Level',
1238
+ optionLabel: 'name.en',
1239
+ optionValue: 'id',
1240
+ options: this.levels(),
1241
+ relations: [
1242
+ {
1243
+ key: 'type',
1244
+ value: 'Level',
1245
+ action: 'show',
1246
+ },
1247
+ ],
1248
+ },
1249
+ {
1250
+ key: 'logId',
1251
+ type: 'select',
1252
+ hidden: true,
1253
+ label: 'Select Log',
1254
+ optionLabel: 'name',
1255
+ optionValue: 'id',
1256
+ options: this.logs(),
1257
+ relations: [
1258
+ {
1259
+ key: 'type',
1260
+ value: 'Log',
1261
+ action: 'show',
1262
+ },
1263
+ ],
1264
+ },
1265
+ {
1266
+ type: 'select',
1267
+ key: 'property',
1268
+ label: 'Value Property',
1269
+ optionLabel: 'name',
1270
+ optionValue: 'key',
1271
+ options: this.configProperties(),
1272
+ },
1273
+ new PickListFieldConfig({
1274
+ cssClass: 'md:col-span-2 mt-2',
1275
+ key: 'propertyDetails',
1276
+ options: this.configProperties(),
1277
+ optionLabel: 'name',
1278
+ optionValue: 'key',
1279
+ sourceHeader: 'Available Properties',
1280
+ targetHeader: 'Selected Properties',
1281
+ }),
1282
+ {
1283
+ cssClass: 'md:col-span-2',
1284
+ key: 'preserveValue',
1285
+ type: 'toggle',
1286
+ label: 'Preserve Value',
1287
+ },
1288
+ ],
1289
+ },
1290
+ ],
1291
+ }));
1292
+ constructor() {
1293
+ effect(() => {
1294
+ if (this.configuration()?.type === 'Log') {
1295
+ if (!this.logs().length) {
1296
+ this.propertiesFacade.loadLogs();
1297
+ }
1298
+ this.parentGroup.get('levelId')?.setValue(null);
1299
+ }
1300
+ else if (this.configuration()?.type === 'Level') {
1301
+ this.parentGroup.get('logId')?.setValue(null);
1302
+ }
1303
+ if (this.configuration()?.logId || this.configuration()?.levelId) {
1304
+ const moduleType = this.configuration()?.type;
1305
+ const moduleId = moduleType === 'Log'
1306
+ ? this.configuration()?.logId
1307
+ : this.configuration()?.levelId;
1308
+ if (moduleId == this.PrevModuleId()) {
1309
+ return;
1310
+ }
1311
+ if (moduleType && moduleId) {
1312
+ this.PrevModuleId.set(moduleId);
1313
+ this.propertiesFacade.loadPropertiesForConfigType(moduleType, moduleId);
1314
+ }
1315
+ }
1316
+ });
1317
+ }
1318
+ ngOnDestroy() {
1319
+ this.propertiesFacade.resetConfigProperties();
1320
+ }
1321
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: InternalModuleConfiguration, deps: [], target: i0.ɵɵFactoryTarget.Component });
1322
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.3", type: InternalModuleConfiguration, isStandalone: true, selector: "mt-internal-module-configuration", ngImport: i0, template: "<mt-dynamic-form formControlName=\"configuration\" [formConfig]=\"formConfig()\" />\n", styles: [""], dependencies: [{ kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }], viewProviders: [
1323
+ { provide: ControlContainer, useExisting: FormGroupDirective },
1324
+ ] });
1325
+ }
1326
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: InternalModuleConfiguration, decorators: [{
1327
+ type: Component,
1328
+ args: [{ selector: 'mt-internal-module-configuration', imports: [DynamicForm, ReactiveFormsModule], viewProviders: [
1329
+ { provide: ControlContainer, useExisting: FormGroupDirective },
1330
+ ], template: "<mt-dynamic-form formControlName=\"configuration\" [formConfig]=\"formConfig()\" />\n" }]
1331
+ }], ctorParameters: () => [] });
1332
+
1333
+ class LocationConfiguration {
1334
+ facade = inject(PropertiesFacade);
1335
+ countries = this.facade.countries;
1336
+ formConfig = computed(() => ({
1337
+ sections: [
1338
+ {
1339
+ key: 'configuration',
1340
+ label: 'Configuration',
1341
+ cssClass: ' rounded-xl bg-white \
1342
+ shadow-sm \
1343
+ px-6 py-4',
1344
+ type: 'header',
1345
+ bodyClass: 'grid grid-cols-1 md:grid-cols-[minmax(0,1fr)_minmax(0,1fr)] gap-3',
1346
+ fields: [
1347
+ {
1348
+ key: 'country',
1349
+ type: 'select',
1350
+ label: 'Select Country',
1351
+ optionLabel: 'name',
1352
+ optionValue: 'name',
1353
+ options: this.countries(),
1354
+ },
1355
+ ],
1356
+ },
1357
+ ],
1358
+ }), ...(ngDevMode ? [{ debugName: "formConfig" }] : []));
1359
+ constructor() {
1360
+ effect(() => {
1361
+ if (!this.countries().length) {
1362
+ this.facade.loadCountries();
1363
+ }
1364
+ });
1365
+ }
1366
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: LocationConfiguration, deps: [], target: i0.ɵɵFactoryTarget.Component });
1367
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.3", type: LocationConfiguration, isStandalone: true, selector: "mt-location-configuration", ngImport: i0, template: "<mt-dynamic-form formControlName=\"configuration\" [formConfig]=\"formConfig()\" />\n", styles: [""], dependencies: [{ kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }], viewProviders: [
1368
+ { provide: ControlContainer, useExisting: FormGroupDirective },
1369
+ ] });
1370
+ }
1371
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: LocationConfiguration, decorators: [{
1372
+ type: Component,
1373
+ args: [{ selector: 'mt-location-configuration', imports: [DynamicForm, ReactiveFormsModule], viewProviders: [
1374
+ { provide: ControlContainer, useExisting: FormGroupDirective },
1375
+ ], template: "<mt-dynamic-form formControlName=\"configuration\" [formConfig]=\"formConfig()\" />\n" }]
1376
+ }], ctorParameters: () => [] });
1377
+
1378
+ class LookupConfiguration {
1379
+ facade = inject(PropertiesFacade);
1380
+ lookups = this.facade.lookups;
1381
+ formConfig = computed(() => ({
1382
+ sections: [
1383
+ {
1384
+ key: 'configuration',
1385
+ label: 'Configuration',
1386
+ cssClass: ' rounded-xl bg-white \
1387
+ shadow-sm \
1388
+ px-6 py-4',
1389
+ type: 'header',
1390
+ bodyClass: 'grid grid-cols-1 md:grid-cols-[minmax(0,1fr)_minmax(0,1fr)] gap-3',
1391
+ fields: [
1392
+ {
1393
+ key: 'lookup',
1394
+ type: 'select',
1395
+ label: 'Select Lookup',
1396
+ optionLabel: 'displayName',
1397
+ optionValue: 'id',
1398
+ options: this.lookups(),
1399
+ },
1400
+ ],
1401
+ },
1402
+ ],
1403
+ }), ...(ngDevMode ? [{ debugName: "formConfig" }] : []));
1404
+ constructor() {
1405
+ effect(() => {
1406
+ if (!this.lookups().length) {
1407
+ this.facade.loadLookups();
1408
+ }
1409
+ });
1410
+ }
1411
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: LookupConfiguration, deps: [], target: i0.ɵɵFactoryTarget.Component });
1412
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.3", type: LookupConfiguration, isStandalone: true, selector: "mt-lookup-configuration", ngImport: i0, template: "<mt-dynamic-form formControlName=\"configuration\" [formConfig]=\"formConfig()\" />\n", styles: [""], dependencies: [{ kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }], viewProviders: [
1413
+ { provide: ControlContainer, useExisting: FormGroupDirective },
1414
+ ] });
1415
+ }
1416
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: LookupConfiguration, decorators: [{
1417
+ type: Component,
1418
+ args: [{ selector: 'mt-lookup-configuration', imports: [DynamicForm, ReactiveFormsModule], viewProviders: [
1419
+ { provide: ControlContainer, useExisting: FormGroupDirective },
1420
+ ], template: "<mt-dynamic-form formControlName=\"configuration\" [formConfig]=\"formConfig()\" />\n" }]
1421
+ }], ctorParameters: () => [] });
1422
+
1423
+ class PercentageConfiguration {
1424
+ formConfig = signal({
1425
+ sections: [
1426
+ {
1427
+ key: 'configuration',
1428
+ label: 'Configuration',
1429
+ cssClass: ' rounded-xl bg-white \
1430
+ shadow-sm \
1431
+ px-6 py-4',
1432
+ type: 'header',
1433
+ bodyClass: 'grid grid-cols-1 md:grid-cols-[minmax(0,1fr)_minmax(0,1fr)] gap-3',
1434
+ fields: [
1435
+ {
1436
+ key: 'color',
1437
+ type: 'color-picker',
1438
+ label: 'Select Color',
1439
+ },
1440
+ ],
1441
+ },
1442
+ ],
1443
+ }, ...(ngDevMode ? [{ debugName: "formConfig" }] : []));
1444
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: PercentageConfiguration, deps: [], target: i0.ɵɵFactoryTarget.Component });
1445
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.3", type: PercentageConfiguration, isStandalone: true, selector: "mt-percentage-configuration", ngImport: i0, template: "<mt-dynamic-form formControlName=\"configuration\" [formConfig]=\"formConfig()\" />\n", styles: [""], dependencies: [{ kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }], viewProviders: [
1446
+ { provide: ControlContainer, useExisting: FormGroupDirective },
1447
+ ] });
1448
+ }
1449
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: PercentageConfiguration, decorators: [{
1450
+ type: Component,
1451
+ args: [{ selector: 'mt-percentage-configuration', imports: [DynamicForm, ReactiveFormsModule], viewProviders: [
1452
+ { provide: ControlContainer, useExisting: FormGroupDirective },
1453
+ ], template: "<mt-dynamic-form formControlName=\"configuration\" [formConfig]=\"formConfig()\" />\n" }]
1454
+ }] });
1455
+
1456
+ class UserConfiguration {
1457
+ facade = inject(PropertiesFacade);
1458
+ groups = this.facade.groups;
1459
+ formConfig = computed(() => ({
1460
+ sections: [
1461
+ {
1462
+ key: 'configuration',
1463
+ label: 'Configuration',
1464
+ cssClass: ' rounded-xl bg-white \
1465
+ shadow-sm \
1466
+ px-6 py-4',
1467
+ type: 'header',
1468
+ bodyClass: 'grid grid-cols-1 md:grid-cols-[minmax(0,1fr)_minmax(0,1fr)] gap-3',
1469
+ fields: [
1470
+ {
1471
+ key: 'group',
1472
+ type: 'select',
1473
+ label: 'Select Group',
1474
+ optionLabel: 'name',
1475
+ optionValue: 'id',
1476
+ options: this.groups(),
1477
+ },
1478
+ ],
1479
+ },
1480
+ ],
1481
+ }), ...(ngDevMode ? [{ debugName: "formConfig" }] : []));
1482
+ constructor() {
1483
+ effect(() => {
1484
+ if (!this.groups().length) {
1485
+ this.facade.loadGroups();
1486
+ }
1487
+ });
1488
+ }
1489
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: UserConfiguration, deps: [], target: i0.ɵɵFactoryTarget.Component });
1490
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.3", type: UserConfiguration, isStandalone: true, selector: "mt-user-configuration", ngImport: i0, template: "<mt-dynamic-form formControlName=\"configuration\" [formConfig]=\"formConfig()\" />\n", styles: [""], dependencies: [{ kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }], viewProviders: [
1491
+ { provide: ControlContainer, useExisting: FormGroupDirective },
1492
+ ] });
1493
+ }
1494
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: UserConfiguration, decorators: [{
1495
+ type: Component,
1496
+ args: [{ selector: 'mt-user-configuration', imports: [DynamicForm, ReactiveFormsModule], viewProviders: [
1497
+ { provide: ControlContainer, useExisting: FormGroupDirective },
1498
+ ], template: "<mt-dynamic-form formControlName=\"configuration\" [formConfig]=\"formConfig()\" />\n" }]
1499
+ }], ctorParameters: () => [] });
1500
+
1501
+ const ATTACHMENT_ACCEPT = [
1502
+ {
1503
+ key: 'image/*',
1504
+ name: 'image',
1505
+ },
1506
+ {
1507
+ key: 'application/pdf',
1508
+ name: 'pdf',
1509
+ },
1510
+ {
1511
+ key: '.mpp',
1512
+ name: 'mpp',
1513
+ },
1514
+ {
1515
+ key: '.xer',
1516
+ name: 'xer',
1517
+ },
1518
+ {
1519
+ key: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
1520
+ name: 'word',
1521
+ },
1522
+ {
1523
+ key: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
1524
+ name: 'excel',
1525
+ },
1526
+ {
1527
+ key: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
1528
+ name: 'powrpoint',
1529
+ },
1530
+ {
1531
+ key: '.eml',
1532
+ name: 'eml',
1533
+ },
1534
+ {
1535
+ key: '.doc',
1536
+ name: 'doc',
1537
+ },
1538
+ {
1539
+ key: '.docx',
1540
+ name: 'docx',
1541
+ },
1542
+ {
1543
+ key: '.ppt',
1544
+ name: 'ppt',
1545
+ },
1546
+ {
1547
+ key: '.pptx',
1548
+ name: 'pptx',
1549
+ },
1550
+ {
1551
+ key: '.xls',
1552
+ name: 'xls',
1553
+ },
1554
+ {
1555
+ key: '.xlsx',
1556
+ name: 'xlsx',
1557
+ },
1558
+ {
1559
+ key: '.csv',
1560
+ name: 'csv',
1561
+ },
1562
+ {
1563
+ key: '.mp4',
1564
+ name: 'mp4',
1565
+ },
1566
+ {
1567
+ key: '.mov',
1568
+ name: 'mov',
1569
+ },
1570
+ {
1571
+ key: '.wmv',
1572
+ name: 'wmv',
1573
+ },
1574
+ {
1575
+ key: '.avi',
1576
+ name: 'avi',
1577
+ },
1578
+ {
1579
+ key: '.mkv',
1580
+ name: 'mkv',
1581
+ },
1582
+ {
1583
+ key: '.msg',
1584
+ name: 'msg',
1585
+ },
1586
+ {
1587
+ key: '.zip',
1588
+ name: 'zip',
1589
+ },
1590
+ {
1591
+ key: '.rar',
1592
+ name: 'rar',
1593
+ },
1594
+ {
1595
+ key: '.7z',
1596
+ name: '7z',
1597
+ },
1598
+ {
1599
+ key: '.gz',
1600
+ name: 'gz',
1601
+ },
1602
+ {
1603
+ key: '.gzip',
1604
+ name: 'gzip',
1605
+ },
1606
+ {
1607
+ key: '.gzip',
1608
+ name: 'gzip',
1609
+ },
1610
+ ];
1611
+ class AttachmentConfiguration {
1612
+ formConfig = signal({
1613
+ sections: [
1614
+ {
1615
+ key: 'configuration',
1616
+ label: 'Configuration',
1617
+ cssClass: ' rounded-xl bg-white \
1618
+ shadow-sm \
1619
+ px-6 py-4',
1620
+ type: 'header',
1621
+ bodyClass: 'grid grid-cols-1 md:grid-cols-2 gap-3',
1622
+ fields: [
1623
+ new PickListFieldConfig({
1624
+ key: 'AcceptTypes',
1625
+ options: ATTACHMENT_ACCEPT,
1626
+ optionLabel: 'name',
1627
+ optionValue: 'key',
1628
+ sourceHeader: 'Available Types',
1629
+ targetHeader: 'Selected Types',
1630
+ cssClass: 'md:col-span-2',
1631
+ }),
1632
+ {
1633
+ key: 'IsMulitple',
1634
+ type: 'toggle',
1635
+ label: 'Allow Multiple Files',
1636
+ },
1637
+ ],
1638
+ },
1639
+ ],
1640
+ }, ...(ngDevMode ? [{ debugName: "formConfig" }] : []));
1641
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AttachmentConfiguration, deps: [], target: i0.ɵɵFactoryTarget.Component });
1642
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.3", type: AttachmentConfiguration, isStandalone: true, selector: "mt-attachment-configuration", ngImport: i0, template: "<mt-dynamic-form formControlName=\"configuration\" [formConfig]=\"formConfig()\" />\n", styles: [""], dependencies: [{ kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }], viewProviders: [
1643
+ { provide: ControlContainer, useExisting: FormGroupDirective },
1644
+ ] });
1645
+ }
1646
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: AttachmentConfiguration, decorators: [{
1647
+ type: Component,
1648
+ args: [{ selector: 'mt-attachment-configuration', imports: [DynamicForm, ReactiveFormsModule], viewProviders: [
1649
+ { provide: ControlContainer, useExisting: FormGroupDirective },
1650
+ ], template: "<mt-dynamic-form formControlName=\"configuration\" [formConfig]=\"formConfig()\" />\n" }]
1651
+ }] });
1652
+
1653
+ class PropertyForm {
1654
+ facade = inject(PropertiesFacade);
1655
+ router = inject(Router);
1656
+ route = inject(ActivatedRoute);
1657
+ propertyId = input('', ...(ngDevMode ? [{ debugName: "propertyId" }] : []));
1658
+ propertyTypes = this.facade.propertyTypes;
1659
+ submitLabel = computed(() => (this.propertyId() ? 'Update' : 'Create'), ...(ngDevMode ? [{ debugName: "submitLabel" }] : []));
1660
+ isEditing = computed(() => !!this.propertyId(), ...(ngDevMode ? [{ debugName: "isEditing" }] : []));
1661
+ // Keep your original structure: "main" is a FormControl<any>, "configuration" is FormControl<any|null>
1662
+ propertyForm = new FormGroup({
1663
+ main: new FormControl({
1664
+ isCalculated: false,
1665
+ viewType: null,
1666
+ name: { ar: '', en: '' },
1667
+ description: '',
1668
+ }),
1669
+ configuration: new FormControl(null),
1670
+ });
1671
+ mainControl = this.propertyForm.get('main');
1672
+ configurationControl = this.propertyForm.get('configuration');
1673
+ creating = this.facade.isLoading('create');
1674
+ updating = this.facade.isLoading('update');
1675
+ submitting = computed(() => this.creating() || this.updating(), ...(ngDevMode ? [{ debugName: "submitting" }] : []));
1676
+ propertyType = toSignal(this.mainControl.valueChanges.pipe(startWith(this.mainControl.value), map((v) => v?.viewType), distinctUntilChanged()), { initialValue: this.mainControl.value?.viewType });
1677
+ selectedPropertyTypeConfiguration = computed(() => {
1678
+ const propertyTypesSetting = this.propertyTypes();
1679
+ const selectedViewType = this.propertyType();
1680
+ if (!propertyTypesSetting?.value || !selectedViewType)
1681
+ return null;
1682
+ // PropertyTypeSetting
1683
+ const match = propertyTypesSetting.value.find((item) => item.viewType?.toLowerCase() === selectedViewType.toLowerCase());
1684
+ return match?.configuration ?? null;
1685
+ }, ...(ngDevMode ? [{ debugName: "selectedPropertyTypeConfiguration" }] : []));
1686
+ configurationFormConfig = computed(() => this.selectedPropertyTypeConfiguration()?.configurationForm ?? null, ...(ngDevMode ? [{ debugName: "configurationFormConfig" }] : []));
1687
+ configurationHost;
1688
+ environmentInjector = inject(EnvironmentInjector);
1689
+ configurationComponentType = signal(null, ...(ngDevMode ? [{ debugName: "configurationComponentType" }] : []));
1690
+ configurationComponentRef = null;
1691
+ configurationComponentLoadId = 0;
1692
+ externalConfigurationForm = signal(null, ...(ngDevMode ? [{ debugName: "externalConfigurationForm" }] : []));
1693
+ externalConfigurationSubscriptions = null;
1694
+ externalConfigurationInvalid = signal(false, ...(ngDevMode ? [{ debugName: "externalConfigurationInvalid" }] : []));
1695
+ viewReady = signal(false, ...(ngDevMode ? [{ debugName: "viewReady" }] : []));
1696
+ configurationComponentExists = computed(() => !!this.configurationComponentType(), ...(ngDevMode ? [{ debugName: "configurationComponentExists" }] : []));
1697
+ configurationFormInvalid = computed(() => this.externalConfigurationInvalid(), ...(ngDevMode ? [{ debugName: "configurationFormInvalid" }] : []));
1698
+ submitDisabled = computed(() => this.submitting() || this.configurationFormInvalid(), ...(ngDevMode ? [{ debugName: "submitDisabled" }] : []));
1699
+ // Your existing dynamic form config unchanged
1700
+ dynamicFormConfigMain = linkedSignal(() => ({
1701
+ layout: {
1702
+ containerClass: `space-y-2`,
1703
+ },
1704
+ sections: [
1705
+ {
1706
+ key: 'top-row',
1707
+ type: 'none',
1708
+ cssClass: ' rounded-xl bg-white shadow-sm px-6 py-4',
1709
+ bodyClass: 'grid grid-cols-1 md:grid-cols-[minmax(0,1fr)_auto] items-center gap-6',
1710
+ fields: [
1711
+ {
1712
+ key: 'viewType',
1713
+ type: 'select',
1714
+ placeholder: 'Select Property Type',
1715
+ optionLabel: 'label.en',
1716
+ optionValue: 'viewType',
1717
+ options: this.propertyTypes()?.value,
1718
+ },
1719
+ {
1720
+ key: 'isCalculated',
1721
+ type: 'toggle',
1722
+ label: 'Calculated',
1723
+ cssClass: 'md:justify-self-end',
1724
+ },
1725
+ ],
1726
+ },
1727
+ {
1728
+ key: 'default-info',
1729
+ label: 'Default Information',
1730
+ type: 'header',
1731
+ cssClass: ' rounded-xl bg-white shadow-sm px-6 py-4',
1732
+ bodyClass: 'grid grid-cols-1 md:grid-cols-2 gap-3',
1733
+ fields: [
1734
+ {
1735
+ key: 'name.ar',
1736
+ label: 'Name-AR',
1737
+ placeholder: 'Name-Ar',
1738
+ validators: [new ValidatorConfig({ type: 'required' })],
1739
+ },
1740
+ {
1741
+ key: 'name.en',
1742
+ label: 'Name-En',
1743
+ placeholder: 'Name-En',
1744
+ validators: [new ValidatorConfig({ type: 'required' })],
1745
+ },
1746
+ {
1747
+ key: 'description',
1748
+ label: 'Description',
1749
+ type: 'textarea',
1750
+ cssClass: 'md:col-span-2',
1751
+ },
1752
+ {
1753
+ key: 'defaultValue',
1754
+ label: 'Default Value',
1755
+ cssClass: 'md:col-span-2',
1756
+ },
1757
+ ],
1758
+ },
1759
+ ],
1760
+ }));
1761
+ constructor() {
1762
+ // Load when editing
1763
+ effect(() => {
1764
+ if (this.propertyId()) {
1765
+ this.facade.loadOne(this.propertyId());
1766
+ }
1767
+ });
1768
+ effect(() => {
1769
+ const property = this.facade.selected();
1770
+ this.syncFormWithSelectedProperty(property);
1771
+ });
1772
+ effect(() => {
1773
+ const currentPropertyType = this.propertyType();
1774
+ if (currentPropertyType === undefined)
1775
+ return;
1776
+ this.configurationControl.reset(null, { emitEvent: false });
1777
+ }, { allowSignalWrites: true });
1778
+ effect(() => {
1779
+ this.resolveConfigurationComponent(this.selectedPropertyTypeConfiguration());
1780
+ });
1781
+ effect(() => {
1782
+ if (!this.viewReady())
1783
+ return;
1784
+ this.renderConfigurationComponent(this.configurationComponentType());
1785
+ });
1786
+ effect(() => {
1787
+ const form = this.externalConfigurationForm();
1788
+ if (!form)
1789
+ return;
1790
+ const value = this.configurationControl.value;
1791
+ if (value) {
1792
+ form.patchValue(value, { emitEvent: false });
1793
+ }
1794
+ else {
1795
+ form.reset({}, { emitEvent: false });
1796
+ }
1797
+ });
1798
+ }
1799
+ ngAfterViewInit() {
1800
+ this.viewReady.set(true);
1801
+ this.renderConfigurationComponent(this.configurationComponentType());
1802
+ }
1803
+ ngOnDestroy() {
1804
+ this.facade.resetSelectedProperty();
1805
+ this.destroyConfigurationComponent();
1806
+ }
1807
+ renderConfigurationComponent(componentType) {
1808
+ if (!this.configurationHost)
1809
+ return;
1810
+ this.destroyConfigurationComponent();
1811
+ if (!componentType)
1812
+ return;
1813
+ const componentRef = this.configurationHost.createComponent(componentType, {
1814
+ environmentInjector: this.environmentInjector,
1815
+ });
1816
+ this.configurationComponentRef = componentRef;
1817
+ this.connectExternalConfigurationForm(componentRef.instance);
1818
+ }
1819
+ destroyConfigurationComponent() {
1820
+ this.externalConfigurationSubscriptions?.unsubscribe();
1821
+ this.externalConfigurationSubscriptions = null;
1822
+ this.externalConfigurationForm.set(null);
1823
+ this.externalConfigurationInvalid.set(false);
1824
+ this.configurationComponentRef?.destroy();
1825
+ this.configurationComponentRef = null;
1826
+ this.configurationHost?.clear();
1827
+ }
1828
+ connectExternalConfigurationForm(instance) {
1829
+ const form = this.extractConfigurationForm(instance);
1830
+ if (!form)
1831
+ return;
1832
+ this.externalConfigurationForm.set(form);
1833
+ this.externalConfigurationInvalid.set(form.invalid);
1834
+ const currentValue = this.configurationControl.value;
1835
+ if (currentValue) {
1836
+ form.patchValue(currentValue, { emitEvent: false });
1837
+ }
1838
+ this.configurationControl.setValue(form.value ?? null, {
1839
+ emitEvent: false,
1840
+ });
1841
+ this.externalConfigurationSubscriptions = new Subscription();
1842
+ this.externalConfigurationSubscriptions.add(form.valueChanges.subscribe((value) => this.configurationControl.setValue(value, { emitEvent: false })));
1843
+ this.externalConfigurationSubscriptions.add(form.statusChanges.subscribe(() => this.externalConfigurationInvalid.set(form.invalid)));
1844
+ }
1845
+ extractConfigurationForm(instance) {
1846
+ const form = instance?.form;
1847
+ return form instanceof FormGroup ? form : null;
1848
+ }
1849
+ // PropertyTypeConfiguration
1850
+ resolveConfigurationComponent(configuration) {
1851
+ const componentLoader = configuration?.configurationComponent;
1852
+ const loadId = ++this.configurationComponentLoadId;
1853
+ if (!componentLoader) {
1854
+ this.configurationComponentType.set(null);
1855
+ return;
1856
+ }
1857
+ // Direct component type
1858
+ if (typeof componentLoader !== 'function' || componentLoader.prototype) {
1859
+ this.configurationComponentType.set(componentLoader);
1860
+ return;
1861
+ }
1862
+ // Async loader factory
1863
+ try {
1864
+ const result = componentLoader();
1865
+ this.applyConfigurationComponentResult(result, loadId);
1866
+ }
1867
+ catch (error) {
1868
+ console.error('Failed to resolve configuration component.', error);
1869
+ this.configurationComponentType.set(null);
1870
+ }
1871
+ }
1872
+ applyConfigurationComponentResult(result, loadId) {
1873
+ // Async promise result
1874
+ if (result instanceof Promise) {
1875
+ this.configurationComponentType.set(null);
1876
+ result
1877
+ .then((component) => {
1878
+ if (loadId !== this.configurationComponentLoadId)
1879
+ return;
1880
+ // Handle default export
1881
+ const resolved = component?.default ?? component;
1882
+ this.configurationComponentType.set(resolved);
1883
+ })
1884
+ .catch((error) => {
1885
+ if (loadId === this.configurationComponentLoadId) {
1886
+ this.configurationComponentType.set(null);
1887
+ }
1888
+ console.error('Unable to load configuration component.', error);
1889
+ });
1890
+ return;
1891
+ }
1892
+ // Direct component type
1893
+ this.configurationComponentType.set(result);
1894
+ }
1895
+ createOrEditProperty() {
1896
+ const mainValue = this.mainControl.value;
1897
+ if (!mainValue)
1898
+ return;
1899
+ const payload = {
1900
+ ...mainValue,
1901
+ Configuration: this.configurationControl.value ?? mainValue.Configuration ?? null,
1902
+ };
1903
+ const request$ = this.propertyId()
1904
+ ? this.facade.update(this.propertyId(), payload)
1905
+ : this.facade.create(payload);
1906
+ request$.subscribe(() => this.goBack());
1907
+ }
1908
+ goBack() {
1909
+ const path = this.isEditing()
1910
+ ? '../../properties-list'
1911
+ : '../properties-list';
1912
+ this.router.navigate([path], { relativeTo: this.route });
1913
+ }
1914
+ syncFormWithSelectedProperty(property) {
1915
+ if (!property)
1916
+ return;
1917
+ this.mainControl.patchValue(property, { emitEvent: true });
1918
+ this.configurationControl.setValue(property.Configuration ?? null, {
1919
+ emitEvent: false,
1920
+ });
1921
+ }
1922
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: PropertyForm, deps: [], target: i0.ɵɵFactoryTarget.Component });
1923
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.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-card class=\"h-full\">\n <ng-template #headless>\n <div class=\"flex justify-between items-center p-3 border-b border-surface\">\n <div class=\"flex gap-2 items-center\">\n <mt-button\n [text]=\"true\"\n icon=\"arrow.arrow-narrow-left\"\n size=\"large\"\n (click)=\"goBack()\"\n ></mt-button>\n <mt-avatar size=\"normal\" icon=\"custom.user-pp\" />\n <h3 class=\"font-bold text-lg\">\n {{ propertyId() ? \"Edit Property\" : \"Create New Property\" }}\n </h3>\n </div>\n <mt-button\n [label]=\"submitLabel()\"\n [loading]=\"submitting()\"\n [disabled]=\"submitDisabled() || this.propertyForm.invalid\"\n (click)=\"createOrEditProperty()\"\n />\n </div>\n <div\n [formGroup]=\"propertyForm\"\n class=\"h-full bg-[radial-gradient(120%_80%_at_100%_0%,_#EBEFFF_0%,_#F6F8FC_45%,_#F6F8FC_100%)] flex justify-center\"\n >\n <div class=\"w-2/3\">\n <mt-dynamic-form\n [formConfig]=\"dynamicFormConfigMain()\"\n [formControlName]=\"'main'\"\n />\n @if (configurationFormConfig()) {\n <mt-dynamic-form\n formControlName=\"configuration\"\n [formConfig]=\"configurationFormConfig()!\"\n />\n } @else {\n <ng-container #configurationHost></ng-container>\n @if (!configurationComponentExists()) {\n @switch (propertyType()) {\n @case (\"User\") {\n <mt-user-configuration />\n }\n @case (\"Percentage\") {\n <mt-percentage-configuration />\n }\n @case (\"Lookup\") {\n <mt-lookup-configuration />\n }\n @case (\"LookupMultiSelect\") {\n <mt-lookup-configuration />\n }\n @case (\"InternalModule\") {\n <mt-internal-module-configuration />\n }\n @case (\"DynamicList\") {\n <mt-dynamic-list-configuration />\n }\n @case (\"API\") {\n <mt-api-configuration formControlName=\"configuration\" />\n }\n <!-- @case('ViewList') { REMOVED FOR NOW\n <mt-view-list-configuration />\n } -->\n @case (\"Attachment\") {\n <mt-attachment-configuration />\n }\n <!-- @case('ReferenceProperty') { REMOVED FOR NOW\n } -->\n @case (\"EditableListView\") {\n <mt-editable-list-view-configuration />\n }\n @case (\"LookupLog\") {\n <mt-check-list-form-configuration />\n }\n <!-- @case('LookupMatrix') { REMOVED FOR NOW\n <mt-lookup-configuration />\n } -->\n @case (\"Location\") {\n <mt-location-configuration />\n }\n }\n }\n }\n </div>\n </div>\n </ng-template>\n</mt-card>\n", styles: [""], dependencies: [{ kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "component", type: Avatar, selector: "mt-avatar", inputs: ["label", "icon", "image", "size", "shape", "badge", "badgeSize", "badgeSeverity"], outputs: ["onImageError"] }, { 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: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { 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" }] });
1924
+ }
1925
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.3", ngImport: i0, type: PropertyForm, decorators: [{
1926
+ type: Component,
1927
+ args: [{ selector: 'mt-property-form', imports: [
1928
+ Card,
1929
+ Avatar,
1930
+ Button,
1931
+ DynamicForm,
1932
+ ReactiveFormsModule,
1933
+ ApiConfiguration,
1934
+ CheckListFormConfiguration,
1935
+ DynamicListConfiguration,
1936
+ EditableListViewConfiguration,
1937
+ InternalModuleConfiguration,
1938
+ LocationConfiguration,
1939
+ LookupConfiguration,
1940
+ PercentageConfiguration,
1941
+ UserConfiguration,
1942
+ AttachmentConfiguration,
1943
+ NgComponentOutlet,
1944
+ ], template: "<mt-card class=\"h-full\">\n <ng-template #headless>\n <div class=\"flex justify-between items-center p-3 border-b border-surface\">\n <div class=\"flex gap-2 items-center\">\n <mt-button\n [text]=\"true\"\n icon=\"arrow.arrow-narrow-left\"\n size=\"large\"\n (click)=\"goBack()\"\n ></mt-button>\n <mt-avatar size=\"normal\" icon=\"custom.user-pp\" />\n <h3 class=\"font-bold text-lg\">\n {{ propertyId() ? \"Edit Property\" : \"Create New Property\" }}\n </h3>\n </div>\n <mt-button\n [label]=\"submitLabel()\"\n [loading]=\"submitting()\"\n [disabled]=\"submitDisabled() || this.propertyForm.invalid\"\n (click)=\"createOrEditProperty()\"\n />\n </div>\n <div\n [formGroup]=\"propertyForm\"\n class=\"h-full bg-[radial-gradient(120%_80%_at_100%_0%,_#EBEFFF_0%,_#F6F8FC_45%,_#F6F8FC_100%)] flex justify-center\"\n >\n <div class=\"w-2/3\">\n <mt-dynamic-form\n [formConfig]=\"dynamicFormConfigMain()\"\n [formControlName]=\"'main'\"\n />\n @if (configurationFormConfig()) {\n <mt-dynamic-form\n formControlName=\"configuration\"\n [formConfig]=\"configurationFormConfig()!\"\n />\n } @else {\n <ng-container #configurationHost></ng-container>\n @if (!configurationComponentExists()) {\n @switch (propertyType()) {\n @case (\"User\") {\n <mt-user-configuration />\n }\n @case (\"Percentage\") {\n <mt-percentage-configuration />\n }\n @case (\"Lookup\") {\n <mt-lookup-configuration />\n }\n @case (\"LookupMultiSelect\") {\n <mt-lookup-configuration />\n }\n @case (\"InternalModule\") {\n <mt-internal-module-configuration />\n }\n @case (\"DynamicList\") {\n <mt-dynamic-list-configuration />\n }\n @case (\"API\") {\n <mt-api-configuration formControlName=\"configuration\" />\n }\n <!-- @case('ViewList') { REMOVED FOR NOW\n <mt-view-list-configuration />\n } -->\n @case (\"Attachment\") {\n <mt-attachment-configuration />\n }\n <!-- @case('ReferenceProperty') { REMOVED FOR NOW\n } -->\n @case (\"EditableListView\") {\n <mt-editable-list-view-configuration />\n }\n @case (\"LookupLog\") {\n <mt-check-list-form-configuration />\n }\n <!-- @case('LookupMatrix') { REMOVED FOR NOW\n <mt-lookup-configuration />\n } -->\n @case (\"Location\") {\n <mt-location-configuration />\n }\n }\n }\n }\n </div>\n </div>\n </ng-template>\n</mt-card>\n" }]
1945
+ }], ctorParameters: () => [], propDecorators: { configurationHost: [{
1946
+ type: ViewChild,
1947
+ args: ['configurationHost', { read: ViewContainerRef }]
1948
+ }] } });
1949
+
1950
+ /*
1951
+ * Public API Surface of structure-builder
1952
+ */
1953
+
1954
+ /**
1955
+ * Generated bundle index. Do not edit.
1956
+ */
1957
+
1958
+ export { CreateProperty, DeleteProperty, GetCountries, GetGroups, GetLogs, GetLookups, GetProperties, GetPropertiesForConfigType, GetProperty, PropertiesFacade, PropertiesState, REQUEST_CONTEXT, ResetApiConfiguration, ResetConfigProperties, ResetSelectedProperty, SetPropertiesModuleInfo, SetPropertyTypes, TestApiConfiguration, UpdateProperty };
1959
+ //# sourceMappingURL=masterteam-properties.mjs.map