@masterteam/properties 0.0.33 → 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.
@@ -8,7 +8,7 @@
8
8
  "columnName": "الاسم",
9
9
  "columnType": "النوع",
10
10
  "columnRequired": "مطلوب",
11
- "columnCalculated": "محسوبة",
11
+ "columnCalculated": "هل هي محسوبة",
12
12
  "createAction": "إنشاء",
13
13
  "editAction": "تعديل",
14
14
  "deleteAction": "حذف",
@@ -8,7 +8,7 @@
8
8
  "columnName": "Name",
9
9
  "columnType": "Type",
10
10
  "columnRequired": "Required",
11
- "columnCalculated": "Calculated",
11
+ "columnCalculated": "Is Calculated",
12
12
  "createAction": "Create",
13
13
  "editAction": "Edit",
14
14
  "deleteAction": "Delete",
@@ -6,7 +6,7 @@ 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 { CrudStateBase, handleApiRequest, PickListFieldConfig, ValidatorConfig, ColorPickerFieldConfig, IconFieldConfig } from '@masterteam/components';
9
+ import { CrudStateBase, handleApiRequest, ValidatorConfig, PickListFieldConfig, ColorPickerFieldConfig, IconFieldConfig } from '@masterteam/components';
10
10
  import { Breadcrumb } from '@masterteam/components/breadcrumb';
11
11
  import { Card } from '@masterteam/components/card';
12
12
  import { Avatar } from '@masterteam/components/avatar';
@@ -1086,7 +1086,7 @@ class PropertiesList {
1086
1086
  },
1087
1087
  },
