@masterteam/properties 0.0.32 → 0.0.34

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.
@@ -1,31 +1,32 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, Injectable, computed, input, linkedSignal, signal, Component, DestroyRef, effect, forwardRef, ChangeDetectionStrategy, EnvironmentInjector, ViewContainerRef, ViewChild } from '@angular/core';
2
+ import { inject, Injectable, computed, input, linkedSignal, signal, Component, DestroyRef, effect, forwardRef, ChangeDetectionStrategy, viewChild, EnvironmentInjector, ViewContainerRef, ViewChild } from '@angular/core';
3
3
  import { CommonModule } from '@angular/common';
4
4
  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
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';
9
+ import { CrudStateBase, handleApiRequest, ValidatorConfig, PickListFieldConfig, ColorPickerFieldConfig, IconFieldConfig } from '@masterteam/components';
11
10
  import { Breadcrumb } from '@masterteam/components/breadcrumb';
12
11
  import { Card } from '@masterteam/components/card';
13
12
  import { Avatar } from '@masterteam/components/avatar';
14
13
  import { Divider } from 'primeng/divider';
15
14
  import { Button } from '@masterteam/components/button';
16
- import * as i1 from '@jsverse/transloco';
15
+ import * as i2 from '@jsverse/transloco';
17
16
  import { TranslocoService, TranslocoModule } from '@jsverse/transloco';
18
17
  import { toSignal } from '@angular/core/rxjs-interop';
19
18
  import { Page } from '@masterteam/components/page';
20
19
  import { DynamicForm } from '@masterteam/forms/dynamic-form';
21
- import * as i1$1 from '@angular/forms';
20
+ import * as i1 from '@angular/forms';
22
21
  import { FormGroup, FormControl, Validators, FormArray, ReactiveFormsModule, NG_VALUE_ACCESSOR, NG_VALIDATORS, ControlContainer, FormGroupDirective } from '@angular/forms';
23
- import * as i2 from 'primeng/skeleton';
22
+ import * as i2$1 from 'primeng/skeleton';
24
23
  import { SkeletonModule } from 'primeng/skeleton';
25
24
  import { FormulaBuilder } from '@masterteam/formula-builder';
26
25
  import { SelectField } from '@masterteam/components/select-field';
27
26
  import { TextField } from '@masterteam/components/text-field';
28
27
  import { ToggleField } from '@masterteam/components/toggle-field';
28
+ import { ModalService } from '@masterteam/components/modal';
29
+ import { ModalRef } from '@masterteam/components/dialog';
29
30
 
30
31
  var PropertiesActionKey;
31
32
  (function (PropertiesActionKey) {
@@ -40,6 +41,11 @@ var PropertiesActionKey;
40
41
  PropertiesActionKey["GetConfigAsType"] = "getConfigAsType";
41
42
  PropertiesActionKey["GetCountries"] = "getCountries";
42
43
  PropertiesActionKey["TestApiConfiguration"] = "testApiConfiguration";
44
+ PropertiesActionKey["GetPropertyStatuses"] = "getPropertyStatuses";
45
+ PropertiesActionKey["CreatePropertyStatus"] = "createPropertyStatus";
46
+ PropertiesActionKey["UpdatePropertyStatus"] = "updatePropertyStatus";
47
+ PropertiesActionKey["DeletePropertyStatus"] = "deletePropertyStatus";
48
+ PropertiesActionKey["ReorderPropertyStatuses"] = "reorderPropertyStatuses";
43
49
  })(PropertiesActionKey || (PropertiesActionKey = {}));
44
50
 
45
51
  class GetProperties {
@@ -84,6 +90,52 @@ class TestApiConfiguration {
84
90
  class ResetApiConfiguration {
85
91
  static type = '[Properties] Reset API Configuration';
86
92
  }
93
+ class GetPropertyStatuses {
94
+ propertyId;
95
+ static type = '[Properties] Get Property Statuses';
96
+ constructor(propertyId) {
97
+ this.propertyId = propertyId;
98
+ }
99
+ }
100
+ class CreatePropertyStatus {
101
+ propertyId;
102
+ payload;
103
+ static type = '[Properties] Create Property Status';
104
+ constructor(propertyId, payload) {
105
+ this.propertyId = propertyId;
106
+ this.payload = payload;
107
+ }
108
+ }
109
+ class UpdatePropertyStatus {
110
+ propertyId;
111
+ statusId;
112
+ payload;
113
+ static type = '[Properties] Update Property Status';
114
+ constructor(propertyId, statusId, payload) {
115
+ this.propertyId = propertyId;
116
+ this.statusId = statusId;
117
+ this.payload = payload;
118
+ }
119
+ }
120
+ class DeletePropertyStatus {
121
+ propertyId;
122
+ statusId;
123
+ static type = '[Properties] Delete Property Status';
124
+ constructor(propertyId, statusId) {
125
+ this.propertyId = propertyId;
126
+ this.statusId = statusId;
127
+ }
128
+ }
129
+ class ReorderPropertyStatuses {
130
+ payload;
131
+ static type = '[Properties] Reorder Property Statuses';
132
+ constructor(payload) {
133
+ this.payload = payload;
134
+ }
135
+ }
136
+ class ResetPropertyStatuses {
137
+ static type = '[Properties] Reset Property Statuses';
138
+ }
87
139
  class GetPropertiesForConfigType {
88
140
  moduleType;
89
141
  moduleId;
@@ -185,6 +237,7 @@ const DEFAULT_STATE = {
185
237
  countries: [],
186
238
  apiSchema: null,
187
239
  apiProperties: [],
240
+ propertyStatuses: [],
188
241
  breadcrumbItems: [],
189
242
  defaultViewType: null,
190
243
  };
@@ -196,7 +249,7 @@ let PropertiesState = class PropertiesState extends CrudStateBase {
196
249
  groupsUrl = 'identity/Groups';
197
250
  countriesUrl = '/assets/countries/countries.json';
198
251
  apiTestUrl = 'app/testAPI';
199
- apiDetectUrl = 'app/detect';
252
+ propertyStatusOrderUrl = 'Properties/Status/Order';
200
253
  // ============================================================================
201
254
  // Data Selectors - Individual for fine-grained reactivity
202
255
  // ============================================================================
@@ -233,6 +286,9 @@ let PropertiesState = class PropertiesState extends CrudStateBase {
233
286
  static apiProperties(state) {
234
287
  return state.apiProperties;
235
288
  }
289
+ static propertyStatuses(state) {
290
+ return state.propertyStatuses;
291
+ }
236
292
  static propertyTypes(state) {
237
293
  return state.propertyTypes ?? {};
238
294
  }
@@ -368,31 +424,97 @@ let PropertiesState = class PropertiesState extends CrudStateBase {
368
424
  apiSchema: null,
369
425
  apiProperties: [],
370
426
  });
371
- const req$ = this.http
372
- .post(this.apiTestUrl, action.payload)
373
- .pipe(switchMap((testResponse) => {
374
- const rawData = testResponse?.data;
375
- if (!rawData) {
376
- return of(null);
377
- }
378
- const formData = new FormData();
379
- formData.append('jsonData', JSON.stringify(rawData));
380
- return this.http
381
- .post(this.apiDetectUrl, formData)
382
- .pipe(tap((detectResponse) => {
383
- const schema = detectResponse?.data ?? null;
384
- const apiProperties = this.mapSchemaToOptions(schema);
385
- ctx.patchState({
386
- apiSchema: schema,
387
- apiProperties,
388
- });
389
- }));
390
- }));
427
+ const req$ = this.http.post(this.apiTestUrl, action.payload);
391
428
  return handleApiRequest({
392
429
  ctx,
393
430
  key: PropertiesActionKey.TestApiConfiguration,
394
431
  request$: req$,
395
- onSuccess: () => ({}),
432
+ onSuccess: (response) => {
433
+ const schema = this.buildSchemaFromRecord(response.data);
434
+ return {
435
+ apiSchema: schema,
436
+ apiProperties: this.mapSchemaToOptions(schema),
437
+ };
438
+ },
439
+ });
440
+ }
441
+ getPropertyStatuses(ctx, action) {
442
+ const req$ = this.http.get(`${this.baseUrl}/${action.propertyId}/Status`);
443
+ return handleApiRequest({
444
+ ctx,
445
+ key: PropertiesActionKey.GetPropertyStatuses,
446
+ request$: req$,
447
+ onSuccess: (response) => ({
448
+ propertyStatuses: Array.isArray(response.data) ? response.data : [],
449
+ }),
450
+ });
451
+ }
452
+ createPropertyStatus(ctx, action) {
453
+ const req$ = this.http.post(`${this.baseUrl}/${action.propertyId}/Status`, action.payload);
454
+ return handleApiRequest({
455
+ ctx,
456
+ key: PropertiesActionKey.CreatePropertyStatus,
457
+ request$: req$,
458
+ onSuccess: (response, state) => {
459
+ const created = response.data;
460
+ if (!created) {
461
+ return {};
462
+ }
463
+ return {
464
+ propertyStatuses: [...state.propertyStatuses, created],
465
+ };
466
+ },
467
+ });
468
+ }
469
+ updatePropertyStatus(ctx, action) {
470
+ const req$ = this.http.put(`${this.baseUrl}/${action.propertyId}/Status/${action.statusId}`, action.payload);
471
+ return handleApiRequest({
472
+ ctx,
473
+ key: PropertiesActionKey.UpdatePropertyStatus,
474
+ request$: req$,
475
+ onSuccess: (response, state) => {
476
+ const updated = response.data;
477
+ if (!updated) {
478
+ return {};
479
+ }
480
+ return {
481
+ propertyStatuses: state.propertyStatuses.map((status) => status.id === updated.id ? updated : status),
482
+ };
483
+ },
484
+ });
485
+ }
486
+ deletePropertyStatus(ctx, action) {
487
+ const req$ = this.http.delete(`${this.baseUrl}/${action.propertyId}/Status/${action.statusId}`);
488
+ return handleApiRequest({
489
+ ctx,
490
+ key: PropertiesActionKey.DeletePropertyStatus,
491
+ request$: req$,
492
+ onSuccess: (_, state) => ({
493
+ propertyStatuses: state.propertyStatuses.filter((status) => status.id !== Number(action.statusId)),
494
+ }),
495
+ });
496
+ }
497
+ reorderPropertyStatuses(ctx, action) {
498
+ const req$ = this.http.put(this.propertyStatusOrderUrl, action.payload);
499
+ return handleApiRequest({
500
+ ctx,
501
+ key: PropertiesActionKey.ReorderPropertyStatuses,
502
+ request$: req$,
503
+ onSuccess: (_, state) => {
504
+ const orderMap = new Map(action.payload.orders.map((item) => [item.statusId, item.order]));
505
+ return {
506
+ propertyStatuses: [...state.propertyStatuses]
507
+ .map((status) => ({
508
+ ...status,
509
+ order: orderMap.get(status.id) ?? status.order ?? null,
510
+ }))
511
+ .sort((left, right) => {
512
+ const leftOrder = left.order ?? Number.MAX_SAFE_INTEGER;
513
+ const rightOrder = right.order ?? Number.MAX_SAFE_INTEGER;
514
+ return leftOrder - rightOrder || left.id - right.id;
515
+ }),
516
+ };
517
+ },
396
518
  });
397
519
  }
398
520
  getPropertiesForConfigType(ctx, action) {
@@ -425,6 +547,11 @@ let PropertiesState = class PropertiesState extends CrudStateBase {
425
547
  apiProperties: [],
426
548
  });
427
549
  }
550
+ resetPropertyStatuses(ctx) {
551
+ ctx.patchState({
552
+ propertyStatuses: [],
553
+ });
554
+ }
428
555
  setModuleInfo(ctx, action) {
429
556
  let parentPath = '';
430
557
  if (action.parentModuleType && action.parentModuleId) {
@@ -541,6 +668,34 @@ let PropertiesState = class PropertiesState extends CrudStateBase {
541
668
  };
542
669
  });
543
670
  }
671
+ buildSchemaFromRecord(record) {
672
+ if (!record) {
673
+ return null;
674
+ }
675
+ const properties = Object.entries(record).reduce((acc, [key, value]) => {
676
+ acc[key] = { type: this.inferApiFieldType(value) };
677
+ return acc;
678
+ }, {});
679
+ return Object.keys(properties).length ? { properties } : null;
680
+ }
681
+ inferApiFieldType(value) {
682
+ if (Array.isArray(value)) {
683
+ return 'array';
684
+ }
685
+ if (value === null) {
686
+ return 'null';
687
+ }
688
+ switch (typeof value) {
689
+ case 'string':
690
+ case 'number':
691
+ case 'boolean':
692
+ return typeof value;
693
+ case 'object':
694
+ return 'object';
695
+ default:
696
+ return undefined;
697
+ }
698
+ }
544
699
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: PropertiesState, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
545
700
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: PropertiesState });
546
701
  };
@@ -565,6 +720,21 @@ __decorate([
565
720
  __decorate([
566
721
  Action(TestApiConfiguration)
567
722
  ], PropertiesState.prototype, "testApiConfiguration", null);
723
+ __decorate([
724
+ Action(GetPropertyStatuses)
725
+ ], PropertiesState.prototype, "getPropertyStatuses", null);
726
+ __decorate([
727
+ Action(CreatePropertyStatus)
728
+ ], PropertiesState.prototype, "createPropertyStatus", null);
729
+ __decorate([
730
+ Action(UpdatePropertyStatus)
731
+ ], PropertiesState.prototype, "updatePropertyStatus", null);
732
+ __decorate([
733
+ Action(DeletePropertyStatus)
734
+ ], PropertiesState.prototype, "deletePropertyStatus", null);
735
+ __decorate([
736
+ Action(ReorderPropertyStatuses)
737
+ ], PropertiesState.prototype, "reorderPropertyStatuses", null);
568
738
  __decorate([
569
739
  Action(GetPropertiesForConfigType)
570
740
  ], PropertiesState.prototype, "getPropertiesForConfigType", null);
@@ -580,6 +750,9 @@ __decorate([
580
750
  __decorate([
581
751
  Action(ResetApiConfiguration)
582
752
  ], PropertiesState.prototype, "resetApiConfiguration", null);
753
+ __decorate([
754
+ Action(ResetPropertyStatuses)
755
+ ], PropertiesState.prototype, "resetPropertyStatuses", null);
583
756
  __decorate([
584
757
  Action(SetPropertiesModuleInfo)
585
758
  ], PropertiesState.prototype, "setModuleInfo", null);
@@ -634,6 +807,9 @@ __decorate([
634
807
  __decorate([
635
808
  Selector()
636
809
  ], PropertiesState, "apiProperties", null);
810
+ __decorate([
811
+ Selector()
812
+ ], PropertiesState, "propertyStatuses", null);
637
813
  __decorate([
638
814
  Selector()
639
815
  ], PropertiesState, "propertyTypes", null);
@@ -660,7 +836,7 @@ PropertiesState = __decorate([
660
836
  ], PropertiesState);
661
837
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: PropertiesState, decorators: [{
662
838
  type: Injectable
663
- }], propDecorators: { getAll: [], getOne: [], getLookups: [], getGroups: [], getConfigAsType: [], getCountries: [], testApiConfiguration: [], getPropertiesForConfigType: [], resetConfigProperties: [], resetConfigScopes: [], resetSelectedProperty: [], resetApiConfiguration: [], setModuleInfo: [], SetPropertyTypes: [], setBreadcrumb: [], setDefaultViewType: [], createProperty: [], updateProperty: [], deleteProperty: [] } });
839
+ }], propDecorators: { getAll: [], getOne: [], getLookups: [], getGroups: [], getConfigAsType: [], getCountries: [], testApiConfiguration: [], getPropertyStatuses: [], createPropertyStatus: [], updatePropertyStatus: [], deletePropertyStatus: [], reorderPropertyStatuses: [], getPropertiesForConfigType: [], resetConfigProperties: [], resetConfigScopes: [], resetSelectedProperty: [], resetApiConfiguration: [], resetPropertyStatuses: [], setModuleInfo: [], SetPropertyTypes: [], setBreadcrumb: [], setDefaultViewType: [], createProperty: [], updateProperty: [], deleteProperty: [] } });
664
840
 
665
841
  class PropertiesFacade {
666
842
  store = inject(Store);
@@ -679,6 +855,7 @@ class PropertiesFacade {
679
855
  countries = select(PropertiesState.countries);
680
856
  apiSchema = select(PropertiesState.apiSchema);
681
857
  apiProperties = select(PropertiesState.apiProperties);
858
+ propertyStatuses = select(PropertiesState.propertyStatuses);
682
859
  breadcrumbItems = select(PropertiesState.breadcrumbItems);
683
860
  defaultViewType = select(PropertiesState.defaultViewType);
684
861
  // ============================================================================
@@ -700,6 +877,11 @@ class PropertiesFacade {
700
877
  isLoadingConfigAsType = computed(() => this.loadingActive().includes(PropertiesActionKey.GetConfigAsType), ...(ngDevMode ? [{ debugName: "isLoadingConfigAsType" }] : []));
701
878
  isLoadingCountries = computed(() => this.loadingActive().includes(PropertiesActionKey.GetCountries), ...(ngDevMode ? [{ debugName: "isLoadingCountries" }] : []));
702
879
  isTestingApi = computed(() => this.loadingActive().includes(PropertiesActionKey.TestApiConfiguration), ...(ngDevMode ? [{ debugName: "isTestingApi" }] : []));
880
+ isLoadingPropertyStatuses = computed(() => this.loadingActive().includes(PropertiesActionKey.GetPropertyStatuses), ...(ngDevMode ? [{ debugName: "isLoadingPropertyStatuses" }] : []));
881
+ isCreatingPropertyStatus = computed(() => this.loadingActive().includes(PropertiesActionKey.CreatePropertyStatus), ...(ngDevMode ? [{ debugName: "isCreatingPropertyStatus" }] : []));
882
+ isUpdatingPropertyStatus = computed(() => this.loadingActive().includes(PropertiesActionKey.UpdatePropertyStatus), ...(ngDevMode ? [{ debugName: "isUpdatingPropertyStatus" }] : []));
883
+ isDeletingPropertyStatus = computed(() => this.loadingActive().includes(PropertiesActionKey.DeletePropertyStatus), ...(ngDevMode ? [{ debugName: "isDeletingPropertyStatus" }] : []));
884
+ isReorderingPropertyStatuses = computed(() => this.loadingActive().includes(PropertiesActionKey.ReorderPropertyStatuses), ...(ngDevMode ? [{ debugName: "isReorderingPropertyStatuses" }] : []));
703
885
  // ============================================================================
704
886
  // Error Signals - Computed from slice (minimal reactivity)
705
887
  // ============================================================================
@@ -714,6 +896,7 @@ class PropertiesFacade {
714
896
  configAsTypeError = computed(() => this.errors()[PropertiesActionKey.GetConfigAsType] ?? null, ...(ngDevMode ? [{ debugName: "configAsTypeError" }] : []));
715
897
  countriesError = computed(() => this.errors()[PropertiesActionKey.GetCountries] ?? null, ...(ngDevMode ? [{ debugName: "countriesError" }] : []));
716
898
  apiTestError = computed(() => this.errors()[PropertiesActionKey.TestApiConfiguration] ?? null, ...(ngDevMode ? [{ debugName: "apiTestError" }] : []));
899
+ propertyStatusesError = computed(() => this.errors()[PropertiesActionKey.GetPropertyStatuses] ?? null, ...(ngDevMode ? [{ debugName: "propertyStatusesError" }] : []));
717
900
  // ============================================================================
718
901
  // Derived Data - Computed from data selectors
719
902
  // ============================================================================
@@ -758,6 +941,24 @@ class PropertiesFacade {
758
941
  resetApiConfiguration() {
759
942
  return this.store.dispatch(new ResetApiConfiguration());
760
943
  }
944
+ loadPropertyStatuses(propertyId) {
945
+ return this.store.dispatch(new GetPropertyStatuses(propertyId));
946
+ }
947
+ createPropertyStatus(propertyId, payload) {
948
+ return this.store.dispatch(new CreatePropertyStatus(propertyId, payload));
949
+ }
950
+ updatePropertyStatus(propertyId, statusId, payload) {
951
+ return this.store.dispatch(new UpdatePropertyStatus(propertyId, statusId, payload));
952
+ }
953
+ deletePropertyStatus(propertyId, statusId) {
954
+ return this.store.dispatch(new DeletePropertyStatus(propertyId, statusId));
955
+ }
956
+ reorderPropertyStatuses(payload) {
957
+ return this.store.dispatch(new ReorderPropertyStatuses(payload));
958
+ }
959
+ resetPropertyStatuses() {
960
+ return this.store.dispatch(new ResetPropertyStatuses());
961
+ }
761
962
  setPropertyTypes(propertyTypes) {
762
963
  return this.store.dispatch(new SetPropertyTypes(propertyTypes));
763
964
  }
@@ -885,7 +1086,7 @@ class PropertiesList {
885
1086
  },
886
1087
  },
887
1088
  {
888
- key: 'isRequired',
1089
+ key: 'isCalculated',
889
1090
  label: this.transloco.translate('properties.list.columnCalculated'),
890
1091
  type: 'boolean',
891
1092
  readonly: true,
@@ -998,7 +1199,7 @@ class PropertiesList {
998
1199
  });
999
1200
  }
1000
1201
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: PropertiesList, deps: [], target: i0.ɵɵFactoryTarget.Component });
1001
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: PropertiesList, isStandalone: true, selector: "mt-properties-list", inputs: { tab: { classPropertyName: "tab", publicName: "tab", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"space-y-3\">\r\n <div class=\"flex items-center justify-between\">\r\n <div class=\"space-y-1\">\r\n <h1 class=\"text-xl font-semibold text-slate-900 tracking-tight\">\r\n {{ \"properties.list.pageTitle\" | transloco }}\r\n </h1>\r\n <mt-breadcrumb\r\n [items]=\"breadcrumbItems()\"\r\n [styleClass]=\"'flex justify-center'\"\r\n >\r\n </mt-breadcrumb>\r\n </div>\r\n </div>\r\n <mt-card paddingless>\r\n <mt-table\r\n [tabs]=\"tabs()\"\r\n [(activeTab)]=\"activeTab\"\r\n (onTabChange)=\"onTabChange($event)\"\r\n [data]=\"tableData()\"\r\n [actions]=\"tableActions()\"\r\n [columns]=\"tableColumns()\"\r\n [rowActions]=\"rowActions()\"\r\n [generalSearch]=\"true\"\r\n [showFilters]=\"true\"\r\n [loading]=\"loading()\"\r\n >\r\n <ng-template #empty>\r\n <div headless class=\"flex-col justify-center items-center w-full p-5\">\r\n <div\r\n class=\"content flex flex-col gap-5 items-center text-center mb-5\"\r\n >\r\n <svg\r\n width=\"152\"\r\n height=\"120\"\r\n viewBox=\"0 0 152 120\"\r\n fill=\"none\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n >\r\n <circle cx=\"76\" cy=\"52\" r=\"52\" fill=\"#E9EAEB\" />\r\n <g filter=\"url(#filter0_ddd_2474_28277)\">\r\n <path\r\n d=\"M77.6 16C66.8273 16 57.2978 21.3233 51.4987 29.4829C49.605 29.0363 47.6301 28.8 45.6 28.8C31.4615 28.8 20 40.2615 20 54.4C20 68.5385 31.4615 80 45.6 80L109.6 80C121.971 80 132 69.9712 132 57.6C132 45.2288 121.971 35.2 109.6 35.2C108.721 35.2 107.854 35.2506 107.002 35.349C102.098 23.9677 90.7797 16 77.6 16Z\"\r\n fill=\"#FAFAFA\"\r\n />\r\n <ellipse\r\n cx=\"45.6\"\r\n cy=\"54.3998\"\r\n rx=\"25.6\"\r\n ry=\"25.6\"\r\n fill=\"url(#paint0_linear_2474_28277)\"\r\n />\r\n <circle\r\n cx=\"77.6016\"\r\n cy=\"48\"\r\n r=\"32\"\r\n fill=\"url(#paint1_linear_2474_28277)\"\r\n />\r\n <ellipse\r\n cx=\"109.599\"\r\n cy=\"57.6002\"\r\n rx=\"22.4\"\r\n ry=\"22.4\"\r\n fill=\"url(#paint2_linear_2474_28277)\"\r\n />\r\n </g>\r\n <circle cx=\"21\" cy=\"19\" r=\"5\" fill=\"#F5F5F5\" />\r\n <circle cx=\"18\" cy=\"109\" r=\"7\" fill=\"#F5F5F5\" />\r\n <circle cx=\"145\" cy=\"35\" r=\"7\" fill=\"#F5F5F5\" />\r\n <circle cx=\"134\" cy=\"8\" r=\"4\" fill=\"#F5F5F5\" />\r\n <foreignObject x=\"44\" y=\"54\" width=\"64\" height=\"64\">\r\n <div\r\n xmlns=\"http://www.w3.org/1999/xhtml\"\r\n style=\"\r\n backdrop-filter: blur(4px);\r\n clip-path: url(#bgblur_0_2474_28277_clip_path);\r\n height: 100%;\r\n width: 100%;\r\n \"\r\n ></div>\r\n </foreignObject>\r\n <g data-figma-bg-blur-radius=\"8\">\r\n <path\r\n d=\"M52 86C52 72.7452 62.7452 62 76 62C89.2548 62 100 72.7452 100 86C100 99.2548 89.2548 110 76 110C62.7452 110 52 99.2548 52 86Z\"\r\n fill=\"#344054\"\r\n fill-opacity=\"0.4\"\r\n />\r\n <path\r\n d=\"M85 95L81.5001 91.5M84 85.5C84 90.1944 80.1944 94 75.5 94C70.8056 94 67 90.1944 67 85.5C67 80.8056 70.8056 77 75.5 77C80.1944 77 84 80.8056 84 85.5Z\"\r\n stroke=\"white\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n </g>\r\n <defs>\r\n <filter\r\n id=\"filter0_ddd_2474_28277\"\r\n x=\"0\"\r\n y=\"16\"\r\n width=\"152\"\r\n height=\"104\"\r\n filterUnits=\"userSpaceOnUse\"\r\n color-interpolation-filters=\"sRGB\"\r\n >\r\n <feFlood flood-opacity=\"0\" result=\"BackgroundImageFix\" />\r\n <feColorMatrix\r\n in=\"SourceAlpha\"\r\n type=\"matrix\"\r\n values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\"\r\n result=\"hardAlpha\"\r\n />\r\n <feMorphology\r\n radius=\"1.5\"\r\n operator=\"erode\"\r\n in=\"SourceAlpha\"\r\n result=\"effect1_dropShadow_2474_28277\"\r\n />\r\n <feOffset dy=\"3\" />\r\n <feGaussianBlur stdDeviation=\"1.5\" />\r\n <feComposite in2=\"hardAlpha\" operator=\"out\" />\r\n <feColorMatrix\r\n type=\"matrix\"\r\n values=\"0 0 0 0 0.0392157 0 0 0 0 0.0496732 0 0 0 0 0.0705882 0 0 0 0.04 0\"\r\n />\r\n <feBlend\r\n mode=\"normal\"\r\n in2=\"BackgroundImageFix\"\r\n result=\"effect1_dropShadow_2474_28277\"\r\n />\r\n <feColorMatrix\r\n in=\"SourceAlpha\"\r\n type=\"matrix\"\r\n values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\"\r\n result=\"hardAlpha\"\r\n />\r\n <feMorphology\r\n radius=\"4\"\r\n operator=\"erode\"\r\n in=\"SourceAlpha\"\r\n result=\"effect2_dropShadow_2474_28277\"\r\n />\r\n <feOffset dy=\"8\" />\r\n <feGaussianBlur stdDeviation=\"4\" />\r\n <feComposite in2=\"hardAlpha\" operator=\"out\" />\r\n <feColorMatrix\r\n type=\"matrix\"\r\n values=\"0 0 0 0 0.0392157 0 0 0 0 0.0496732 0 0 0 0 0.0705882 0 0 0 0.03 0\"\r\n />\r\n <feBlend\r\n mode=\"normal\"\r\n in2=\"effect1_dropShadow_2474_28277\"\r\n result=\"effect2_dropShadow_2474_28277\"\r\n />\r\n <feColorMatrix\r\n in=\"SourceAlpha\"\r\n type=\"matrix\"\r\n values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\"\r\n result=\"hardAlpha\"\r\n />\r\n <feMorphology\r\n radius=\"4\"\r\n operator=\"erode\"\r\n in=\"SourceAlpha\"\r\n result=\"effect3_dropShadow_2474_28277\"\r\n />\r\n <feOffset dy=\"20\" />\r\n <feGaussianBlur stdDeviation=\"12\" />\r\n <feComposite in2=\"hardAlpha\" operator=\"out\" />\r\n <feColorMatrix\r\n type=\"matrix\"\r\n values=\"0 0 0 0 0.0392157 0 0 0 0 0.0496732 0 0 0 0 0.0705882 0 0 0 0.08 0\"\r\n />\r\n <feBlend\r\n mode=\"normal\"\r\n in2=\"effect2_dropShadow_2474_28277\"\r\n result=\"effect3_dropShadow_2474_28277\"\r\n />\r\n <feBlend\r\n mode=\"normal\"\r\n in=\"SourceGraphic\"\r\n in2=\"effect3_dropShadow_2474_28277\"\r\n result=\"shape\"\r\n />\r\n </filter>\r\n <clipPath\r\n id=\"bgblur_0_2474_28277_clip_path\"\r\n transform=\"translate(-44 -54)\"\r\n >\r\n <path\r\n d=\"M52 86C52 72.7452 62.7452 62 76 62C89.2548 62 100 72.7452 100 86C100 99.2548 89.2548 110 76 110C62.7452 110 52 99.2548 52 86Z\"\r\n />\r\n </clipPath>\r\n <linearGradient\r\n id=\"paint0_linear_2474_28277\"\r\n x1=\"25.9429\"\r\n y1=\"37.4855\"\r\n x2=\"71.2\"\r\n y2=\"79.9998\"\r\n gradientUnits=\"userSpaceOnUse\"\r\n >\r\n <stop stop-color=\"#D0D5DD\" />\r\n <stop offset=\"0.350715\" stop-color=\"white\" stop-opacity=\"0\" />\r\n </linearGradient>\r\n <linearGradient\r\n id=\"paint1_linear_2474_28277\"\r\n x1=\"53.0301\"\r\n y1=\"26.8571\"\r\n x2=\"109.602\"\r\n y2=\"80\"\r\n gradientUnits=\"userSpaceOnUse\"\r\n >\r\n <stop stop-color=\"#D0D5DD\" />\r\n <stop offset=\"0.350715\" stop-color=\"white\" stop-opacity=\"0\" />\r\n </linearGradient>\r\n <linearGradient\r\n id=\"paint2_linear_2474_28277\"\r\n x1=\"92.3992\"\r\n y1=\"42.8002\"\r\n x2=\"131.999\"\r\n y2=\"80.0002\"\r\n gradientUnits=\"userSpaceOnUse\"\r\n >\r\n <stop stop-color=\"#D0D5DD\" />\r\n <stop offset=\"0.350715\" stop-color=\"white\" stop-opacity=\"0\" />\r\n </linearGradient>\r\n </defs>\r\n </svg>\r\n\r\n <div class=\"flex flex-col gap-1\">\r\n <div class=\"text-md text-surface-600\">\r\n {{ \"properties.list.emptyStateNoData\" | transloco }}\r\n </div>\r\n </div>\r\n <div>\r\n <mt-button\r\n [label]=\"'properties.list.addNewProperty' | transloco\"\r\n icon=\"general.plus\"\r\n (click)=\"createProperty()\"\r\n />\r\n </div>\r\n </div>\r\n <p-divider type=\"solid\">\r\n <div class=\"text-lg text-surface-600\">\r\n {{ \"properties.list.emptyStateTemplate\" | transloco }}\r\n </div>\r\n </p-divider>\r\n <div class=\"flex gap-3 mt-5 justify-center\">\r\n @for (card of propertyTypes(); track card.label) {\r\n <mt-card\r\n headless\r\n class=\"w-25 tailwind-4 cursor-pointer\"\r\n style=\"background-color: #fafafa\"\r\n (click)=\"createPropertyWithType(card.value)\"\r\n >\r\n <div\r\n class=\"content flex flex-col gap-3 items-center text-center\"\r\n >\r\n <mt-avatar\r\n [style.--p-avatar-background]=\"\r\n 'var(--p-' + card.color + '-100)'\r\n \"\r\n [style.--p-avatar-color]=\"'var(--p-' + card.color + '-600)'\"\r\n [icon]=\"card.icon\"\r\n shape=\"square\"\r\n ></mt-avatar>\r\n <div class=\"flex flex-col gap-1\">\r\n <div class=\"text-xs font-normal\">{{ card.label }}</div>\r\n </div>\r\n </div>\r\n </mt-card>\r\n }\r\n </div>\r\n </div>\r\n </ng-template>\r\n </mt-table>\r\n </mt-card>\r\n</div>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: Table, selector: "mt-table", inputs: ["filters", "data", "columns", "rowActions", "size", "showGridlines", "stripedRows", "selectableRows", "generalSearch", "showFilters", "loading", "updating", "lazy", "lazyTotalRecords", "reorderableColumns", "reorderableRows", "dataKey", "exportable", "exportFilename", "tabs", "tabsOptionLabel", "tabsOptionValue", "activeTab", "actions", "paginatorPosition", "pageSize", "currentPage", "first", "filterTerm"], outputs: ["selectionChange", "cellChange", "lazyLoad", "columnReorder", "rowReorder", "filtersChange", "activeTabChange", "onTabChange", "pageSizeChange", "currentPageChange", "firstChange", "filterTermChange"] }, { kind: "component", type: Breadcrumb, selector: "mt-breadcrumb", inputs: ["items", "styleClass"], outputs: ["onItemClick"] }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "component", type: Avatar, selector: "mt-avatar", inputs: ["label", "icon", "image", "styleClass", "size", "shape", "badge", "badgeSize", "badgeSeverity"], outputs: ["onImageError"] }, { kind: "component", type: Divider, selector: "p-divider", inputs: ["styleClass", "layout", "type", "align"] }, { 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: "ngmodule", type: TranslocoModule }, { kind: "pipe", type: i1.TranslocoPipe, name: "transloco" }] });
1202
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: PropertiesList, isStandalone: true, selector: "mt-properties-list", inputs: { tab: { classPropertyName: "tab", publicName: "tab", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"space-y-3\">\r\n <div class=\"flex items-center justify-between\">\r\n <div class=\"space-y-1\">\r\n <h1 class=\"text-xl font-semibold text-slate-900 tracking-tight\">\r\n {{ \"properties.list.pageTitle\" | transloco }}\r\n </h1>\r\n <mt-breadcrumb\r\n [items]=\"breadcrumbItems()\"\r\n [styleClass]=\"'flex justify-center'\"\r\n >\r\n </mt-breadcrumb>\r\n </div>\r\n </div>\r\n <mt-card paddingless>\r\n <mt-table\r\n [tabs]=\"tabs()\"\r\n [(activeTab)]=\"activeTab\"\r\n (onTabChange)=\"onTabChange($event)\"\r\n [data]=\"tableData()\"\r\n [actions]=\"tableActions()\"\r\n [columns]=\"tableColumns()\"\r\n [rowActions]=\"rowActions()\"\r\n [generalSearch]=\"true\"\r\n [showFilters]=\"true\"\r\n [loading]=\"loading()\"\r\n >\r\n <ng-template #empty>\r\n <div headless class=\"flex-col justify-center items-center w-full p-5\">\r\n <div\r\n class=\"content flex flex-col gap-5 items-center text-center mb-5\"\r\n >\r\n <svg\r\n width=\"152\"\r\n height=\"120\"\r\n viewBox=\"0 0 152 120\"\r\n fill=\"none\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n >\r\n <circle cx=\"76\" cy=\"52\" r=\"52\" fill=\"#E9EAEB\" />\r\n <g filter=\"url(#filter0_ddd_2474_28277)\">\r\n <path\r\n d=\"M77.6 16C66.8273 16 57.2978 21.3233 51.4987 29.4829C49.605 29.0363 47.6301 28.8 45.6 28.8C31.4615 28.8 20 40.2615 20 54.4C20 68.5385 31.4615 80 45.6 80L109.6 80C121.971 80 132 69.9712 132 57.6C132 45.2288 121.971 35.2 109.6 35.2C108.721 35.2 107.854 35.2506 107.002 35.349C102.098 23.9677 90.7797 16 77.6 16Z\"\r\n fill=\"#FAFAFA\"\r\n />\r\n <ellipse\r\n cx=\"45.6\"\r\n cy=\"54.3998\"\r\n rx=\"25.6\"\r\n ry=\"25.6\"\r\n fill=\"url(#paint0_linear_2474_28277)\"\r\n />\r\n <circle\r\n cx=\"77.6016\"\r\n cy=\"48\"\r\n r=\"32\"\r\n fill=\"url(#paint1_linear_2474_28277)\"\r\n />\r\n <ellipse\r\n cx=\"109.599\"\r\n cy=\"57.6002\"\r\n rx=\"22.4\"\r\n ry=\"22.4\"\r\n fill=\"url(#paint2_linear_2474_28277)\"\r\n />\r\n </g>\r\n <circle cx=\"21\" cy=\"19\" r=\"5\" fill=\"#F5F5F5\" />\r\n <circle cx=\"18\" cy=\"109\" r=\"7\" fill=\"#F5F5F5\" />\r\n <circle cx=\"145\" cy=\"35\" r=\"7\" fill=\"#F5F5F5\" />\r\n <circle cx=\"134\" cy=\"8\" r=\"4\" fill=\"#F5F5F5\" />\r\n <foreignObject x=\"44\" y=\"54\" width=\"64\" height=\"64\">\r\n <div\r\n xmlns=\"http://www.w3.org/1999/xhtml\"\r\n style=\"\r\n backdrop-filter: blur(4px);\r\n clip-path: url(#bgblur_0_2474_28277_clip_path);\r\n height: 100%;\r\n width: 100%;\r\n \"\r\n ></div>\r\n </foreignObject>\r\n <g data-figma-bg-blur-radius=\"8\">\r\n <path\r\n d=\"M52 86C52 72.7452 62.7452 62 76 62C89.2548 62 100 72.7452 100 86C100 99.2548 89.2548 110 76 110C62.7452 110 52 99.2548 52 86Z\"\r\n fill=\"#344054\"\r\n fill-opacity=\"0.4\"\r\n />\r\n <path\r\n d=\"M85 95L81.5001 91.5M84 85.5C84 90.1944 80.1944 94 75.5 94C70.8056 94 67 90.1944 67 85.5C67 80.8056 70.8056 77 75.5 77C80.1944 77 84 80.8056 84 85.5Z\"\r\n stroke=\"white\"\r\n stroke-width=\"2\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n />\r\n </g>\r\n <defs>\r\n <filter\r\n id=\"filter0_ddd_2474_28277\"\r\n x=\"0\"\r\n y=\"16\"\r\n width=\"152\"\r\n height=\"104\"\r\n filterUnits=\"userSpaceOnUse\"\r\n color-interpolation-filters=\"sRGB\"\r\n >\r\n <feFlood flood-opacity=\"0\" result=\"BackgroundImageFix\" />\r\n <feColorMatrix\r\n in=\"SourceAlpha\"\r\n type=\"matrix\"\r\n values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\"\r\n result=\"hardAlpha\"\r\n />\r\n <feMorphology\r\n radius=\"1.5\"\r\n operator=\"erode\"\r\n in=\"SourceAlpha\"\r\n result=\"effect1_dropShadow_2474_28277\"\r\n />\r\n <feOffset dy=\"3\" />\r\n <feGaussianBlur stdDeviation=\"1.5\" />\r\n <feComposite in2=\"hardAlpha\" operator=\"out\" />\r\n <feColorMatrix\r\n type=\"matrix\"\r\n values=\"0 0 0 0 0.0392157 0 0 0 0 0.0496732 0 0 0 0 0.0705882 0 0 0 0.04 0\"\r\n />\r\n <feBlend\r\n mode=\"normal\"\r\n in2=\"BackgroundImageFix\"\r\n result=\"effect1_dropShadow_2474_28277\"\r\n />\r\n <feColorMatrix\r\n in=\"SourceAlpha\"\r\n type=\"matrix\"\r\n values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\"\r\n result=\"hardAlpha\"\r\n />\r\n <feMorphology\r\n radius=\"4\"\r\n operator=\"erode\"\r\n in=\"SourceAlpha\"\r\n result=\"effect2_dropShadow_2474_28277\"\r\n />\r\n <feOffset dy=\"8\" />\r\n <feGaussianBlur stdDeviation=\"4\" />\r\n <feComposite in2=\"hardAlpha\" operator=\"out\" />\r\n <feColorMatrix\r\n type=\"matrix\"\r\n values=\"0 0 0 0 0.0392157 0 0 0 0 0.0496732 0 0 0 0 0.0705882 0 0 0 0.03 0\"\r\n />\r\n <feBlend\r\n mode=\"normal\"\r\n in2=\"effect1_dropShadow_2474_28277\"\r\n result=\"effect2_dropShadow_2474_28277\"\r\n />\r\n <feColorMatrix\r\n in=\"SourceAlpha\"\r\n type=\"matrix\"\r\n values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\"\r\n result=\"hardAlpha\"\r\n />\r\n <feMorphology\r\n radius=\"4\"\r\n operator=\"erode\"\r\n in=\"SourceAlpha\"\r\n result=\"effect3_dropShadow_2474_28277\"\r\n />\r\n <feOffset dy=\"20\" />\r\n <feGaussianBlur stdDeviation=\"12\" />\r\n <feComposite in2=\"hardAlpha\" operator=\"out\" />\r\n <feColorMatrix\r\n type=\"matrix\"\r\n values=\"0 0 0 0 0.0392157 0 0 0 0 0.0496732 0 0 0 0 0.0705882 0 0 0 0.08 0\"\r\n />\r\n <feBlend\r\n mode=\"normal\"\r\n in2=\"effect2_dropShadow_2474_28277\"\r\n result=\"effect3_dropShadow_2474_28277\"\r\n />\r\n <feBlend\r\n mode=\"normal\"\r\n in=\"SourceGraphic\"\r\n in2=\"effect3_dropShadow_2474_28277\"\r\n result=\"shape\"\r\n />\r\n </filter>\r\n <clipPath\r\n id=\"bgblur_0_2474_28277_clip_path\"\r\n transform=\"translate(-44 -54)\"\r\n >\r\n <path\r\n d=\"M52 86C52 72.7452 62.7452 62 76 62C89.2548 62 100 72.7452 100 86C100 99.2548 89.2548 110 76 110C62.7452 110 52 99.2548 52 86Z\"\r\n />\r\n </clipPath>\r\n <linearGradient\r\n id=\"paint0_linear_2474_28277\"\r\n x1=\"25.9429\"\r\n y1=\"37.4855\"\r\n x2=\"71.2\"\r\n y2=\"79.9998\"\r\n gradientUnits=\"userSpaceOnUse\"\r\n >\r\n <stop stop-color=\"#D0D5DD\" />\r\n <stop offset=\"0.350715\" stop-color=\"white\" stop-opacity=\"0\" />\r\n </linearGradient>\r\n <linearGradient\r\n id=\"paint1_linear_2474_28277\"\r\n x1=\"53.0301\"\r\n y1=\"26.8571\"\r\n x2=\"109.602\"\r\n y2=\"80\"\r\n gradientUnits=\"userSpaceOnUse\"\r\n >\r\n <stop stop-color=\"#D0D5DD\" />\r\n <stop offset=\"0.350715\" stop-color=\"white\" stop-opacity=\"0\" />\r\n </linearGradient>\r\n <linearGradient\r\n id=\"paint2_linear_2474_28277\"\r\n x1=\"92.3992\"\r\n y1=\"42.8002\"\r\n x2=\"131.999\"\r\n y2=\"80.0002\"\r\n gradientUnits=\"userSpaceOnUse\"\r\n >\r\n <stop stop-color=\"#D0D5DD\" />\r\n <stop offset=\"0.350715\" stop-color=\"white\" stop-opacity=\"0\" />\r\n </linearGradient>\r\n </defs>\r\n </svg>\r\n\r\n <div class=\"flex flex-col gap-1\">\r\n <div class=\"text-md text-surface-600\">\r\n {{ \"properties.list.emptyStateNoData\" | transloco }}\r\n </div>\r\n </div>\r\n <div>\r\n <mt-button\r\n [label]=\"'properties.list.addNewProperty' | transloco\"\r\n icon=\"general.plus\"\r\n (click)=\"createProperty()\"\r\n />\r\n </div>\r\n </div>\r\n <p-divider type=\"solid\">\r\n <div class=\"text-lg text-surface-600\">\r\n {{ \"properties.list.emptyStateTemplate\" | transloco }}\r\n </div>\r\n </p-divider>\r\n <div class=\"flex gap-3 mt-5 justify-center\">\r\n @for (card of propertyTypes(); track card.label) {\r\n <mt-card\r\n headless\r\n class=\"w-25 tailwind-4 cursor-pointer\"\r\n style=\"background-color: #fafafa\"\r\n (click)=\"createPropertyWithType(card.value)\"\r\n >\r\n <div\r\n class=\"content flex flex-col gap-3 items-center text-center\"\r\n >\r\n <mt-avatar\r\n [style.--p-avatar-background]=\"\r\n 'var(--p-' + card.color + '-100)'\r\n \"\r\n [style.--p-avatar-color]=\"'var(--p-' + card.color + '-600)'\"\r\n [icon]=\"card.icon\"\r\n shape=\"square\"\r\n ></mt-avatar>\r\n <div class=\"flex flex-col gap-1\">\r\n <div class=\"text-xs font-normal\">{{ card.label }}</div>\r\n </div>\r\n </div>\r\n </mt-card>\r\n }\r\n </div>\r\n </div>\r\n </ng-template>\r\n </mt-table>\r\n </mt-card>\r\n</div>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: Table, selector: "mt-table", inputs: ["filters", "data", "columns", "rowActions", "size", "showGridlines", "stripedRows", "selectableRows", "clickableRows", "generalSearch", "showFilters", "loading", "updating", "lazy", "lazyTotalRecords", "reorderableColumns", "reorderableRows", "dataKey", "exportable", "exportFilename", "tabs", "tabsOptionLabel", "tabsOptionValue", "activeTab", "actions", "paginatorPosition", "pageSize", "currentPage", "first", "filterTerm"], outputs: ["selectionChange", "cellChange", "lazyLoad", "columnReorder", "rowReorder", "rowClick", "filtersChange", "activeTabChange", "onTabChange", "pageSizeChange", "currentPageChange", "firstChange", "filterTermChange"] }, { kind: "component", type: Breadcrumb, selector: "mt-breadcrumb", inputs: ["items", "styleClass"], outputs: ["onItemClick"] }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "component", type: Avatar, selector: "mt-avatar", inputs: ["label", "icon", "image", "styleClass", "size", "shape", "badge", "badgeSize", "badgeSeverity"], outputs: ["onImageError"] }, { kind: "component", type: Divider, selector: "p-divider", inputs: ["styleClass", "layout", "type", "align"] }, { 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: "ngmodule", type: TranslocoModule }, { kind: "pipe", type: i2.TranslocoPipe, name: "transloco" }] });
1002
1203
  }
1003
1204
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: PropertiesList, decorators: [{
1004
1205
  type: Component,
@@ -1019,11 +1220,19 @@ class ApiConfiguration {
1019
1220
  destroyRef = inject(DestroyRef);
1020
1221
  transloco = inject(TranslocoService);
1021
1222
  schema = signal(null, ...(ngDevMode ? [{ debugName: "schema" }] : []));
1223
+ lastLoadedPayloadSignature = null;
1022
1224
  isWriting = false;
1023
1225
  touched = false;
1024
1226
  isTesting = this.facade.isTestingApi;
1025
1227
  apiProperties = this.facade.apiProperties;
1026
- hasDetectedSchema = computed(() => this.apiProperties().length > 0, ...(ngDevMode ? [{ debugName: "hasDetectedSchema" }] : []));
1228
+ resolvedApiProperties = computed(() => {
1229
+ const loadedProperties = this.apiProperties();
1230
+ if (loadedProperties.length) {
1231
+ return loadedProperties;
1232
+ }
1233
+ return this.mapSchemaToOptions(this.schema());
1234
+ }, ...(ngDevMode ? [{ debugName: "resolvedApiProperties" }] : []));
1235
+ hasDetectedSchema = computed(() => this.resolvedApiProperties().length > 0, ...(ngDevMode ? [{ debugName: "hasDetectedSchema" }] : []));
1027
1236
  form = new FormGroup({
1028
1237
  endpoint: new FormControl('', {
1029
1238
  nonNullable: true,
@@ -1080,6 +1289,8 @@ class ApiConfiguration {
1080
1289
  supportMultiSelect: false,
1081
1290
  }, { emitEvent: false });
1082
1291
  this.setHeadersFromRecord({});
1292
+ this.lastLoadedPayloadSignature = null;
1293
+ this.facade.resetApiConfiguration().subscribe();
1083
1294
  this.schema.set(null);
1084
1295
  this.touched = false;
1085
1296
  return;
@@ -1093,6 +1304,7 @@ class ApiConfiguration {
1093
1304
  }, { emitEvent: false });
1094
1305
  this.setHeadersFromRecord(value.headers ?? {});
1095
1306
  this.touched = false;
1307
+ this.loadApiFields(value.endpoint ?? '', value.headers ?? {});
1096
1308
  }
1097
1309
  finally {
1098
1310
  this.isWriting = false;
@@ -1133,11 +1345,7 @@ class ApiConfiguration {
1133
1345
  return;
1134
1346
  }
1135
1347
  const headers = this.headersToRecord();
1136
- const payload = {
1137
- endpoint: this.form.controls.endpoint.value,
1138
- headers: Object.keys(headers).length ? headers : undefined,
1139
- };
1140
- this.facade.testApiConfiguration(payload).subscribe();
1348
+ this.loadApiFields(this.form.controls.endpoint.value, headers, true);
1141
1349
  }
1142
1350
  emitValue(triggerTouched = true) {
1143
1351
  if (this.isWriting) {
@@ -1181,6 +1389,35 @@ class ApiConfiguration {
1181
1389
  return acc;
1182
1390
  }, {});
1183
1391
  }
1392
+ loadApiFields(endpoint, headers, force = false) {
1393
+ const trimmedEndpoint = endpoint.trim();
1394
+ if (!trimmedEndpoint) {
1395
+ return;
1396
+ }
1397
+ const payload = {
1398
+ endpoint: trimmedEndpoint,
1399
+ headers: Object.keys(headers).length ? headers : undefined,
1400
+ };
1401
+ const payloadSignature = JSON.stringify(payload);
1402
+ if (!force && payloadSignature === this.lastLoadedPayloadSignature) {
1403
+ return;
1404
+ }
1405
+ this.lastLoadedPayloadSignature = payloadSignature;
1406
+ this.facade.testApiConfiguration(payload).subscribe();
1407
+ }
1408
+ mapSchemaToOptions(schema) {
1409
+ if (!schema?.properties) {
1410
+ return [];
1411
+ }
1412
+ return Object.entries(schema.properties).map(([key, definition]) => {
1413
+ const typeLabel = definition?.type ? ` | ${definition.type}` : '';
1414
+ return {
1415
+ key,
1416
+ name: `${key}${typeLabel}`,
1417
+ type: definition?.type,
1418
+ };
1419
+ });
1420
+ }
1184
1421
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: ApiConfiguration, deps: [], target: i0.ɵɵFactoryTarget.Component });
1185
1422
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: ApiConfiguration, isStandalone: true, selector: "mt-api-configuration", providers: [
1186
1423
  {
@@ -1193,7 +1430,7 @@ class ApiConfiguration {
1193
1430
  useExisting: forwardRef(() => ApiConfiguration),
1194
1431
  multi: true,
1195
1432
  },
1196
- ], ngImport: i0, template: "<div [formGroup]=\"form\" class=\"space-y-6\">\r\n <div class=\"space-y-4 rounded-xl bg-content px-6 py-4 shadow-sm\">\r\n <div class=\"grid items-end gap-3 md:grid-cols-[minmax(0,1fr)_auto]\">\r\n <mt-text-field\r\n formControlName=\"endpoint\"\r\n [label]=\"'properties.form.endpoint' | transloco\"\r\n [placeholder]=\"'properties.form.endpointPlaceholder' | transloco\"\r\n />\r\n <div class=\"flex justify-end gap-2\">\r\n <mt-button\r\n type=\"button\"\r\n [text]=\"true\"\r\n icon=\"general.plus\"\r\n [label]=\"'properties.form.addHeader' | transloco\"\r\n (click)=\"addHeader()\"\r\n />\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"'properties.form.testApi' | transloco\"\r\n [loading]=\"isTesting()\"\r\n (click)=\"testApi()\"\r\n />\r\n </div>\r\n </div>\r\n\r\n @if (headers.controls.length) {\r\n <div class=\"space-y-3\">\r\n <div class=\"text-sm font-medium text-surface-500\">\r\n {{ \"properties.form.headers\" | transloco }}\r\n </div>\r\n <div class=\"space-y-3\">\r\n @for (\r\n headerCtrl of headers.controls;\r\n track headerCtrl;\r\n let i = $index\r\n ) {\r\n <div\r\n [formGroup]=\"headerCtrl\"\r\n class=\"grid items-end gap-3 md:grid-cols-[minmax(0,1fr)_minmax(0,1fr)_auto]\"\r\n >\r\n <mt-text-field\r\n formControlName=\"key\"\r\n [label]=\"'properties.form.headerKey' | transloco\"\r\n />\r\n <mt-text-field\r\n formControlName=\"value\"\r\n [label]=\"'properties.form.headerValue' | transloco\"\r\n />\r\n <mt-button\r\n type=\"button\"\r\n [text]=\"true\"\r\n icon=\"general.trash-01\"\r\n (click)=\"removeHeader(i)\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n } @else {\r\n <p class=\"text-xs text-surface-400\">\r\n {{ \"properties.form.noHeadersMessage\" | transloco }}\r\n </p>\r\n }\r\n </div>\r\n\r\n <div class=\"space-y-4 rounded-xl bg-content px-6 py-4 shadow-sm\">\r\n @if (hasDetectedSchema()) {\r\n <div class=\"grid gap-4 md:grid-cols-2\">\r\n <mt-select-field\r\n formControlName=\"key\"\r\n [options]=\"apiProperties()\"\r\n [showClear]=\"true\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n [label]=\"'properties.form.keyField' | transloco\"\r\n />\r\n <mt-select-field\r\n formControlName=\"value\"\r\n [options]=\"apiProperties()\"\r\n [showClear]=\"true\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n [label]=\"'properties.form.valueField' | transloco\"\r\n />\r\n </div>\r\n } @else {\r\n <p class=\"text-xs text-surface-400\">\r\n {{ \"properties.form.messageTestApiPrompt\" | transloco }}\r\n </p>\r\n }\r\n\r\n <div class=\"flex items-center justify-between gap-4\">\r\n <mt-toggle-field\r\n formControlName=\"supportMultiSelect\"\r\n [label]=\"'properties.form.labelSupportMultiSelect' | transloco\"\r\n />\r\n @if (isTesting()) {\r\n <span class=\"text-xs text-surface-400\">\r\n {{ \"properties.form.messageTesting\" | transloco }}\r\n </span>\r\n }\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: 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", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: ToggleField, selector: "mt-toggle-field", inputs: ["label", "labelPosition", "placeholder", "readonly", "pInputs", "required", "toggleShape", "size", "icon", "descriptionCard"], 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"] }, { kind: "ngmodule", type: TranslocoModule }, { kind: "pipe", type: i1.TranslocoPipe, name: "transloco" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1433
+ ], ngImport: i0, template: "<div [formGroup]=\"form\" class=\"space-y-6\">\n <div class=\"space-y-4 rounded-xl bg-content 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]=\"'properties.form.endpoint' | transloco\"\n [placeholder]=\"'properties.form.endpointPlaceholder' | transloco\"\n />\n <div class=\"flex justify-end gap-2\">\n <mt-button\n type=\"button\"\n [text]=\"true\"\n icon=\"general.plus\"\n [label]=\"'properties.form.addHeader' | transloco\"\n (click)=\"addHeader()\"\n />\n <mt-button\n type=\"button\"\n [label]=\"'properties.form.testApi' | transloco\"\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\">\n {{ \"properties.form.headers\" | transloco }}\n </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\n formControlName=\"key\"\n [label]=\"'properties.form.headerKey' | transloco\"\n />\n <mt-text-field\n formControlName=\"value\"\n [label]=\"'properties.form.headerValue' | transloco\"\n />\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 {{ \"properties.form.noHeadersMessage\" | transloco }}\n </p>\n }\n </div>\n\n <div class=\"space-y-4 rounded-xl bg-content 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]=\"resolvedApiProperties()\"\n [showClear]=\"true\"\n optionLabel=\"name\"\n optionValue=\"key\"\n [label]=\"'properties.form.keyField' | transloco\"\n />\n <mt-select-field\n formControlName=\"value\"\n [options]=\"resolvedApiProperties()\"\n [showClear]=\"true\"\n optionLabel=\"name\"\n optionValue=\"key\"\n [label]=\"'properties.form.valueField' | transloco\"\n />\n </div>\n } @else {\n <p class=\"text-xs text-surface-400\">\n {{ \"properties.form.messageTestApiPrompt\" | transloco }}\n </p>\n }\n\n <div class=\"flex items-center justify-between gap-4\">\n <mt-toggle-field\n formControlName=\"supportMultiSelect\"\n [label]=\"'properties.form.labelSupportMultiSelect' | transloco\"\n />\n @if (isTesting()) {\n <span class=\"text-xs text-surface-400\">\n {{ \"properties.form.messageTesting\" | transloco }}\n </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],[formArray],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", "group", "size", "optionGroupLabel", "optionGroupChildren", "loading", "optionIcon", "optionIconColor", "optionIconShape", "optionAvatarShape", "optionGroupIcon", "optionGroupIconColor", "optionGroupIconShape", "optionGroupAvatarShape"], outputs: ["onChange"] }, { kind: "component", type: ToggleField, selector: "mt-toggle-field", inputs: ["label", "labelPosition", "placeholder", "readonly", "pInputs", "required", "toggleShape", "size", "icon", "descriptionCard"], 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"] }, { kind: "ngmodule", type: TranslocoModule }, { kind: "pipe", type: i2.TranslocoPipe, name: "transloco" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1197
1434
  }
1198
1435
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: ApiConfiguration, decorators: [{
1199
1436
  type: Component,
@@ -1216,7 +1453,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
1216
1453
  useExisting: forwardRef(() => ApiConfiguration),
1217
1454
  multi: true,
1218
1455
  },
1219
- ], template: "<div [formGroup]=\"form\" class=\"space-y-6\">\r\n <div class=\"space-y-4 rounded-xl bg-content px-6 py-4 shadow-sm\">\r\n <div class=\"grid items-end gap-3 md:grid-cols-[minmax(0,1fr)_auto]\">\r\n <mt-text-field\r\n formControlName=\"endpoint\"\r\n [label]=\"'properties.form.endpoint' | transloco\"\r\n [placeholder]=\"'properties.form.endpointPlaceholder' | transloco\"\r\n />\r\n <div class=\"flex justify-end gap-2\">\r\n <mt-button\r\n type=\"button\"\r\n [text]=\"true\"\r\n icon=\"general.plus\"\r\n [label]=\"'properties.form.addHeader' | transloco\"\r\n (click)=\"addHeader()\"\r\n />\r\n <mt-button\r\n type=\"button\"\r\n [label]=\"'properties.form.testApi' | transloco\"\r\n [loading]=\"isTesting()\"\r\n (click)=\"testApi()\"\r\n />\r\n </div>\r\n </div>\r\n\r\n @if (headers.controls.length) {\r\n <div class=\"space-y-3\">\r\n <div class=\"text-sm font-medium text-surface-500\">\r\n {{ \"properties.form.headers\" | transloco }}\r\n </div>\r\n <div class=\"space-y-3\">\r\n @for (\r\n headerCtrl of headers.controls;\r\n track headerCtrl;\r\n let i = $index\r\n ) {\r\n <div\r\n [formGroup]=\"headerCtrl\"\r\n class=\"grid items-end gap-3 md:grid-cols-[minmax(0,1fr)_minmax(0,1fr)_auto]\"\r\n >\r\n <mt-text-field\r\n formControlName=\"key\"\r\n [label]=\"'properties.form.headerKey' | transloco\"\r\n />\r\n <mt-text-field\r\n formControlName=\"value\"\r\n [label]=\"'properties.form.headerValue' | transloco\"\r\n />\r\n <mt-button\r\n type=\"button\"\r\n [text]=\"true\"\r\n icon=\"general.trash-01\"\r\n (click)=\"removeHeader(i)\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n } @else {\r\n <p class=\"text-xs text-surface-400\">\r\n {{ \"properties.form.noHeadersMessage\" | transloco }}\r\n </p>\r\n }\r\n </div>\r\n\r\n <div class=\"space-y-4 rounded-xl bg-content px-6 py-4 shadow-sm\">\r\n @if (hasDetectedSchema()) {\r\n <div class=\"grid gap-4 md:grid-cols-2\">\r\n <mt-select-field\r\n formControlName=\"key\"\r\n [options]=\"apiProperties()\"\r\n [showClear]=\"true\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n [label]=\"'properties.form.keyField' | transloco\"\r\n />\r\n <mt-select-field\r\n formControlName=\"value\"\r\n [options]=\"apiProperties()\"\r\n [showClear]=\"true\"\r\n optionLabel=\"name\"\r\n optionValue=\"key\"\r\n [label]=\"'properties.form.valueField' | transloco\"\r\n />\r\n </div>\r\n } @else {\r\n <p class=\"text-xs text-surface-400\">\r\n {{ \"properties.form.messageTestApiPrompt\" | transloco }}\r\n </p>\r\n }\r\n\r\n <div class=\"flex items-center justify-between gap-4\">\r\n <mt-toggle-field\r\n formControlName=\"supportMultiSelect\"\r\n [label]=\"'properties.form.labelSupportMultiSelect' | transloco\"\r\n />\r\n @if (isTesting()) {\r\n <span class=\"text-xs text-surface-400\">\r\n {{ \"properties.form.messageTesting\" | transloco }}\r\n </span>\r\n }\r\n </div>\r\n </div>\r\n</div>\r\n" }]
1456
+ ], template: "<div [formGroup]=\"form\" class=\"space-y-6\">\n <div class=\"space-y-4 rounded-xl bg-content 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]=\"'properties.form.endpoint' | transloco\"\n [placeholder]=\"'properties.form.endpointPlaceholder' | transloco\"\n />\n <div class=\"flex justify-end gap-2\">\n <mt-button\n type=\"button\"\n [text]=\"true\"\n icon=\"general.plus\"\n [label]=\"'properties.form.addHeader' | transloco\"\n (click)=\"addHeader()\"\n />\n <mt-button\n type=\"button\"\n [label]=\"'properties.form.testApi' | transloco\"\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\">\n {{ \"properties.form.headers\" | transloco }}\n </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\n formControlName=\"key\"\n [label]=\"'properties.form.headerKey' | transloco\"\n />\n <mt-text-field\n formControlName=\"value\"\n [label]=\"'properties.form.headerValue' | transloco\"\n />\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 {{ \"properties.form.noHeadersMessage\" | transloco }}\n </p>\n }\n </div>\n\n <div class=\"space-y-4 rounded-xl bg-content 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]=\"resolvedApiProperties()\"\n [showClear]=\"true\"\n optionLabel=\"name\"\n optionValue=\"key\"\n [label]=\"'properties.form.keyField' | transloco\"\n />\n <mt-select-field\n formControlName=\"value\"\n [options]=\"resolvedApiProperties()\"\n [showClear]=\"true\"\n optionLabel=\"name\"\n optionValue=\"key\"\n [label]=\"'properties.form.valueField' | transloco\"\n />\n </div>\n } @else {\n <p class=\"text-xs text-surface-400\">\n {{ \"properties.form.messageTestApiPrompt\" | transloco }}\n </p>\n }\n\n <div class=\"flex items-center justify-between gap-4\">\n <mt-toggle-field\n formControlName=\"supportMultiSelect\"\n [label]=\"'properties.form.labelSupportMultiSelect' | transloco\"\n />\n @if (isTesting()) {\n <span class=\"text-xs text-surface-400\">\n {{ \"properties.form.messageTesting\" | transloco }}\n </span>\n }\n </div>\n </div>\n</div>\n" }]
1220
1457
  }], ctorParameters: () => [] });