1088
1088
  {
1089
- key: 'isRequired',
1089
+ key: 'isCalculated',
1090
1090
  label: this.transloco.translate('properties.list.columnCalculated'),
1091
1091
  type: 'boolean',
1092
1092
  readonly: true,
@@ -1488,6 +1488,7 @@ class CheckListFormConfiguration {
1488
1488
  optionValue: 'id',
1489
1489
  filter: true,
1490
1490
  options: this.lookups(),
1491
+ validators: [ValidatorConfig.required()],
1491
1492
  },
1492
1493
  {
1493
1494
  key: 'scopeId',
@@ -1497,6 +1498,7 @@ class CheckListFormConfiguration {
1497
1498
  optionValue: 'id',
1498
1499
  options: this.scopeItems(),
1499
1500
  filter: true,
1501
+ validators: [ValidatorConfig.required()],
1500
1502
  },
1501
1503
  new PickListFieldConfig({
1502
1504
  key: 'properties',
@@ -1506,6 +1508,7 @@ class CheckListFormConfiguration {
1506
1508
  optionValue: 'key',
1507
1509
  sourceHeader: this.transloco.translate('properties.form.availableProperties'),
1508
1510
  targetHeader: this.transloco.translate('properties.form.selectedProperties'),
1511
+ validators: [ValidatorConfig.required()],
1509
1512
  }),
1510
1513
  ],
1511
1514
  },
@@ -1586,6 +1589,7 @@ class EntityListConfiguration {
1586
1589
  optionValue: 'id',
1587
1590
  options: this.moduleItems(),
1588
1591
  filter: true,
1592
+ validators: [ValidatorConfig.required()],
1589
1593
  },
1590
1594
  {
1591
1595
  key: 'access',
@@ -1594,6 +1598,7 @@ class EntityListConfiguration {
1594
1598
  optionLabel: 'label',
1595
1599
  optionValue: 'value',
1596
1600
  options: this.accessOptions,
1601
+ validators: [ValidatorConfig.required()],
1597
1602
  },
1598
1603
  {
1599
1604
  key: 'snapshotMode',
@@ -1611,6 +1616,7 @@ class EntityListConfiguration {
1611
1616
  optionValue: 'key',
1612
1617
  sourceHeader: 'Available Read Fields',
1613
1618
  targetHeader: 'Selected Read Fields',
1619
+ validators: [ValidatorConfig.required()],
1614
1620
  }),
1615
1621
  new PickListFieldConfig({
1616
1622
  key: 'writeFields',
@@ -1620,6 +1626,7 @@ class EntityListConfiguration {
1620
1626
  optionValue: 'key',
1621
1627
  sourceHeader: 'Available Write Fields',
1622
1628
  targetHeader: 'Selected Write Fields',
1629
+ validators: [ValidatorConfig.required()],
1623
1630
  relations: [
1624
1631
  { action: 'show', key: 'access', value: 'Write' },
1625
1632
  { action: 'show', key: 'access', value: 'ReadWrite' },
@@ -1699,6 +1706,7 @@ class LocationConfiguration {
1699
1706
  optionValue: 'name',
1700
1707
  options: this.countries(),
1701
1708
  filter: true,
1709
+ validators: [ValidatorConfig.required()],
1702
1710
  },
1703
1711
  ],
1704
1712
  },
@@ -1746,6 +1754,7 @@ class LookupConfiguration {
1746
1754
  optionValue: 'id',
1747
1755
  options: this.lookups(),
1748
1756
  filter: true,
1757
+ validators: [ValidatorConfig.required()],
1749
1758
  },
1750
1759
  ],
1751
1760
  },
@@ -2320,6 +2329,7 @@ class AttachmentConfiguration {
2320
2329
  sourceHeader: this.transloco.translate('properties.form.availableTypes'),
2321
2330
  targetHeader: this.transloco.translate('properties.form.selectedTypes'),
2322
2331
  cssClass: 'md:col-span-2',
2332
+ validators: [ValidatorConfig.required()],
2323
2333
  }),
2324
2334
  {
2325
2335
  key: 'IsMulitple',
@@ -2372,14 +2382,13 @@ class PropertyForm {
2372
2382
  mainControl = this.propertyForm.get('main');
2373
2383
  configurationControl = this.propertyForm.get('configuration');
2374
2384
  formulaControl = this.propertyForm.get('formula');
2385
+ mainValue = signal(this.mainControl.value, ...(ngDevMode ? [{ debugName: "mainValue" }] : []));
2375
2386
  creating = this.facade.isCreating;
2376
2387
  updating = this.facade.isUpdating;
2377
2388
  loading = this.facade.isLoadingOne;
2378
2389
  submitting = computed(() => this.creating() || this.updating(), ...(ngDevMode ? [{ debugName: "submitting" }] : []));
2379
- propertyType = toSignal(this.mainControl.valueChanges.pipe(map((v) => v?.viewType), distinctUntilChanged()));
2380
- isCalculated = toSignal(this.mainControl.valueChanges.pipe(map((v) => Boolean(v?.isCalculated)), distinctUntilChanged()), {
2381
- initialValue: Boolean(this.mainControl.value?.isCalculated),
2382
- });
2390
+ propertyType = computed(() => this.mainValue()?.viewType ?? null, ...(ngDevMode ? [{ debugName: "propertyType" }] : []));
2391
+ isCalculated = computed(() => Boolean(this.mainValue()?.isCalculated), ...(ngDevMode ? [{ debugName: "isCalculated" }] : []));
2383
2392
  formulaSchemaId = computed(() => this.resolveSchemaId(this.facade.parentModuleId() ?? this.facade.moduleId()), ...(ngDevMode ? [{ debugName: "formulaSchemaId" }] : []));
2384
2393
  selectedViewType = computed(() => this.propertyType() ??
2385
2394
  this.facade.selected()?.viewType, ...(ngDevMode ? [{ debugName: "selectedViewType" }] : []));
@@ -2407,7 +2416,8 @@ class PropertyForm {
2407
2416
  configurationComponentRef = null;
2408
2417
  configurationComponentLoadId = 0;
2409
2418
  externalConfigurationForm = signal(null, ...(ngDevMode ? [{ debugName: "externalConfigurationForm" }] : []));
2410
- externalConfigurationSubscriptions = null;
2419
+ externalConfigurationSubscriptions = new Subscription();
2420
+ subscriptions = new Subscription();
2411
2421
  externalConfigurationInvalid = signal(false, ...(ngDevMode ? [{ debugName: "externalConfigurationInvalid" }] : []));
2412
2422
  lastStatusScrollKey = signal(null, ...(ngDevMode ? [{ debugName: "lastStatusScrollKey" }] : []));
2413
2423
  configurationComponentExists = computed(() => !!this.configurationComponentType(), ...(ngDevMode ? [{ debugName: "configurationComponentExists" }] : []));
@@ -2478,16 +2488,6 @@ class PropertyForm {
2478
2488
  key: 'viewType',
2479
2489
  value: 'Checkbox',
2480
2490
  },
2481
- {
2482
- action: 'show',
2483
- key: 'viewType',
2484
- value: 'Lookup',
2485
- },
2486
- {
2487
- action: 'show',
2488
- key: 'viewType',
2489
- value: 'LookupMultiSelect',
2490
- },
2491
2491
  {
2492
2492
  action: 'show',
2493
2493
  key: 'viewType',
@@ -2536,6 +2536,7 @@ class PropertyForm {
2536
2536
  ],
2537
2537
  }), ...(ngDevMode ? [{ debugName: "dynamicFormConfigMain" }] : []));
2538
2538
  constructor() {
2539
+ this.subscriptions.add(this.mainControl.valueChanges.subscribe((value) => this.mainValue.set(value)));
2539
2540
  // Load when editing
2540
2541
  effect(() => {
2541
2542
  if (this.propertyId()) {
@@ -2581,6 +2582,11 @@ class PropertyForm {
2581
2582
  effect(() => {
2582
2583
  this.renderConfigurationComponent(this.configurationComponentType());
2583
2584
  });
2585
+ effect(() => {
2586
+ const calculated = this.isCalculated();
2587
+ this.formulaControl.setValidators(calculated ? [Validators.required] : []);
2588
+ this.formulaControl.updateValueAndValidity({ emitEvent: false });
2589
+ });
2584
2590
  effect(() => {
2585
2591
  const fragment = this.routeFragment();
2586
2592
  const section = this.statusConfigurationSection();
@@ -2618,8 +2624,9 @@ class PropertyForm {
2618
2624
  this.connectExternalConfigurationForm(componentRef.instance);
2619
2625
  }
2620
2626
  destroyConfigurationComponent() {
2621
- this.externalConfigurationSubscriptions?.unsubscribe();
2622
- this.externalConfigurationSubscriptions = null;
2627
+ const formSubscriptions = this.externalConfigurationSubscriptions;
2628
+ this.externalConfigurationSubscriptions = new Subscription();
2629
+ formSubscriptions.unsubscribe();
2623
2630
  this.externalConfigurationForm.set(null);
2624
2631
  this.externalConfigurationInvalid.set(false);
2625
2632
  this.configurationComponentRef?.destroy();
@@ -2639,7 +2646,6 @@ class PropertyForm {
2639
2646
  this.configurationControl.setValue(form.value ?? null, {
2640
2647
  emitEvent: false,
2641
2648
  });
2642
- this.externalConfigurationSubscriptions = new Subscription();
2643
2649
  this.externalConfigurationSubscriptions.add(form.valueChanges.subscribe((value) => this.configurationControl.setValue(value, { emitEvent: false })));
2644
2650
  this.externalConfigurationSubscriptions.add(form.statusChanges.subscribe(() => this.externalConfigurationInvalid.set(form.invalid)));
2645
2651
  }
@@ -2726,6 +2732,7 @@ class PropertyForm {
2726
2732
  this.mainControl.patchValue(property, {
2727
2733
  emitEvent: false,
2728
2734
  });
2735
+ this.mainValue.set(this.mainControl.value);
2729
2736
  this.configurationControl.setValue(property?.configuration);
2730
2737
  this.formulaControl.setValue(property.formula ?? null, {
2731
2738
  emitEvent: false,
@@ -2781,6 +2788,7 @@ class PropertyForm {
2781
2788
  this.facade.resetSelectedProperty();
2782
2789
  this.facade.setDefaultViewType('');
2783
2790
  this.destroyConfigurationComponent();
2791
+ this.subscriptions.unsubscribe();
2784
2792
  }
2785
2793
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: PropertyForm, deps: [], target: i0.ɵɵFactoryTarget.Component });
2786
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" }] });