1221
1458
 
1222
1459
  class CheckListFormConfiguration {
@@ -1247,10 +1484,11 @@ class CheckListFormConfiguration {
1247
1484
  key: 'lookup',
1248
1485
  type: 'select',
1249
1486
  label: this.transloco.translate('properties.form.selectLookup'),
1250
- optionLabel: 'name',
1487
+ optionLabel: 'name.display',
1251
1488
  optionValue: 'id',
1252
1489
  filter: true,
1253
1490
  options: this.lookups(),
1491
+ validators: [ValidatorConfig.required()],
1254
1492
  },
1255
1493
  {
1256
1494
  key: 'scopeId',
@@ -1260,6 +1498,7 @@ class CheckListFormConfiguration {
1260
1498
  optionValue: 'id',
1261
1499
  options: this.scopeItems(),
1262
1500
  filter: true,
1501
+ validators: [ValidatorConfig.required()],
1263
1502
  },
1264
1503
  new PickListFieldConfig({
1265
1504
  key: 'properties',
@@ -1269,6 +1508,7 @@ class CheckListFormConfiguration {
1269
1508
  optionValue: 'key',
1270
1509
  sourceHeader: this.transloco.translate('properties.form.availableProperties'),
1271
1510
  targetHeader: this.transloco.translate('properties.form.selectedProperties'),
1511
+ validators: [ValidatorConfig.required()],
1272
1512
  }),
1273
1513
  ],
1274
1514
  },
@@ -1294,7 +1534,7 @@ class CheckListFormConfiguration {
1294
1534
  this.propertiesFacade.resetConfigProperties();
1295
1535
  }
1296
1536
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: CheckListFormConfiguration, deps: [], target: i0.ɵɵFactoryTarget.Component });
1297
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.3", type: CheckListFormConfiguration, isStandalone: true, selector: "mt-check-list-form-configuration", ngImport: i0, template: "<mt-dynamic-form formControlName=\"configuration\" [formConfig]=\"formConfig()\" />\r\n", styles: [""], dependencies: [{ kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig", "forcedHiddenFieldKeys", "preserveForcedHiddenValues"], outputs: ["runtimeMessagesChange"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }], viewProviders: [
1537
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.3", type: CheckListFormConfiguration, isStandalone: true, selector: "mt-check-list-form-configuration", ngImport: i0, template: "<mt-dynamic-form formControlName=\"configuration\" [formConfig]=\"formConfig()\" />\r\n", styles: [""], dependencies: [{ kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig", "forcedHiddenFieldKeys", "preserveForcedHiddenValues", "visibleSectionKeys"], outputs: ["runtimeMessagesChange"] }, { 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: [
1298
1538
  { provide: ControlContainer, useExisting: FormGroupDirective },
1299
1539
  ] });
1300
1540
  }
@@ -1335,8 +1575,8 @@ class EntityListConfiguration {
1335
1575
  {
1336
1576
  key: 'configuration',
1337
1577
  label: this.transloco.translate('properties.form.configurationSection'),
1338
- cssClass: ' rounded-xl bg-content \
1339
- shadow-sm \
1578
+ cssClass: ' rounded-xl bg-content \
1579
+ shadow-sm \
1340
1580
  px-6 py-4',
1341
1581
  type: 'header',
1342
1582
  bodyClass: 'grid grid-cols-1 md:grid-cols-2 gap-3',
@@ -1349,6 +1589,7 @@ class EntityListConfiguration {
1349
1589
  optionValue: 'id',
1350
1590
  options: this.moduleItems(),
1351
1591
  filter: true,
1592
+ validators: [ValidatorConfig.required()],
1352
1593
  },
1353
1594
  {
1354
1595
  key: 'access',
@@ -1357,6 +1598,7 @@ class EntityListConfiguration {
1357
1598
  optionLabel: 'label',
1358
1599
  optionValue: 'value',
1359
1600
  options: this.accessOptions,
1601
+ validators: [ValidatorConfig.required()],
1360
1602
  },
1361
1603
  {
1362
1604
  key: 'snapshotMode',
@@ -1374,6 +1616,7 @@ class EntityListConfiguration {
1374
1616
  optionValue: 'key',
1375
1617
  sourceHeader: 'Available Read Fields',
1376
1618
  targetHeader: 'Selected Read Fields',
1619
+ validators: [ValidatorConfig.required()],
1377
1620
  }),
1378
1621
  new PickListFieldConfig({
1379
1622
  key: 'writeFields',
@@ -1383,26 +1626,19 @@ class EntityListConfiguration {
1383
1626
  optionValue: 'key',
1384
1627
  sourceHeader: 'Available Write Fields',
1385
1628
  targetHeader: 'Selected Write Fields',
1629
+ validators: [ValidatorConfig.required()],
1386
1630
  relations: [
1387
1631
  { action: 'show', key: 'access', value: 'Write' },
1388
1632
  { action: 'show', key: 'access', value: 'ReadWrite' },
1389
1633
  { action: 'show', key: 'access', value: 'Auto' },
1390
1634
  ],
1391
1635
  }),
1392
- {
1393
- key: 'readFilter',
1394
- type: 'text',
1395
- cssClass: 'md:col-span-2',
1396
- label: 'Read Filter',
1397
- placeholder: 'status == "completed"',
1398
- },
1399
1636
  ],
1400
1637
  },
1401
1638
  ],
1402
1639
  }), ...(ngDevMode ? [{ debugName: "formConfig" }] : []));
1403
1640
  constructor() {
1404
1641
  this.applyEntityListDefaults();
1405
- this.syncLegacyScopeAlias();
1406
1642
  this.loadModuleProperties();
1407
1643
  }
1408
1644
  applyEntityListDefaults() {
@@ -1415,35 +1651,12 @@ class EntityListConfiguration {
1415
1651
  snapshotMode: 'Snapshot',
1416
1652
  readFields: [],
1417
1653
  writeFields: [],
1418
- readFilter: '',
1419
1654
  }, { emitEvent: true });
1420
1655
  }
1421
- syncLegacyScopeAlias() {
1422
- effect(() => {
1423
- const config = this.configuration();
1424
- if (!config || typeof config !== 'object')
1425
- return;
1426
- const moduleId = config.moduleId;
1427
- const scopeId = config.scopeId;
1428
- if ((moduleId === null || moduleId === undefined || moduleId === '') &&
1429
- scopeId !== null &&
1430
- scopeId !== undefined &&
1431
- scopeId !== '') {
1432
- this.configurationControl.patchValue({ ...config, moduleId: scopeId }, { emitEvent: true });
1433
- return;
1434
- }
1435
- if (moduleId !== null &&
1436
- moduleId !== undefined &&
1437
- moduleId !== '' &&
1438
- moduleId !== scopeId) {
1439
- this.configurationControl.patchValue({ ...config, scopeId: moduleId }, { emitEvent: true });
1440
- }
1441
- });
1442
- }
1443
1656
  loadModuleProperties() {
1444
1657
  effect(() => {
1445
1658
  const config = this.configuration();
1446
- const moduleId = config?.moduleId ?? config?.scopeId;
1659
+ const moduleId = config?.moduleId;
1447
1660
  if (!moduleId || moduleId === this.previousModuleId()) {
1448
1661
  return;
1449
1662
  }
@@ -1459,7 +1672,7 @@ class EntityListConfiguration {
1459
1672
  this.propertiesFacade.resetConfigProperties();
1460
1673
  }
1461
1674
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: EntityListConfiguration, deps: [], target: i0.ɵɵFactoryTarget.Component });
1462
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.3", type: EntityListConfiguration, isStandalone: true, selector: "mt-entity-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", "forcedHiddenFieldKeys", "preserveForcedHiddenValues"], outputs: ["runtimeMessagesChange"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }], viewProviders: [
1675
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.3", type: EntityListConfiguration, isStandalone: true, selector: "mt-entity-list-configuration", ngImport: i0, template: "<mt-dynamic-form formControlName=\"configuration\" [formConfig]=\"formConfig()\" />\r\n", styles: [""], dependencies: [{ kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig", "forcedHiddenFieldKeys", "preserveForcedHiddenValues", "visibleSectionKeys"], outputs: ["runtimeMessagesChange"] }, { 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: [
1463
1676
  { provide: ControlContainer, useExisting: FormGroupDirective },
1464
1677
  ] });
1465
1678
  }
@@ -1467,7 +1680,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
1467
1680
  type: Component,
1468
1681
  args: [{ selector: 'mt-entity-list-configuration', imports: [DynamicForm, ReactiveFormsModule], viewProviders: [
1469
1682
  { provide: ControlContainer, useExisting: FormGroupDirective },
1470
- ], template: "<mt-dynamic-form formControlName=\"configuration\" [formConfig]=\"formConfig()\" />\n" }]
1683
+ ], template: "<mt-dynamic-form formControlName=\"configuration\" [formConfig]=\"formConfig()\" />\r\n" }]
1471
1684
  }], ctorParameters: () => [] });
1472
1685
 
1473
1686
  class LocationConfiguration {
@@ -1493,6 +1706,7 @@ class LocationConfiguration {
1493
1706
  optionValue: 'name',
1494
1707
  options: this.countries(),
1495
1708
  filter: true,
1709
+ validators: [ValidatorConfig.required()],
1496
1710
  },
1497
1711
  ],
1498
1712
  },
@@ -1506,7 +1720,7 @@ class LocationConfiguration {
1506
1720
  });
1507
1721
  }
1508
1722
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: LocationConfiguration, deps: [], target: i0.ɵɵFactoryTarget.Component });
1509
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.3", type: LocationConfiguration, isStandalone: true, selector: "mt-location-configuration", ngImport: i0, template: "<mt-dynamic-form formControlName=\"configuration\" [formConfig]=\"formConfig()\" />\r\n", styles: [""], dependencies: [{ kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig", "forcedHiddenFieldKeys", "preserveForcedHiddenValues"], outputs: ["runtimeMessagesChange"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }], viewProviders: [
1723
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.3", type: LocationConfiguration, isStandalone: true, selector: "mt-location-configuration", ngImport: i0, template: "<mt-dynamic-form formControlName=\"configuration\" [formConfig]=\"formConfig()\" />\r\n", styles: [""], dependencies: [{ kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig", "forcedHiddenFieldKeys", "preserveForcedHiddenValues", "visibleSectionKeys"], outputs: ["runtimeMessagesChange"] }, { 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: [
1510
1724
  { provide: ControlContainer, useExisting: FormGroupDirective },
1511
1725
  ] });
1512
1726
  }
@@ -1540,6 +1754,7 @@ class LookupConfiguration {
1540
1754
  optionValue: 'id',
1541
1755
  options: this.lookups(),
1542
1756
  filter: true,
1757
+ validators: [ValidatorConfig.required()],
1543
1758
  },
1544
1759
  ],
1545
1760
  },
@@ -1553,7 +1768,7 @@ class LookupConfiguration {
1553
1768
  });
1554
1769
  }
1555
1770
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: LookupConfiguration, deps: [], target: i0.ɵɵFactoryTarget.Component });
1556
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.3", type: LookupConfiguration, isStandalone: true, selector: "mt-lookup-configuration", ngImport: i0, template: "<mt-dynamic-form formControlName=\"configuration\" [formConfig]=\"formConfig()\" />\r\n", styles: [""], dependencies: [{ kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig", "forcedHiddenFieldKeys", "preserveForcedHiddenValues"], outputs: ["runtimeMessagesChange"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }], viewProviders: [
1771
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.3", type: LookupConfiguration, isStandalone: true, selector: "mt-lookup-configuration", ngImport: i0, template: "<mt-dynamic-form formControlName=\"configuration\" [formConfig]=\"formConfig()\" />\r\n", styles: [""], dependencies: [{ kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig", "forcedHiddenFieldKeys", "preserveForcedHiddenValues", "visibleSectionKeys"], outputs: ["runtimeMessagesChange"] }, { 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: [
1557
1772
  { provide: ControlContainer, useExisting: FormGroupDirective },
1558
1773
  ] });
1559
1774
  }
@@ -1587,7 +1802,7 @@ class PercentageConfiguration {
1587
1802
  ],
1588
1803
  }, ...(ngDevMode ? [{ debugName: "formConfig" }] : []));
1589
1804
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: PercentageConfiguration, deps: [], target: i0.ɵɵFactoryTarget.Component });
1590
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.3", type: PercentageConfiguration, isStandalone: true, selector: "mt-percentage-configuration", ngImport: i0, template: "<mt-dynamic-form formControlName=\"configuration\" [formConfig]=\"formConfig()\" />\r\n", styles: [""], dependencies: [{ kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig", "forcedHiddenFieldKeys", "preserveForcedHiddenValues"], outputs: ["runtimeMessagesChange"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }], viewProviders: [
1805
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.3", type: PercentageConfiguration, isStandalone: true, selector: "mt-percentage-configuration", ngImport: i0, template: "<mt-dynamic-form formControlName=\"configuration\" [formConfig]=\"formConfig()\" />\r\n", styles: [""], dependencies: [{ kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig", "forcedHiddenFieldKeys", "preserveForcedHiddenValues", "visibleSectionKeys"], outputs: ["runtimeMessagesChange"] }, { 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: [
1591
1806
  { provide: ControlContainer, useExisting: FormGroupDirective },
1592
1807
  ] });
1593
1808
  }
@@ -1598,6 +1813,344 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
1598
1813
  ], template: "<mt-dynamic-form formControlName=\"configuration\" [formConfig]=\"formConfig()\" />\r\n" }]
1599
1814
  }] });
1600
1815
 
1816
+ class StatusItemForm {
1817
+ modal = inject(ModalService);
1818
+ ref = inject(ModalRef);
1819
+ facade = inject(PropertiesFacade);
1820
+ transloco = inject(TranslocoService);
1821
+ propertyId = input.required(...(ngDevMode ? [{ debugName: "propertyId" }] : []));
1822
+ levelSchemaId = input(undefined, ...(ngDevMode ? [{ debugName: "levelSchemaId" }] : []));
1823
+ statusData = input(null, ...(ngDevMode ? [{ debugName: "statusData" }] : []));
1824
+ editMode = computed(() => !!this.statusData(), ...(ngDevMode ? [{ debugName: "editMode" }] : []));
1825
+ isSubmitting = computed(() => this.editMode()
1826
+ ? this.facade.isUpdatingPropertyStatus()
1827
+ : this.facade.isCreatingPropertyStatus(), ...(ngDevMode ? [{ debugName: "isSubmitting" }] : []));
1828
+ buttonLabel = computed(() => this.editMode()
1829
+ ? this.transloco.translate('properties.form.statusUpdateButton')
1830
+ : this.transloco.translate('properties.form.statusCreateButton'), ...(ngDevMode ? [{ debugName: "buttonLabel" }] : []));
1831
+ statusFormConfig = linkedSignal(() => ({
1832
+ sections: [
1833
+ {
1834
+ key: 'statusItemForm',
1835
+ type: 'header',
1836
+ columns: 12,
1837
+ fields: [
1838
+ {
1839
+ key: 'display.en',
1840
+ colSpan: 6,
1841
+ label: this.transloco.translate('properties.form.statusEnglishDisplay'),
1842
+ validators: [ValidatorConfig.required()],
1843
+ },
1844
+ {
1845
+ key: 'display.ar',
1846
+ colSpan: 6,
1847
+ label: this.transloco.translate('properties.form.statusArabicDisplay'),
1848
+ validators: [ValidatorConfig.required()],
1849
+ },
1850
+ {
1851
+ key: 'description.en',
1852
+ type: 'textarea',
1853
+ colSpan: 6,
1854
+ label: this.transloco.translate('properties.form.statusEnglishDescription'),
1855
+ },
1856
+ {
1857
+ key: 'description.ar',
1858
+ type: 'textarea',
1859
+ colSpan: 6,
1860
+ label: this.transloco.translate('properties.form.statusArabicDescription'),
1861
+ },
1862
+ {
1863
+ key: 'type',
1864
+ type: 'select',
1865
+ colSpan: 4,
1866
+ label: this.transloco.translate('properties.form.statusType'),
1867
+ optionLabel: 'label',
1868
+ optionValue: 'value',
1869
+ options: [
1870
+ { label: 'Performance', value: 'Performance' },
1871
+ { label: 'NonePerformance', value: 'NonePerformance' },
1872
+ ],
1873
+ },
1874
+ new ColorPickerFieldConfig({
1875
+ key: 'color',
1876
+ colSpan: 4,
1877
+ label: this.transloco.translate('properties.form.statusColor'),
1878
+ }),
1879
+ new IconFieldConfig({
1880
+ key: 'icon',
1881
+ colSpan: 4,
1882
+ label: this.transloco.translate('properties.form.statusIcon'),
1883
+ }),
1884
+ ],
1885
+ },
1886
+ ],
1887
+ }), ...(ngDevMode ? [{ debugName: "statusFormConfig" }] : []));
1888
+ statusFormControl = new FormControl({
1889
+ display: {
1890
+ en: '',
1891
+ ar: '',
1892
+ },
1893
+ description: {
1894
+ en: '',
1895
+ ar: '',
1896
+ },
1897
+ type: 'Performance',
1898
+ color: '#64748b',
1899
+ icon: '',
1900
+ }, { nonNullable: true });
1901
+ formulaControl = new FormControl(null);
1902
+ statusType = toSignal(this.statusFormControl.valueChanges.pipe(startWith(this.statusFormControl.value), map((value) => value?.type ?? 'Performance')), {
1903
+ initialValue: this.statusFormControl.value?.type ?? 'Performance',
1904
+ });
1905
+ showFormula = computed(() => this.statusType() === 'Performance', ...(ngDevMode ? [{ debugName: "showFormula" }] : []));
1906
+ constructor() {
1907
+ effect(() => {
1908
+ if (this.showFormula()) {
1909
+ this.formulaControl.setValidators(Validators.required);
1910
+ }
1911
+ else {
1912
+ this.formulaControl.clearValidators();
1913
+ }
1914
+ this.formulaControl.updateValueAndValidity({ emitEvent: false });
1915
+ });
1916
+ effect(() => {
1917
+ const status = this.statusData();
1918
+ if (!status) {
1919
+ this.statusFormControl.patchValue({
1920
+ display: {
1921
+ en: '',
1922
+ ar: '',
1923
+ },
1924
+ description: {
1925
+ en: '',
1926
+ ar: '',
1927
+ },
1928
+ type: 'Performance',
1929
+ color: '#64748b',
1930
+ icon: '',
1931
+ }, {
1932
+ emitEvent: false,
1933
+ });
1934
+ this.formulaControl.patchValue(null, {
1935
+ emitEvent: false,
1936
+ });
1937
+ return;
1938
+ }
1939
+ this.statusFormControl.patchValue({
1940
+ display: {
1941
+ en: status.display?.['en'] ?? '',
1942
+ ar: status.display?.['ar'] ?? '',
1943
+ },
1944
+ description: {
1945
+ en: status.description?.['en'] ?? '',
1946
+ ar: status.description?.['ar'] ?? '',
1947
+ },
1948
+ type: status.type ?? 'Performance',
1949
+ color: status.color ?? '#64748b',
1950
+ icon: status.icon ?? '',
1951
+ }, { emitEvent: false });
1952
+ this.formulaControl.patchValue(status.formula, {
1953
+ emitEvent: false,
1954
+ });
1955
+ });
1956
+ }
1957
+ onSubmit() {
1958
+ if (this.statusFormControl.invalid || this.isSubmitting()) {
1959
+ this.statusFormControl.markAllAsTouched();
1960
+ return;
1961
+ }
1962
+ if (this.showFormula() && this.formulaControl.invalid) {
1963
+ this.formulaControl.markAsTouched();
1964
+ return;
1965
+ }
1966
+ const value = this.statusFormControl.value;
1967
+ const payload = {
1968
+ type: value.type,
1969
+ display: value.display,
1970
+ description: value.description,
1971
+ color: value.color,
1972
+ icon: value.icon,
1973
+ formula: this.showFormula() ? this.formulaControl.value : null,
1974
+ };
1975
+ const request$ = this.editMode() && this.statusData()
1976
+ ? this.facade.updatePropertyStatus(this.propertyId(), this.statusData().id, payload)
1977
+ : this.facade.createPropertyStatus(this.propertyId(), payload);
1978
+ request$.subscribe(() => {
1979
+ this.ref.close({ success: true });
1980
+ });
1981
+ }
1982
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: StatusItemForm, deps: [], target: i0.ɵɵFactoryTarget.Component });
1983
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: StatusItemForm, isStandalone: true, selector: "mt-status-item-form", inputs: { propertyId: { classPropertyName: "propertyId", publicName: "propertyId", isSignal: true, isRequired: true, transformFunction: null }, levelSchemaId: { classPropertyName: "levelSchemaId", publicName: "levelSchemaId", isSignal: true, isRequired: false, transformFunction: null }, statusData: { classPropertyName: "statusData", publicName: "statusData", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div\n [class]=\"\n 'flex max-h-[75vh] flex-col gap-4 overflow-y-auto p-4 my-4 ' +\n modal.contentClass\n \"\n>\n <form class=\"space-y-6\">\n <mt-dynamic-form\n class=\"block\"\n [formConfig]=\"statusFormConfig()\"\n [formControl]=\"statusFormControl\"\n />\n\n @if (showFormula()) {\n <div class=\"rounded-xl border border-surface-200 bg-content px-4 py-4\">\n <div class=\"mb-3 text-sm font-medium text-surface-700\">\n {{ \"properties.form.statusFormula\" | transloco }}\n </div>\n\n <mt-formula-builder\n [formControl]=\"formulaControl\"\n [levelSchemaId]=\"levelSchemaId()\"\n />\n </div>\n }\n </form>\n</div>\n\n<div [class]=\"modal.footerClass\" class=\"mt-7\">\n <mt-button\n [label]=\"buttonLabel()\"\n (click)=\"onSubmit()\"\n [loading]=\"isSubmitting()\"\n [disabled]=\"\n statusFormControl.invalid ||\n (showFormula() && formulaControl.invalid) ||\n isSubmitting()\n \"\n />\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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", "forcedHiddenFieldKeys", "preserveForcedHiddenValues", "visibleSectionKeys"], outputs: ["runtimeMessagesChange"] }, { kind: "component", type: FormulaBuilder, selector: "mt-formula-builder", inputs: ["propertiesByPath", "levelSchemaId", "templateId", "placeholder", "hideToolbar", "hideStatusBar"], outputs: ["validationChange", "tokensChange"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: TranslocoModule }, { kind: "pipe", type: i2.TranslocoPipe, name: "transloco" }] });
1984
+ }
1985
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: StatusItemForm, decorators: [{
1986
+ type: Component,
1987
+ args: [{ selector: 'mt-status-item-form', standalone: true, imports: [
1988
+ CommonModule,
1989
+ Button,
1990
+ DynamicForm,
1991
+ FormulaBuilder,
1992
+ ReactiveFormsModule,
1993
+ TranslocoModule,
1994
+ ], template: "<div\n [class]=\"\n 'flex max-h-[75vh] flex-col gap-4 overflow-y-auto p-4 my-4 ' +\n modal.contentClass\n \"\n>\n <form class=\"space-y-6\">\n <mt-dynamic-form\n class=\"block\"\n [formConfig]=\"statusFormConfig()\"\n [formControl]=\"statusFormControl\"\n />\n\n @if (showFormula()) {\n <div class=\"rounded-xl border border-surface-200 bg-content px-4 py-4\">\n <div class=\"mb-3 text-sm font-medium text-surface-700\">\n {{ \"properties.form.statusFormula\" | transloco }}\n </div>\n\n <mt-formula-builder\n [formControl]=\"formulaControl\"\n [levelSchemaId]=\"levelSchemaId()\"\n />\n </div>\n }\n </form>\n</div>\n\n<div [class]=\"modal.footerClass\" class=\"mt-7\">\n <mt-button\n [label]=\"buttonLabel()\"\n (click)=\"onSubmit()\"\n [loading]=\"isSubmitting()\"\n [disabled]=\"\n statusFormControl.invalid ||\n (showFormula() && formulaControl.invalid) ||\n isSubmitting()\n \"\n />\n</div>\n" }]
1995
+ }], ctorParameters: () => [], propDecorators: { propertyId: [{ type: i0.Input, args: [{ isSignal: true, alias: "propertyId", required: true }] }], levelSchemaId: [{ type: i0.Input, args: [{ isSignal: true, alias: "levelSchemaId", required: false }] }], statusData: [{ type: i0.Input, args: [{ isSignal: true, alias: "statusData", required: false }] }] } });
1996
+
1997
+ class StatusConfiguration {
1998
+ facade = inject(PropertiesFacade);
1999
+ modalService = inject(ModalService);
2000
+ transloco = inject(TranslocoService);
2001
+ lastLoadedPropertyId = signal(null, ...(ngDevMode ? [{ debugName: "lastLoadedPropertyId" }] : []));
2002
+ propertyId = input(null, ...(ngDevMode ? [{ debugName: "propertyId" }] : []));
2003
+ levelSchemaId = input(undefined, ...(ngDevMode ? [{ debugName: "levelSchemaId" }] : []));
2004
+ deletingRowIds = signal([], ...(ngDevMode ? [{ debugName: "deletingRowIds" }] : []));
2005
+ statuses = computed(() => [...this.facade.propertyStatuses()].sort((left, right) => {
2006
+ const leftOrder = left.order ?? Number.MAX_SAFE_INTEGER;
2007
+ const rightOrder = right.order ?? Number.MAX_SAFE_INTEGER;
2008
+ if (leftOrder !== rightOrder) {
2009
+ return leftOrder - rightOrder;
2010
+ }
2011
+ return left.id - right.id;
2012
+ }), ...(ngDevMode ? [{ debugName: "statuses" }] : []));
2013
+ loading = this.facade.isLoadingPropertyStatuses;
2014
+ reordering = this.facade.isReorderingPropertyStatuses;
2015
+ resolvedPropertyId = computed(() => this.normalizePropertyId(this.propertyId()), ...(ngDevMode ? [{ debugName: "resolvedPropertyId" }] : []));
2016
+ canManageStatuses = computed(() => !!this.resolvedPropertyId(), ...(ngDevMode ? [{ debugName: "canManageStatuses" }] : []));
2017
+ tableColumns = linkedSignal(() => [
2018
+ {
2019
+ key: 'display.en',
2020
+ label: this.transloco.translate('properties.form.statusColumnDisplay'),
2021
+ },
2022
+ {
2023
+ key: 'key',
2024
+ label: this.transloco.translate('properties.form.statusColumnKey'),
2025
+ },
2026
+ {
2027
+ key: 'type',
2028
+ label: this.transloco.translate('properties.form.statusColumnType'),
2029
+ },
2030
+ {
2031
+ key: 'color',
2032
+ label: this.transloco.translate('properties.form.statusColumnColor'),
2033
+ },
2034
+ {
2035
+ key: 'icon',
2036
+ label: this.transloco.translate('properties.form.statusColumnIcon'),
2037
+ },
2038
+ ], ...(ngDevMode ? [{ debugName: "tableColumns" }] : []));
2039
+ tableActions = computed(() => {
2040
+ if (!this.canManageStatuses()) {
2041
+ return [];
2042
+ }
2043
+ return [
2044
+ {
2045
+ icon: 'general.plus',
2046
+ label: this.transloco.translate('properties.form.statusAddAction'),
2047
+ color: 'primary',
2048
+ action: () => this.openStatusDialog(),
2049
+ },
2050
+ ];
2051
+ }, ...(ngDevMode ? [{ debugName: "tableActions" }] : []));
2052
+ rowActions = computed(() => {
2053
+ const propertyId = this.resolvedPropertyId();
2054
+ if (!propertyId) {
2055
+ return [];
2056
+ }
2057
+ return [
2058
+ {
2059
+ icon: 'custom.pencil',
2060
+ tooltip: this.transloco.translate('properties.form.statusEditAction'),
2061
+ color: 'primary',
2062
+ action: (row) => this.openStatusDialog(row),
2063
+ },
2064
+ {
2065
+ icon: 'general.trash-01',
2066
+ tooltip: this.transloco.translate('properties.form.statusDeleteAction'),
2067
+ color: 'danger',
2068
+ variant: 'outlined',
2069
+ action: (row) => this.deleteStatus(row),
2070
+ confirmation: {
2071
+ type: 'popup',
2072
+ confirmationType: 'delete',
2073
+ },
2074
+ loading: (row) => this.deletingRowIds().includes(row.id),
2075
+ },
2076
+ ];
2077
+ }, ...(ngDevMode ? [{ debugName: "rowActions" }] : []));
2078
+ constructor() {
2079
+ effect(() => {
2080
+ const propertyId = this.resolvedPropertyId();
2081
+ if (!propertyId) {
2082
+ this.lastLoadedPropertyId.set(null);
2083
+ this.facade.resetPropertyStatuses().subscribe();
2084
+ return;
2085
+ }
2086
+ if (this.lastLoadedPropertyId() === propertyId) {
2087
+ return;
2088
+ }
2089
+ this.lastLoadedPropertyId.set(propertyId);
2090
+ this.facade.resetPropertyStatuses().subscribe();
2091
+ this.facade.loadPropertyStatuses(propertyId).subscribe();
2092
+ });
2093
+ }
2094
+ ngOnDestroy() {
2095
+ this.facade.resetPropertyStatuses().subscribe();
2096
+ }
2097
+ openStatusDialog(statusData = null) {
2098
+ const propertyId = this.resolvedPropertyId();
2099
+ if (!propertyId) {
2100
+ return;
2101
+ }
2102
+ this.modalService.openModal(StatusItemForm, 'dialog', {
2103
+ header: statusData
2104
+ ? this.transloco.translate('properties.form.statusEditTitle')
2105
+ : this.transloco.translate('properties.form.statusCreateTitle'),
2106
+ styleClass: '!w-[72vw] max-w-6xl',
2107
+ appendTo: 'body',
2108
+ dismissableMask: true,
2109
+ inputValues: {
2110
+ propertyId,
2111
+ levelSchemaId: this.levelSchemaId(),
2112
+ statusData,
2113
+ },
2114
+ });
2115
+ }
2116
+ deleteStatus(status) {
2117
+ const propertyId = this.resolvedPropertyId();
2118
+ if (!propertyId || !status?.id) {
2119
+ return;
2120
+ }
2121
+ this.deletingRowIds.update((ids) => [...ids, status.id]);
2122
+ this.facade
2123
+ .deletePropertyStatus(propertyId, status.id)
2124
+ .pipe(finalize(() => {
2125
+ this.deletingRowIds.update((ids) => ids.filter((id) => id !== status.id));
2126
+ }))
2127
+ .subscribe();
2128
+ }
2129
+ onRowReorder(event) {
2130
+ const reordered = Array.isArray(event.value)
2131
+ ? event.value
2132
+ : this.statuses();
2133
+ const orders = reordered.map((status, index) => ({
2134
+ statusId: status.id,
2135
+ order: index + 1,
2136
+ }));
2137
+ this.facade.reorderPropertyStatuses({ orders }).subscribe();
2138
+ }
2139
+ normalizePropertyId(value) {
2140
+ if (value === null || value === undefined || value === '') {
2141
+ return null;
2142
+ }
2143
+ const parsed = typeof value === 'string' ? Number(value) : value;
2144
+ return Number.isFinite(parsed) ? parsed : null;
2145
+ }
2146
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: StatusConfiguration, deps: [], target: i0.ɵɵFactoryTarget.Component });
2147
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: StatusConfiguration, isStandalone: true, selector: "mt-status-configuration", inputs: { propertyId: { classPropertyName: "propertyId", publicName: "propertyId", isSignal: true, isRequired: false, transformFunction: null }, levelSchemaId: { classPropertyName: "levelSchemaId", publicName: "levelSchemaId", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<mt-card [title]=\"'properties.form.statusesSection' | transloco\">\n @if (canManageStatuses()) {\n <mt-table\n [data]=\"statuses()\"\n [columns]=\"tableColumns()\"\n [actions]=\"tableActions()\"\n [rowActions]=\"rowActions()\"\n [generalSearch]=\"true\"\n [loading]=\"loading()\"\n [updating]=\"reordering()\"\n [reorderableRows]=\"true\"\n dataKey=\"id\"\n (rowReorder)=\"onRowReorder($event)\"\n />\n } @else {\n <div\n class=\"rounded-xl border border-dashed border-surface-300 bg-surface-50 px-4 py-6 text-sm text-surface-600\"\n >\n {{ \"properties.form.statusesSavePrompt\" | transloco }}\n </div>\n }\n</mt-card>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "component", type: Table, selector: "mt-table", inputs: ["filters", "data", "columns", "rowActions", "size", "showGridlines", "stripedRows", "selectableRows", "clickableRows", "generalSearch", "showFilters", "loading", "updating", "lazy", "lazyTotalRecords", "reorderableColumns", "reorderableRows", "dataKey", "exportable", "exportFilename", "tabs", "tabsOptionLabel", "tabsOptionValue", "activeTab", "actions", "paginatorPosition", "pageSize", "currentPage", "first", "filterTerm"], outputs: ["selectionChange", "cellChange", "lazyLoad", "columnReorder", "rowReorder", "rowClick", "filtersChange", "activeTabChange", "onTabChange", "pageSizeChange", "currentPageChange", "firstChange", "filterTermChange"] }, { kind: "ngmodule", type: TranslocoModule }, { kind: "pipe", type: i2.TranslocoPipe, name: "transloco" }] });
2148
+ }
2149
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: StatusConfiguration, decorators: [{
2150
+ type: Component,
2151
+ args: [{ selector: 'mt-status-configuration', standalone: true, imports: [CommonModule, Card, Table, TranslocoModule], template: "<mt-card [title]=\"'properties.form.statusesSection' | transloco\">\n @if (canManageStatuses()) {\n <mt-table\n [data]=\"statuses()\"\n [columns]=\"tableColumns()\"\n [actions]=\"tableActions()\"\n [rowActions]=\"rowActions()\"\n [generalSearch]=\"true\"\n [loading]=\"loading()\"\n [updating]=\"reordering()\"\n [reorderableRows]=\"true\"\n dataKey=\"id\"\n (rowReorder)=\"onRowReorder($event)\"\n />\n } @else {\n <div\n class=\"rounded-xl border border-dashed border-surface-300 bg-surface-50 px-4 py-6 text-sm text-surface-600\"\n >\n {{ \"properties.form.statusesSavePrompt\" | transloco }}\n </div>\n }\n</mt-card>\n" }]
2152
+ }], ctorParameters: () => [], propDecorators: { propertyId: [{ type: i0.Input, args: [{ isSignal: true, alias: "propertyId", required: false }] }], levelSchemaId: [{ type: i0.Input, args: [{ isSignal: true, alias: "levelSchemaId", required: false }] }] } });
2153
+
1601
2154
  class UserConfiguration {
1602
2155
  facade = inject(PropertiesFacade);
1603
2156
  transloco = inject(TranslocoService);
@@ -1634,7 +2187,7 @@ class UserConfiguration {
1634
2187
  });
1635
2188
  }
1636
2189
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: UserConfiguration, deps: [], target: i0.ɵɵFactoryTarget.Component });
1637
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.3", type: UserConfiguration, isStandalone: true, selector: "mt-user-configuration", ngImport: i0, template: "<mt-dynamic-form formControlName=\"configuration\" [formConfig]=\"formConfig()\" />\r\n", styles: [""], dependencies: [{ kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig", "forcedHiddenFieldKeys", "preserveForcedHiddenValues"], outputs: ["runtimeMessagesChange"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }], viewProviders: [
2190
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.3", type: UserConfiguration, isStandalone: true, selector: "mt-user-configuration", ngImport: i0, template: "<mt-dynamic-form formControlName=\"configuration\" [formConfig]=\"formConfig()\" />\r\n", styles: [""], dependencies: [{ kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig", "forcedHiddenFieldKeys", "preserveForcedHiddenValues", "visibleSectionKeys"], outputs: ["runtimeMessagesChange"] }, { 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: [
1638
2191
  { provide: ControlContainer, useExisting: FormGroupDirective },
1639
2192
  ] });
1640
2193
  }
@@ -1776,6 +2329,7 @@ class AttachmentConfiguration {
1776
2329
  sourceHeader: this.transloco.translate('properties.form.availableTypes'),
1777
2330
  targetHeader: this.transloco.translate('properties.form.selectedTypes'),
1778
2331
  cssClass: 'md:col-span-2',
2332
+ validators: [ValidatorConfig.required()],
1779
2333
  }),
1780
2334
  {
1781
2335
  key: 'IsMulitple',
@@ -1787,7 +2341,7 @@ class AttachmentConfiguration {
1787
2341
  ],
1788
2342
  }, ...(ngDevMode ? [{ debugName: "formConfig" }] : []));
1789
2343
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: AttachmentConfiguration, deps: [], target: i0.ɵɵFactoryTarget.Component });
1790
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.3", type: AttachmentConfiguration, isStandalone: true, selector: "mt-attachment-configuration", ngImport: i0, template: "<mt-dynamic-form formControlName=\"configuration\" [formConfig]=\"formConfig()\" />\r\n", styles: [""], dependencies: [{ kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig", "forcedHiddenFieldKeys", "preserveForcedHiddenValues"], outputs: ["runtimeMessagesChange"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }], viewProviders: [
2344
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.0.3", type: AttachmentConfiguration, isStandalone: true, selector: "mt-attachment-configuration", ngImport: i0, template: "<mt-dynamic-form formControlName=\"configuration\" [formConfig]=\"formConfig()\" />\r\n", styles: [""], dependencies: [{ kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig", "forcedHiddenFieldKeys", "preserveForcedHiddenValues", "visibleSectionKeys"], outputs: ["runtimeMessagesChange"] }, { 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: [
1791
2345
  { provide: ControlContainer, useExisting: FormGroupDirective },
1792
2346
  ] });
1793
2347
  }
@@ -1828,15 +2382,17 @@ class PropertyForm {
1828
2382
  mainControl = this.propertyForm.get('main');
1829
2383
  configurationControl = this.propertyForm.get('configuration');
1830
2384
  formulaControl = this.propertyForm.get('formula');
2385
+ mainValue = signal(this.mainControl.value, ...(ngDevMode ? [{ debugName: "mainValue" }] : []));
1831
2386
  creating = this.facade.isCreating;
1832
2387
  updating = this.facade.isUpdating;
1833
2388
  loading = this.facade.isLoadingOne;
1834
2389
  submitting = computed(() => this.creating() || this.updating(), ...(ngDevMode ? [{ debugName: "submitting" }] : []));
1835
- propertyType = toSignal(this.mainControl.valueChanges.pipe(map((v) => v?.viewType), distinctUntilChanged()));
1836
- isCalculated = toSignal(this.mainControl.valueChanges.pipe(map((v) => Boolean(v?.isCalculated)), distinctUntilChanged()), {
1837
- initialValue: Boolean(this.mainControl.value?.isCalculated),
1838
- });
2390
+ propertyType = computed(() => this.mainValue()?.viewType ?? null, ...(ngDevMode ? [{ debugName: "propertyType" }] : []));
2391
+ isCalculated = computed(() => Boolean(this.mainValue()?.isCalculated), ...(ngDevMode ? [{ debugName: "isCalculated" }] : []));
1839
2392
  formulaSchemaId = computed(() => this.resolveSchemaId(this.facade.parentModuleId() ?? this.facade.moduleId()), ...(ngDevMode ? [{ debugName: "formulaSchemaId" }] : []));
2393
+ selectedViewType = computed(() => this.propertyType() ??
2394
+ this.facade.selected()?.viewType, ...(ngDevMode ? [{ debugName: "selectedViewType" }] : []));
2395
+ statusPropertyId = computed(() => this.resolveSchemaId(this.facade.selected()?.id ?? this.propertyId()), ...(ngDevMode ? [{ debugName: "statusPropertyId" }] : []));
1840
2396
  availablePropertyTypes = computed(() => {
1841
2397
  const allTypes = this.propertyTypes()?.value ?? [];
1842
2398
  return allTypes.filter((item) => !this.legacyReplacedViewTypes.includes(item?.viewType ?? ''));
@@ -1851,13 +2407,19 @@ class PropertyForm {
1851
2407
  }, ...(ngDevMode ? [{ debugName: "selectedPropertyTypeConfiguration" }] : []));
1852
2408
  configurationFormConfig = computed(() => this.selectedPropertyTypeConfiguration()?.configurationForm ?? null, ...(ngDevMode ? [{ debugName: "configurationFormConfig" }] : []));
1853
2409
  configurationHost;
2410
+ statusConfigurationSection = viewChild('statusConfigurationSection', ...(ngDevMode ? [{ debugName: "statusConfigurationSection" }] : []));
1854
2411
  environmentInjector = inject(EnvironmentInjector);
2412
+ routeFragment = toSignal(this.route.fragment, {
2413
+ initialValue: this.route.snapshot.fragment,
2414
+ });
1855
2415
  configurationComponentType = signal(null, ...(ngDevMode ? [{ debugName: "configurationComponentType" }] : []));
1856
2416
  configurationComponentRef = null;
1857
2417
  configurationComponentLoadId = 0;
1858
2418
  externalConfigurationForm = signal(null, ...(ngDevMode ? [{ debugName: "externalConfigurationForm" }] : []));
1859
- externalConfigurationSubscriptions = null;
2419
+ externalConfigurationSubscriptions = new Subscription();
2420
+ subscriptions = new Subscription();
1860
2421
  externalConfigurationInvalid = signal(false, ...(ngDevMode ? [{ debugName: "externalConfigurationInvalid" }] : []));
2422
+ lastStatusScrollKey = signal(null, ...(ngDevMode ? [{ debugName: "lastStatusScrollKey" }] : []));
1861
2423
  configurationComponentExists = computed(() => !!this.configurationComponentType(), ...(ngDevMode ? [{ debugName: "configurationComponentExists" }] : []));
1862
2424
  configurationFormInvalid = computed(() => this.externalConfigurationInvalid(), ...(ngDevMode ? [{ debugName: "configurationFormInvalid" }] : []));
1863
2425
  submitDisabled = computed(() => this.submitting() || this.configurationFormInvalid(), ...(ngDevMode ? [{ debugName: "submitDisabled" }] : []));
@@ -1926,16 +2488,6 @@ class PropertyForm {
1926
2488
  key: 'viewType',
1927
2489
  value: 'Checkbox',
1928
2490
  },
1929
- {
1930
- action: 'show',
1931
- key: 'viewType',
1932
- value: 'Lookup',
1933
- },
1934
- {
1935
- action: 'show',
1936
- key: 'viewType',
1937
- value: 'LookupMultiSelect',
1938
- },
1939
2491
  {
1940
2492
  action: 'show',
1941
2493
  key: 'viewType',
@@ -1984,6 +2536,7 @@ class PropertyForm {
1984
2536
  ],
1985
2537
  }), ...(ngDevMode ? [{ debugName: "dynamicFormConfigMain" }] : []));
1986
2538
  constructor() {
2539
+ this.subscriptions.add(this.mainControl.valueChanges.subscribe((value) => this.mainValue.set(value)));
1987
2540
  // Load when editing
1988
2541
  effect(() => {
1989
2542
  if (this.propertyId()) {
@@ -2016,10 +2569,7 @@ class PropertyForm {
2016
2569
  // Load config scopes for specific property types
2017
2570
  const supportedTypes = ['EntityList', 'LookupModuleCheckList'];
2018
2571
  if (supportedTypes.includes(currentPropertyType)) {
2019
- const configScopeType = currentPropertyType === 'LookupModuleCheckList'
2020
- ? 'LookupLog'
2021
- : currentPropertyType;
2022
- this.facade.loadConfigAsType(configScopeType);
2572
+ this.facade.loadConfigAsType(currentPropertyType);
2023
2573
  }
2024
2574
  });
2025
2575
  effect(() => {
@@ -2032,6 +2582,34 @@ class PropertyForm {
2032
2582
  effect(() => {
2033
2583
  this.renderConfigurationComponent(this.configurationComponentType());
2034
2584
  });
2585
+ effect(() => {
2586
+ const calculated = this.isCalculated();
2587
+ this.formulaControl.setValidators(calculated ? [Validators.required] : []);
2588
+ this.formulaControl.updateValueAndValidity({ emitEvent: false });
2589
+ });
2590
+ effect(() => {
2591
+ const fragment = this.routeFragment();
2592
+ const section = this.statusConfigurationSection();
2593
+ const propertyId = this.statusPropertyId();
2594
+ const viewType = this.selectedViewType();
2595
+ if (fragment !== 'status-configuration' ||
2596
+ !section ||
2597
+ !propertyId ||
2598
+ viewType !== 'Status') {
2599
+ return;
2600
+ }
2601
+ const scrollKey = `${propertyId}:${fragment}`;
2602
+ if (this.lastStatusScrollKey() === scrollKey) {
2603
+ return;
2604
+ }
2605
+ this.lastStatusScrollKey.set(scrollKey);
2606
+ setTimeout(() => {
2607
+ section.nativeElement.scrollIntoView({
2608
+ behavior: 'smooth',
2609
+ block: 'start',
2610
+ });
2611
+ });
2612
+ });
2035
2613
  }
2036
2614
  renderConfigurationComponent(componentType) {
2037
2615
  if (!this.configurationHost)
@@ -2046,8 +2624,9 @@ class PropertyForm {
2046
2624
  this.connectExternalConfigurationForm(componentRef.instance);
2047
2625
  }
2048
2626
  destroyConfigurationComponent() {
2049
- this.externalConfigurationSubscriptions?.unsubscribe();
2050
- this.externalConfigurationSubscriptions = null;
2627
+ const formSubscriptions = this.externalConfigurationSubscriptions;
2628
+ this.externalConfigurationSubscriptions = new Subscription();
2629
+ formSubscriptions.unsubscribe();
2051
2630
  this.externalConfigurationForm.set(null);
2052
2631
  this.externalConfigurationInvalid.set(false);
2053
2632
  this.configurationComponentRef?.destroy();
@@ -2067,7 +2646,6 @@ class PropertyForm {
2067
2646
  this.configurationControl.setValue(form.value ?? null, {
2068
2647
  emitEvent: false,
2069
2648
  });
2070
- this.externalConfigurationSubscriptions = new Subscription();
2071
2649
  this.externalConfigurationSubscriptions.add(form.valueChanges.subscribe((value) => this.configurationControl.setValue(value, { emitEvent: false })));
2072
2650
  this.externalConfigurationSubscriptions.add(form.statusChanges.subscribe(() => this.externalConfigurationInvalid.set(form.invalid)));
2073
2651
  }
@@ -2140,7 +2718,13 @@ class PropertyForm {
2140
2718
  const request$ = this.propertyId()
2141
2719
  ? this.facade.update(this.propertyId(), payload)
2142
2720
  : this.facade.create(payload);
2143
- request$.subscribe(() => this.goBack());
2721
+ request$.subscribe(() => {
2722
+ if (mainValue.viewType === 'Status') {
2723
+ this.handleStatusPropertySave();
2724
+ return;
2725
+ }
2726
+ this.goBack();
2727
+ });
2144
2728
  }
2145
2729
  syncFormWithSelectedProperty(property) {
2146
2730
  if (!property)
@@ -2148,6 +2732,7 @@ class PropertyForm {
2148
2732
  this.mainControl.patchValue(property, {
2149
2733
  emitEvent: false,
2150
2734
  });
2735
+ this.mainValue.set(this.mainControl.value);
2151
2736
  this.configurationControl.setValue(property?.configuration);
2152
2737
  this.formulaControl.setValue(property.formula ?? null, {
2153
2738
  emitEvent: false,
@@ -2162,13 +2747,51 @@ class PropertyForm {
2162
2747
  queryParamsHandling: 'preserve',
2163
2748
  });
2164
2749
  }
2750
+ handleStatusPropertySave() {
2751
+ const savedId = this.statusPropertyId();
2752
+ if (!savedId) {
2753
+ return;
2754
+ }
2755
+ if (this.propertyId()) {
2756
+ this.facade.loadOne(savedId).subscribe(() => {
2757
+ this.router
2758
+ .navigate([], {
2759
+ relativeTo: this.route,
2760
+ queryParamsHandling: 'preserve',
2761
+ fragment: 'status-configuration',
2762
+ replaceUrl: true,
2763
+ })
2764
+ .then(() => this.scrollToStatusConfiguration());
2765
+ });
2766
+ return;
2767
+ }
2768
+ this.router.navigate([savedId], {
2769
+ relativeTo: this.route,
2770
+ queryParamsHandling: 'preserve',
2771
+ fragment: 'status-configuration',
2772
+ replaceUrl: true,
2773
+ });
2774
+ }
2775
+ scrollToStatusConfiguration() {
2776
+ const section = this.statusConfigurationSection();
2777
+ if (!section) {
2778
+ return;
2779
+ }
2780
+ setTimeout(() => {
2781
+ section.nativeElement.scrollIntoView({
2782
+ behavior: 'smooth',
2783
+ block: 'start',
2784
+ });
2785
+ });
2786
+ }
2165
2787
  ngOnDestroy() {
2166
2788
  this.facade.resetSelectedProperty();
2167
2789
  this.facade.setDefaultViewType('');
2168
2790
  this.destroyConfigurationComponent();
2791
+ this.subscriptions.unsubscribe();
2169
2792
  }
2170
2793
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: PropertyForm, deps: [], target: i0.ɵɵFactoryTarget.Component });
2171
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: PropertyForm, isStandalone: true, selector: "mt-property-form", inputs: { propertyId: { classPropertyName: "propertyId", publicName: "propertyId", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "configurationHost", first: true, predicate: ["configurationHost"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "<mt-page\r\n [title]=\"\r\n propertyId()\r\n ? ('properties.form.editProperty' | transloco)\r\n : ('properties.form.createNewProperty' | transloco)\r\n \"\r\n avatarIcon=\"custom.products-and-services\"\r\n [avatarStyle]=\"{\r\n '--p-avatar-background': 'var(--p-sky-50)',\r\n '--p-avatar-color': 'var(--p-sky-700)',\r\n }\"\r\n (backButtonClick)=\"goBack()\"\r\n backButton\r\n class=\"h-full\"\r\n>\r\n <ng-template #headerEnd>\r\n <mt-button\r\n class=\"mx-2\"\r\n [label]=\"submitLabel()\"\r\n [icon]=\"isEditing() ? 'custom.pencil' : 'general.plus'\"\r\n [loading]=\"submitting()\"\r\n [disabled]=\"submitDisabled() || this.propertyForm.invalid\"\r\n (click)=\"createOrEditProperty()\"\r\n />\r\n </ng-template>\r\n <div\r\n [formGroup]=\"propertyForm\"\r\n class=\"h-full py-4 h-full overflow-y-auto flex justify-center\"\r\n >\r\n <div class=\"w-2/3 flex flex-col gap-6\">\r\n @if (loading()) {\r\n <!-- Skeleton Loading State -->\r\n <div class=\"rounded-xl bg-white shadow-sm p-6 space-y-4\">\r\n <div class=\"flex justify-between items-center gap-6\">\r\n <p-skeleton width=\"50%\" height=\"3rem\"></p-skeleton>\r\n <p-skeleton width=\"8rem\" height=\"2.5rem\"></p-skeleton>\r\n </div>\r\n </div>\r\n\r\n <div class=\"rounded-xl bg-white shadow-sm p-6 space-y-4\">\r\n <p-skeleton\r\n width=\"12rem\"\r\n height=\"1.5rem\"\r\n styleClass=\"mb-4\"\r\n ></p-skeleton>\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n <p-skeleton height=\"3rem\"></p-skeleton>\r\n <p-skeleton height=\"3rem\"></p-skeleton>\r\n <p-skeleton height=\"6rem\" styleClass=\"md:col-span-2\"></p-skeleton>\r\n <p-skeleton height=\"3rem\" styleClass=\"md:col-span-2\"></p-skeleton>\r\n </div>\r\n </div>\r\n\r\n <div class=\"rounded-xl bg-white shadow-sm p-6 space-y-4\">\r\n <p-skeleton\r\n width=\"10rem\"\r\n height=\"1.5rem\"\r\n styleClass=\"mb-4\"\r\n ></p-skeleton>\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n <p-skeleton height=\"3rem\"></p-skeleton>\r\n <p-skeleton height=\"3rem\"></p-skeleton>\r\n <p-skeleton height=\"8rem\" styleClass=\"md:col-span-2\"></p-skeleton>\r\n </div>\r\n </div>\r\n } @else {\r\n <mt-dynamic-form\r\n [formConfig]=\"dynamicFormConfigMain()\"\r\n [formControlName]=\"'main'\"\r\n />\r\n @if (configurationFormConfig()) {\r\n <mt-dynamic-form\r\n formControlName=\"configuration\"\r\n [formConfig]=\"configurationFormConfig()!\"\r\n />\r\n } @else {\r\n <ng-container #configurationHost></ng-container>\r\n @if (!configurationComponentExists()) {\r\n @switch (propertyType()) {\r\n @case (\"User\") {\r\n <mt-user-configuration />\r\n }\r\n @case (\"Percentage\") {\r\n <mt-percentage-configuration />\r\n }\r\n @case (\"Lookup\") {\r\n <mt-lookup-configuration />\r\n }\r\n @case (\"LookupMultiSelect\") {\n <mt-lookup-configuration />\n }\n @case (\"EntityList\") {\n <mt-entity-list-configuration />\n }\n @case (\"API\") {\n <mt-api-configuration formControlName=\"configuration\" />\n }\n <!-- @case('ViewList') { REMOVED FOR NOW\r\n <mt-view-list-configuration />\r\n } -->\r\n @case (\"Attachment\") {\r\n <mt-attachment-configuration />\r\n }\r\n <!-- @case('ReferenceProperty') { REMOVED FOR NOW\r\n } -->\r\n @case (\"LookupModuleCheckList\") {\n <mt-check-list-form-configuration />\n }\n <!-- @case('LookupMatrix') { REMOVED FOR NOW\r\n <mt-lookup-configuration />\r\n } -->\r\n @case (\"Location\") {\r\n <mt-location-configuration />\r\n }\r\n }\r\n }\r\n }\r\n @if (isCalculated()) {\r\n <mt-card title=\"Formula\">\r\n <mt-formula-builder\r\n formControlName=\"formula\"\r\n [levelSchemaId]=\"formulaSchemaId()\"\r\n />\r\n </mt-card>\r\n }\r\n }\r\n </div>\r\n </div>\r\n</mt-page>\r\n", styles: [""], dependencies: [{ kind: "component", type: Page, selector: "mt-page", inputs: ["backButton", "backButtonIcon", "avatarIcon", "avatarStyle", "avatarShape", "title", "tabs", "activeTab", "contentClass", "contentId"], outputs: ["backButtonClick", "tabChange"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig", "forcedHiddenFieldKeys", "preserveForcedHiddenValues"], outputs: ["runtimeMessagesChange"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: FormulaBuilder, selector: "mt-formula-builder", inputs: ["propertiesByPath", "levelSchemaId", "templateId", "placeholder", "hideToolbar", "hideStatusBar"], outputs: ["validationChange", "tokensChange"] }, { kind: "component", type: ApiConfiguration, selector: "mt-api-configuration" }, { kind: "component", type: CheckListFormConfiguration, selector: "mt-check-list-form-configuration" }, { kind: "component", type: EntityListConfiguration, selector: "mt-entity-list-configuration" }, { kind: "component", type: LocationConfiguration, selector: "mt-location-configuration" }, { kind: "component", type: LookupConfiguration, selector: "mt-lookup-configuration" }, { kind: "component", type: PercentageConfiguration, selector: "mt-percentage-configuration" }, { kind: "component", type: UserConfiguration, selector: "mt-user-configuration" }, { kind: "component", type: AttachmentConfiguration, selector: "mt-attachment-configuration" }, { kind: "ngmodule", type: SkeletonModule }, { kind: "component", type: i2.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "ngmodule", type: TranslocoModule }, { kind: "pipe", type: i1.TranslocoPipe, name: "transloco" }] });
2794
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: PropertyForm, isStandalone: true, selector: "mt-property-form", inputs: { propertyId: { classPropertyName: "propertyId", publicName: "propertyId", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "statusConfigurationSection", first: true, predicate: ["statusConfigurationSection"], descendants: true, isSignal: true }, { propertyName: "configurationHost", first: true, predicate: ["configurationHost"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: "<mt-page\n [title]=\"\n propertyId()\n ? ('properties.form.editProperty' | transloco)\n : ('properties.form.createNewProperty' | transloco)\n \"\n avatarIcon=\"custom.products-and-services\"\n [avatarStyle]=\"{\n '--p-avatar-background': 'var(--p-sky-50)',\n '--p-avatar-color': 'var(--p-sky-700)',\n }\"\n (backButtonClick)=\"goBack()\"\n backButton\n class=\"h-full\"\n>\n <ng-template #headerEnd>\n <mt-button\n class=\"mx-2\"\n [label]=\"submitLabel()\"\n [icon]=\"isEditing() ? 'custom.pencil' : 'general.plus'\"\n [loading]=\"submitting()\"\n [disabled]=\"submitDisabled() || this.propertyForm.invalid\"\n (click)=\"createOrEditProperty()\"\n />\n </ng-template>\n <div\n [formGroup]=\"propertyForm\"\n class=\"h-full py-4 h-full overflow-y-auto flex justify-center\"\n >\n <div class=\"w-2/3 flex flex-col gap-6\">\n @if (loading()) {\n <!-- Skeleton Loading State -->\n <div class=\"rounded-xl bg-white shadow-sm p-6 space-y-4\">\n <div class=\"flex justify-between items-center gap-6\">\n <p-skeleton width=\"50%\" height=\"3rem\"></p-skeleton>\n <p-skeleton width=\"8rem\" height=\"2.5rem\"></p-skeleton>\n </div>\n </div>\n\n <div class=\"rounded-xl bg-white shadow-sm p-6 space-y-4\">\n <p-skeleton\n width=\"12rem\"\n height=\"1.5rem\"\n styleClass=\"mb-4\"\n ></p-skeleton>\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <p-skeleton height=\"3rem\"></p-skeleton>\n <p-skeleton height=\"3rem\"></p-skeleton>\n <p-skeleton height=\"6rem\" styleClass=\"md:col-span-2\"></p-skeleton>\n <p-skeleton height=\"3rem\" styleClass=\"md:col-span-2\"></p-skeleton>\n </div>\n </div>\n\n <div class=\"rounded-xl bg-white shadow-sm p-6 space-y-4\">\n <p-skeleton\n width=\"10rem\"\n height=\"1.5rem\"\n styleClass=\"mb-4\"\n ></p-skeleton>\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <p-skeleton height=\"3rem\"></p-skeleton>\n <p-skeleton height=\"3rem\"></p-skeleton>\n <p-skeleton height=\"8rem\" styleClass=\"md:col-span-2\"></p-skeleton>\n </div>\n </div>\n } @else {\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 (\"EntityList\") {\n <mt-entity-list-configuration />\n }\n @case (\"API\") {\n <mt-api-configuration formControlName=\"configuration\" />\n }\n @case (\"Status\") {\n <section #statusConfigurationSection>\n <mt-status-configuration\n [propertyId]=\"statusPropertyId()\"\n [levelSchemaId]=\"formulaSchemaId()\"\n />\n </section>\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 (\"LookupModuleCheckList\") {\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 @if (isCalculated()) {\n <mt-card title=\"Formula\">\n <mt-formula-builder\n formControlName=\"formula\"\n [levelSchemaId]=\"formulaSchemaId()\"\n />\n </mt-card>\n }\n }\n </div>\n </div>\n</mt-page>\n", styles: [""], dependencies: [{ kind: "component", type: Page, selector: "mt-page", inputs: ["backButton", "backButtonIcon", "avatarIcon", "avatarStyle", "avatarShape", "title", "tabs", "activeTab", "contentClass", "contentId"], outputs: ["backButtonClick", "tabChange"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig", "forcedHiddenFieldKeys", "preserveForcedHiddenValues", "visibleSectionKeys"], outputs: ["runtimeMessagesChange"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],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: FormulaBuilder, selector: "mt-formula-builder", inputs: ["propertiesByPath", "levelSchemaId", "templateId", "placeholder", "hideToolbar", "hideStatusBar"], outputs: ["validationChange", "tokensChange"] }, { kind: "component", type: ApiConfiguration, selector: "mt-api-configuration" }, { kind: "component", type: CheckListFormConfiguration, selector: "mt-check-list-form-configuration" }, { kind: "component", type: EntityListConfiguration, selector: "mt-entity-list-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: StatusConfiguration, selector: "mt-status-configuration", inputs: ["propertyId", "levelSchemaId"] }, { kind: "component", type: UserConfiguration, selector: "mt-user-configuration" }, { kind: "component", type: AttachmentConfiguration, selector: "mt-attachment-configuration" }, { kind: "ngmodule", type: SkeletonModule }, { kind: "component", type: i2$1.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "ngmodule", type: TranslocoModule }, { kind: "pipe", type: i2.TranslocoPipe, name: "transloco" }] });
2172
2795
  }
2173
2796
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: PropertyForm, decorators: [{
2174
2797
  type: Component,
@@ -2185,15 +2808,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
2185
2808
  LocationConfiguration,
2186
2809
  LookupConfiguration,
2187
2810
  PercentageConfiguration,
2811
+ StatusConfiguration,
2188
2812
  UserConfiguration,
2189
2813
  AttachmentConfiguration,
2190
2814
  SkeletonModule,
2191
2815
  TranslocoModule,
2192
- ], template: "<mt-page\r\n [title]=\"\r\n propertyId()\r\n ? ('properties.form.editProperty' | transloco)\r\n : ('properties.form.createNewProperty' | transloco)\r\n \"\r\n avatarIcon=\"custom.products-and-services\"\r\n [avatarStyle]=\"{\r\n '--p-avatar-background': 'var(--p-sky-50)',\r\n '--p-avatar-color': 'var(--p-sky-700)',\r\n }\"\r\n (backButtonClick)=\"goBack()\"\r\n backButton\r\n class=\"h-full\"\r\n>\r\n <ng-template #headerEnd>\r\n <mt-button\r\n class=\"mx-2\"\r\n [label]=\"submitLabel()\"\r\n [icon]=\"isEditing() ? 'custom.pencil' : 'general.plus'\"\r\n [loading]=\"submitting()\"\r\n [disabled]=\"submitDisabled() || this.propertyForm.invalid\"\r\n (click)=\"createOrEditProperty()\"\r\n />\r\n </ng-template>\r\n <div\r\n [formGroup]=\"propertyForm\"\r\n class=\"h-full py-4 h-full overflow-y-auto flex justify-center\"\r\n >\r\n <div class=\"w-2/3 flex flex-col gap-6\">\r\n @if (loading()) {\r\n <!-- Skeleton Loading State -->\r\n <div class=\"rounded-xl bg-white shadow-sm p-6 space-y-4\">\r\n <div class=\"flex justify-between items-center gap-6\">\r\n <p-skeleton width=\"50%\" height=\"3rem\"></p-skeleton>\r\n <p-skeleton width=\"8rem\" height=\"2.5rem\"></p-skeleton>\r\n </div>\r\n </div>\r\n\r\n <div class=\"rounded-xl bg-white shadow-sm p-6 space-y-4\">\r\n <p-skeleton\r\n width=\"12rem\"\r\n height=\"1.5rem\"\r\n styleClass=\"mb-4\"\r\n ></p-skeleton>\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n <p-skeleton height=\"3rem\"></p-skeleton>\r\n <p-skeleton height=\"3rem\"></p-skeleton>\r\n <p-skeleton height=\"6rem\" styleClass=\"md:col-span-2\"></p-skeleton>\r\n <p-skeleton height=\"3rem\" styleClass=\"md:col-span-2\"></p-skeleton>\r\n </div>\r\n </div>\r\n\r\n <div class=\"rounded-xl bg-white shadow-sm p-6 space-y-4\">\r\n <p-skeleton\r\n width=\"10rem\"\r\n height=\"1.5rem\"\r\n styleClass=\"mb-4\"\r\n ></p-skeleton>\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n <p-skeleton height=\"3rem\"></p-skeleton>\r\n <p-skeleton height=\"3rem\"></p-skeleton>\r\n <p-skeleton height=\"8rem\" styleClass=\"md:col-span-2\"></p-skeleton>\r\n </div>\r\n </div>\r\n } @else {\r\n <mt-dynamic-form\r\n [formConfig]=\"dynamicFormConfigMain()\"\r\n [formControlName]=\"'main'\"\r\n />\r\n @if (configurationFormConfig()) {\r\n <mt-dynamic-form\r\n formControlName=\"configuration\"\r\n [formConfig]=\"configurationFormConfig()!\"\r\n />\r\n } @else {\r\n <ng-container #configurationHost></ng-container>\r\n @if (!configurationComponentExists()) {\r\n @switch (propertyType()) {\r\n @case (\"User\") {\r\n <mt-user-configuration />\r\n }\r\n @case (\"Percentage\") {\r\n <mt-percentage-configuration />\r\n }\r\n @case (\"Lookup\") {\r\n <mt-lookup-configuration />\r\n }\r\n @case (\"LookupMultiSelect\") {\n <mt-lookup-configuration />\n }\n @case (\"EntityList\") {\n <mt-entity-list-configuration />\n }\n @case (\"API\") {\n <mt-api-configuration formControlName=\"configuration\" />\n }\n <!-- @case('ViewList') { REMOVED FOR NOW\r\n <mt-view-list-configuration />\r\n } -->\r\n @case (\"Attachment\") {\r\n <mt-attachment-configuration />\r\n }\r\n <!-- @case('ReferenceProperty') { REMOVED FOR NOW\r\n } -->\r\n @case (\"LookupModuleCheckList\") {\n <mt-check-list-form-configuration />\n }\n <!-- @case('LookupMatrix') { REMOVED FOR NOW\r\n <mt-lookup-configuration />\r\n } -->\r\n @case (\"Location\") {\r\n <mt-location-configuration />\r\n }\r\n }\r\n }\r\n }\r\n @if (isCalculated()) {\r\n <mt-card title=\"Formula\">\r\n <mt-formula-builder\r\n formControlName=\"formula\"\r\n [levelSchemaId]=\"formulaSchemaId()\"\r\n />\r\n </mt-card>\r\n }\r\n }\r\n </div>\r\n </div>\r\n</mt-page>\r\n" }]
2816
+ ], template: "<mt-page\n [title]=\"\n propertyId()\n ? ('properties.form.editProperty' | transloco)\n : ('properties.form.createNewProperty' | transloco)\n \"\n avatarIcon=\"custom.products-and-services\"\n [avatarStyle]=\"{\n '--p-avatar-background': 'var(--p-sky-50)',\n '--p-avatar-color': 'var(--p-sky-700)',\n }\"\n (backButtonClick)=\"goBack()\"\n backButton\n class=\"h-full\"\n>\n <ng-template #headerEnd>\n <mt-button\n class=\"mx-2\"\n [label]=\"submitLabel()\"\n [icon]=\"isEditing() ? 'custom.pencil' : 'general.plus'\"\n [loading]=\"submitting()\"\n [disabled]=\"submitDisabled() || this.propertyForm.invalid\"\n (click)=\"createOrEditProperty()\"\n />\n </ng-template>\n <div\n [formGroup]=\"propertyForm\"\n class=\"h-full py-4 h-full overflow-y-auto flex justify-center\"\n >\n <div class=\"w-2/3 flex flex-col gap-6\">\n @if (loading()) {\n <!-- Skeleton Loading State -->\n <div class=\"rounded-xl bg-white shadow-sm p-6 space-y-4\">\n <div class=\"flex justify-between items-center gap-6\">\n <p-skeleton width=\"50%\" height=\"3rem\"></p-skeleton>\n <p-skeleton width=\"8rem\" height=\"2.5rem\"></p-skeleton>\n </div>\n </div>\n\n <div class=\"rounded-xl bg-white shadow-sm p-6 space-y-4\">\n <p-skeleton\n width=\"12rem\"\n height=\"1.5rem\"\n styleClass=\"mb-4\"\n ></p-skeleton>\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <p-skeleton height=\"3rem\"></p-skeleton>\n <p-skeleton height=\"3rem\"></p-skeleton>\n <p-skeleton height=\"6rem\" styleClass=\"md:col-span-2\"></p-skeleton>\n <p-skeleton height=\"3rem\" styleClass=\"md:col-span-2\"></p-skeleton>\n </div>\n </div>\n\n <div class=\"rounded-xl bg-white shadow-sm p-6 space-y-4\">\n <p-skeleton\n width=\"10rem\"\n height=\"1.5rem\"\n styleClass=\"mb-4\"\n ></p-skeleton>\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <p-skeleton height=\"3rem\"></p-skeleton>\n <p-skeleton height=\"3rem\"></p-skeleton>\n <p-skeleton height=\"8rem\" styleClass=\"md:col-span-2\"></p-skeleton>\n </div>\n </div>\n } @else {\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 (\"EntityList\") {\n <mt-entity-list-configuration />\n }\n @case (\"API\") {\n <mt-api-configuration formControlName=\"configuration\" />\n }\n @case (\"Status\") {\n <section #statusConfigurationSection>\n <mt-status-configuration\n [propertyId]=\"statusPropertyId()\"\n [levelSchemaId]=\"formulaSchemaId()\"\n />\n </section>\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 (\"LookupModuleCheckList\") {\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 @if (isCalculated()) {\n <mt-card title=\"Formula\">\n <mt-formula-builder\n formControlName=\"formula\"\n [levelSchemaId]=\"formulaSchemaId()\"\n />\n </mt-card>\n }\n }\n </div>\n </div>\n</mt-page>\n" }]
2193
2817
  }], ctorParameters: () => [], propDecorators: { propertyId: [{ type: i0.Input, args: [{ isSignal: true, alias: "propertyId", required: false }] }], configurationHost: [{
2194
2818
  type: ViewChild,
2195
2819
  args: ['configurationHost', { read: ViewContainerRef }]
2196
- }] } });
2820
+ }], statusConfigurationSection: [{ type: i0.ViewChild, args: ['statusConfigurationSection', { isSignal: true }] }] } });
2197
2821
 
2198
2822
  /*
2199
2823
  * Public API Surface of structure-builder
@@ -2203,5 +2827,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
2203
2827
  * Generated bundle index. Do not edit.
2204
2828
  */
2205
2829
 
2206
- 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 };
2830
+ export { CreateProperty, CreatePropertyStatus, DeleteProperty, DeletePropertyStatus, GetConfigAsType, GetCountries, GetGroups, GetLookups, GetProperties, GetPropertiesForConfigType, GetProperty, GetPropertyStatuses, PropertiesActionKey, PropertiesFacade, PropertiesList, PropertiesState, PropertyForm, REQUEST_CONTEXT, ReorderPropertyStatuses, ResetApiConfiguration, ResetConfigProperties, ResetConfigScopes, ResetPropertyStatuses, ResetSelectedProperty, SetBreadcrumb, SetDefaultViewType, SetPropertiesModuleInfo, SetPropertyTypes, TestApiConfiguration, UpdateProperty, UpdatePropertyStatus };
2207
2831
  //# sourceMappingURL=masterteam-properties.mjs.map