@masterteam/properties 0.0.69 → 0.0.71

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.
package/README.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # @masterteam/properties
2
2
 
3
+ ## Property form scope
4
+
5
+ `PropertyForm` accepts a typed `scope` input. Route hosts should map their URL
6
+ parameters to this domain contract instead of making the package understand
7
+ application-specific route names.
8
+
9
+ ```ts
10
+ import { type PropertiesScope, PropertyForm } from '@masterteam/properties';
11
+
12
+ readonly scope: PropertiesScope = {
13
+ target: { type: 'module', id: 21 },
14
+ parent: { type: 'level', id: 7 },
15
+ };
16
+ ```
17
+
18
+ ```html
19
+ <mt-property-form [propertyId]="propertyId" [scope]="scope" />
20
+ ```
21
+
22
+ When `scope` is supplied, the form applies it to `PropertiesFacade` and waits
23
+ for that dispatch to complete before loading an existing property. This is
24
+ required for cold create/edit routes because property requests, formula schema
25
+ IDs, and save endpoints all depend on the effective scope. Visiting a list page
26
+ first must never be required.
27
+
28
+ For backward compatibility, hosts that already initialize
29
+ `PropertiesFacade.setModuleInfo(...)` before constructing the form can omit the
30
+ input. New route and embedded integrations should prefer the explicit scope.
3
31
 
4
32
  ## 🤝 Contributing
5
33
 
@@ -5,7 +5,7 @@ import { Table } from '@masterteam/components/table';
5
5
  import { Router, ActivatedRoute } from '@angular/router';
6
6
  import { HttpClient, HttpContextToken } from '@angular/common/http';
7
7
  import { Action, Selector, State, Store, select } from '@ngxs/store';
8
- import { of, finalize, startWith, map, distinctUntilChanged, EMPTY, Subscription } from 'rxjs';
8
+ import { of, finalize, startWith, map, distinctUntilChanged, EMPTY, switchMap, Subscription } from 'rxjs';
9
9
  import { CrudStateBase, handleApiRequest, ValidatorConfig, PickListFieldConfig, ColorPickerFieldConfig } from '@masterteam/components';
10
10
  import { Breadcrumb } from '@masterteam/components/breadcrumb';
11
11
  import { Card } from '@masterteam/components/card';
@@ -30,6 +30,12 @@ import { ToggleField } from '@masterteam/components/toggle-field';
30
30
  import { ModalService } from '@masterteam/components/modal';
31
31
  import { ModalRef } from '@masterteam/components/dialog';
32
32
 
33
+ function buildPropertiesScopeContextKey(scope) {
34
+ return [scope.parent, scope.target]
35
+ .filter((target) => target != null)
36
+ .map((target) => `${target.type}:${target.id}`)
37
+ .join('/');
38
+ }
33
39
  var PropertiesActionKey;
34
40
  (function (PropertiesActionKey) {
35
41
  PropertiesActionKey["GetAll"] = "getAll";
@@ -277,14 +283,15 @@ let PropertiesState = class PropertiesState extends CrudStateBase {
277
283
  * standalone module as `Module:{id}` instead of mistaking it for a level.
278
284
  */
279
285
  static formulaContextKey(state) {
280
- const parts = [];
281
- if (state.parentModuleType && state.parentModuleId) {
282
- parts.push(`${state.parentModuleType}:${state.parentModuleId}`);
283
- }
284
- if (state.moduleType && state.moduleId) {
285
- parts.push(`${state.moduleType}:${state.moduleId}`);
286
+ if (state.moduleType == null || state.moduleId == null) {
287
+ return null;
286
288
  }
287
- return parts.length > 0 ? parts.join('/') : null;
289
+ return buildPropertiesScopeContextKey({
290
+ target: { type: state.moduleType, id: state.moduleId },
291
+ parent: state.parentModuleType != null && state.parentModuleId != null
292
+ ? { type: state.parentModuleType, id: state.parentModuleId }
293
+ : undefined,
294
+ });
288
295
  }
289
296
  static lookups(state) {
290
297
  return state.lookups;
@@ -985,6 +992,9 @@ class PropertiesFacade {
985
992
  setModuleInfo(moduleType, moduleId, parentModuleType, parentModuleId, parentPath) {
986
993
  return this.store.dispatch(new SetPropertiesModuleInfo(moduleType, moduleId, parentModuleType, parentModuleId, parentPath));
987
994
  }
995
+ setScope(scope) {
996
+ return this.setModuleInfo(scope.target.type, scope.target.id, scope.parent?.type, scope.parent?.id, scope.parentPath);
997
+ }
988
998
  loadLookups() {
989
999
  return this.store.dispatch(new GetLookups());
990
1000
  }
@@ -2493,6 +2503,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
2493
2503
  ], template: "<mt-dynamic-form formControlName=\"configuration\" [formConfig]=\"formConfig()\" />\r\n" }]
2494
2504
  }] });
2495
2505
 
2506
+ function createPropertyFormRequest(operations, scope, propertyId) {
2507
+ if (scope) {
2508
+ const scopeRequest$ = operations.setScope(scope);
2509
+ return propertyId
2510
+ ? scopeRequest$.pipe(switchMap(() => operations.loadOne(propertyId)))
2511
+ : scopeRequest$;
2512
+ }
2513
+ return propertyId ? operations.loadOne(propertyId) : null;
2514
+ }
2515
+
2496
2516
  class PropertyForm {
2497
2517
  facade = inject(PropertiesFacade);
2498
2518
  router = inject(Router);
@@ -2503,6 +2523,7 @@ class PropertyForm {
2503
2523
  initialValue: this.transloco.getActiveLang(),
2504
2524
  });
2505
2525
  propertyId = input('', ...(ngDevMode ? [{ debugName: "propertyId" }] : /* istanbul ignore next */ []));
2526
+ scope = input(null, ...(ngDevMode ? [{ debugName: "scope" }] : /* istanbul ignore next */ []));
2506
2527
  propertyTypes = this.facade.propertyTypes;
2507
2528
  legacyReplacedViewTypes = [
2508
2529
  'DynamicList',
@@ -2563,14 +2584,25 @@ class PropertyForm {
2563
2584
  * standalone module is addressed as `Module:{id}` rather than mistaken for a
2564
2585
  * level. Undefined when no scope is set.
2565
2586
  */
2566
- formulaContextKey = computed(() => this.facade.formulaContextKey() ?? undefined, ...(ngDevMode ? [{ debugName: "formulaContextKey" }] : /* istanbul ignore next */ []));
2567
- formulaSchemaId = computed(() => this.resolveSchemaId(this.facade.parentModuleId() ?? this.facade.moduleId()), ...(ngDevMode ? [{ debugName: "formulaSchemaId" }] : /* istanbul ignore next */ []));
2587
+ formulaContextKey = computed(() => {
2588
+ const scope = this.scope();
2589
+ return scope
2590
+ ? buildPropertiesScopeContextKey(scope)
2591
+ : (this.facade.formulaContextKey() ?? undefined);
2592
+ }, ...(ngDevMode ? [{ debugName: "formulaContextKey" }] : /* istanbul ignore next */ []));
2593
+ formulaSchemaId = computed(() => {
2594
+ const scope = this.scope();
2595
+ return this.resolveSchemaId(scope
2596
+ ? (scope.parent?.id ?? scope.target.id)
2597
+ : (this.facade.parentModuleId() ?? this.facade.moduleId()));
2598
+ }, ...(ngDevMode ? [{ debugName: "formulaSchemaId" }] : /* istanbul ignore next */ []));
2568
2599
  formulaModuleId = computed(() => {
2569
- const parentModuleId = this.resolveSchemaId(this.facade.parentModuleId());
2600
+ const scope = this.scope();
2601
+ const parentModuleId = this.resolveSchemaId(scope ? (scope.parent?.id ?? null) : this.facade.parentModuleId());
2570
2602
  if (parentModuleId === undefined) {
2571
2603
  return undefined;
2572
2604
  }
2573
- return this.resolveSchemaId(this.facade.moduleId());
2605
+ return this.resolveSchemaId(scope ? scope.target.id : this.facade.moduleId());
2574
2606
  }, ...(ngDevMode ? [{ debugName: "formulaModuleId" }] : /* istanbul ignore next */ []));
2575
2607
  selectedViewType = computed(() => this.propertyType() ??
2576
2608
  this.facade.selected()?.viewType, ...(ngDevMode ? [{ debugName: "selectedViewType" }] : /* istanbul ignore next */ []));
@@ -2700,11 +2732,18 @@ class PropertyForm {
2700
2732
  }), ...(ngDevMode ? [{ debugName: "dynamicFormConfigMain" }] : /* istanbul ignore next */ []));
2701
2733
  constructor() {
2702
2734
  this.subscriptions.add(this.mainControl.valueChanges.subscribe((value) => this.mainValue.set(value)));
2703
- // Load when editing
2704
- effect(() => {
2705
- if (this.propertyId()) {
2706
- this.facade.loadOne(this.propertyId());
2735
+ // Apply an explicit scope before loading an edit. This must remain one
2736
+ // serialized effect: separate context/load effects have no ordering
2737
+ // guarantee during the initial change-detection pass.
2738
+ effect((onCleanup) => {
2739
+ const scope = this.scope();
2740
+ const propertyId = this.propertyId();
2741
+ const request$ = createPropertyFormRequest(this.facade, scope, propertyId);
2742
+ if (!request$) {
2743
+ return;
2707
2744
  }
2745
+ const subscription = request$.subscribe();
2746
+ onCleanup(() => subscription.unsubscribe());
2708
2747
  });
2709
2748
  // Patch viewType from store when creating new property
2710
2749
  effect(() => {
@@ -3004,7 +3043,7 @@ class PropertyForm {
3004
3043
  this.subscriptions.unsubscribe();
3005
3044
  }
3006
3045
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: PropertyForm, deps: [], target: i0.ɵɵFactoryTarget.Component });
3007
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", 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\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($event)\"\r\n />\r\n </ng-template>\r\n <div\r\n [formGroup]=\"propertyForm\"\r\n class=\"h-full py-4 h-full overflow-y-auto flex justify-center\"\r\n >\r\n <div class=\"w-2/3 flex flex-col gap-6\">\r\n @if (loading()) {\r\n <!-- Skeleton Loading State -->\r\n <div class=\"rounded-xl bg-white shadow-sm p-6 space-y-4\">\r\n <div class=\"flex justify-between items-center gap-6\">\r\n <p-skeleton width=\"50%\" height=\"3rem\"></p-skeleton>\r\n <p-skeleton width=\"8rem\" height=\"2.5rem\"></p-skeleton>\r\n </div>\r\n </div>\r\n\r\n <div class=\"rounded-xl bg-white shadow-sm p-6 space-y-4\">\r\n <p-skeleton\r\n width=\"12rem\"\r\n height=\"1.5rem\"\r\n styleClass=\"mb-4\"\r\n ></p-skeleton>\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n <p-skeleton height=\"3rem\"></p-skeleton>\r\n <p-skeleton height=\"3rem\"></p-skeleton>\r\n <p-skeleton height=\"6rem\" styleClass=\"md:col-span-2\"></p-skeleton>\r\n <p-skeleton height=\"3rem\" styleClass=\"md:col-span-2\"></p-skeleton>\r\n </div>\r\n </div>\r\n\r\n <div class=\"rounded-xl bg-white shadow-sm p-6 space-y-4\">\r\n <p-skeleton\r\n width=\"10rem\"\r\n height=\"1.5rem\"\r\n styleClass=\"mb-4\"\r\n ></p-skeleton>\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n <p-skeleton height=\"3rem\"></p-skeleton>\r\n <p-skeleton height=\"3rem\"></p-skeleton>\r\n <p-skeleton height=\"8rem\" styleClass=\"md:col-span-2\"></p-skeleton>\r\n </div>\r\n </div>\r\n } @else {\r\n <mt-dynamic-form\r\n [formConfig]=\"dynamicFormConfigMain()\"\r\n [formControlName]=\"'main'\"\r\n />\r\n @if (configurationFormConfig()) {\r\n <mt-dynamic-form\r\n formControlName=\"configuration\"\r\n [formConfig]=\"configurationFormConfig()!\"\r\n />\r\n } @else {\r\n <ng-container #configurationHost></ng-container>\r\n @if (!configurationComponentExists()) {\r\n @switch (propertyType()) {\r\n @case (\"User\") {\r\n <mt-user-configuration />\r\n }\r\n @case (\"Percentage\") {\r\n <mt-percentage-configuration />\r\n }\r\n @case (\"Lookup\") {\r\n <mt-lookup-configuration />\r\n }\r\n @case (\"LookupMultiSelect\") {\r\n <mt-lookup-configuration />\r\n }\r\n @case (\"EntityList\") {\r\n <mt-entity-list-configuration />\r\n }\r\n @case (\"API\") {\r\n <mt-api-configuration formControlName=\"configuration\" />\r\n }\r\n @case (\"Status\") {\r\n <section #statusConfigurationSection>\r\n <mt-status-configuration\r\n [propertyId]=\"statusPropertyId()\"\r\n [contextKey]=\"formulaContextKey()\"\r\n [levelSchemaId]=\"formulaSchemaId()\"\r\n [moduleId]=\"formulaModuleId()\"\r\n />\r\n </section>\r\n }\r\n <!-- @case('ViewList') { REMOVED FOR NOW\r\n <mt-view-list-configuration />\r\n } -->\r\n @case (\"Attachment\") {\r\n <mt-attachment-configuration />\r\n }\r\n <!-- @case('ReferenceProperty') { REMOVED FOR NOW\r\n } -->\r\n @case (\"LookupModuleCheckList\") {\r\n <mt-check-list-form-configuration />\r\n }\r\n <!-- @case('LookupMatrix') { REMOVED FOR NOW\r\n <mt-lookup-configuration />\r\n } -->\r\n @case (\"Location\") {\r\n <mt-location-configuration />\r\n }\r\n }\r\n }\r\n }\r\n @if (isCalculated() && !hideFormulaBuilder()) {\r\n <mt-card>\r\n <ng-template #headless>\r\n <div\r\n class=\"flex items-center justify-between px-4 py-5 border-b border-surface\"\r\n >\r\n <h3 class=\"text-xl font-semibold\">\r\n {{ \"properties.form.formula\" | transloco }}\r\n <span class=\"text-red-500\">*</span>\r\n </h3>\r\n </div>\r\n <div class=\"flex-1 min-h-0 p-4\">\r\n <mt-formula-builder\r\n formControlName=\"formula\"\r\n [contextKey]=\"formulaContextKey()\"\r\n [levelSchemaId]=\"formulaSchemaId()\"\r\n [moduleId]=\"formulaModuleId()\"\r\n />\r\n </div>\r\n </ng-template>\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", "forcedDisabledFieldKeys", "preserveForcedHiddenValues", "visibleSectionKeys", "externalValues"], 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", "moduleId", "contextKey", "contextEntityTypeKey", "templateId", "placeholder", "hideToolbar", "hideStatusBar", "toolbarTabs", "codeOnly", "builderOnly", "valueMode", "isProcessBuilder"], 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", "contextKey", "levelSchemaId", "moduleId"] }, { 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" }] });
3046
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.8", type: PropertyForm, isStandalone: true, selector: "mt-property-form", inputs: { propertyId: { classPropertyName: "propertyId", publicName: "propertyId", isSignal: true, isRequired: false, transformFunction: null }, scope: { classPropertyName: "scope", publicName: "scope", 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\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($event)\"\r\n />\r\n </ng-template>\r\n <div\r\n [formGroup]=\"propertyForm\"\r\n class=\"h-full py-4 h-full overflow-y-auto flex justify-center\"\r\n >\r\n <div class=\"w-2/3 flex flex-col gap-6\">\r\n @if (loading()) {\r\n <!-- Skeleton Loading State -->\r\n <div class=\"rounded-xl bg-white shadow-sm p-6 space-y-4\">\r\n <div class=\"flex justify-between items-center gap-6\">\r\n <p-skeleton width=\"50%\" height=\"3rem\"></p-skeleton>\r\n <p-skeleton width=\"8rem\" height=\"2.5rem\"></p-skeleton>\r\n </div>\r\n </div>\r\n\r\n <div class=\"rounded-xl bg-white shadow-sm p-6 space-y-4\">\r\n <p-skeleton\r\n width=\"12rem\"\r\n height=\"1.5rem\"\r\n styleClass=\"mb-4\"\r\n ></p-skeleton>\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n <p-skeleton height=\"3rem\"></p-skeleton>\r\n <p-skeleton height=\"3rem\"></p-skeleton>\r\n <p-skeleton height=\"6rem\" styleClass=\"md:col-span-2\"></p-skeleton>\r\n <p-skeleton height=\"3rem\" styleClass=\"md:col-span-2\"></p-skeleton>\r\n </div>\r\n </div>\r\n\r\n <div class=\"rounded-xl bg-white shadow-sm p-6 space-y-4\">\r\n <p-skeleton\r\n width=\"10rem\"\r\n height=\"1.5rem\"\r\n styleClass=\"mb-4\"\r\n ></p-skeleton>\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n <p-skeleton height=\"3rem\"></p-skeleton>\r\n <p-skeleton height=\"3rem\"></p-skeleton>\r\n <p-skeleton height=\"8rem\" styleClass=\"md:col-span-2\"></p-skeleton>\r\n </div>\r\n </div>\r\n } @else {\r\n <mt-dynamic-form\r\n [formConfig]=\"dynamicFormConfigMain()\"\r\n [formControlName]=\"'main'\"\r\n />\r\n @if (configurationFormConfig()) {\r\n <mt-dynamic-form\r\n formControlName=\"configuration\"\r\n [formConfig]=\"configurationFormConfig()!\"\r\n />\r\n } @else {\r\n <ng-container #configurationHost></ng-container>\r\n @if (!configurationComponentExists()) {\r\n @switch (propertyType()) {\r\n @case (\"User\") {\r\n <mt-user-configuration />\r\n }\r\n @case (\"Percentage\") {\r\n <mt-percentage-configuration />\r\n }\r\n @case (\"Lookup\") {\r\n <mt-lookup-configuration />\r\n }\r\n @case (\"LookupMultiSelect\") {\r\n <mt-lookup-configuration />\r\n }\r\n @case (\"EntityList\") {\r\n <mt-entity-list-configuration />\r\n }\r\n @case (\"API\") {\r\n <mt-api-configuration formControlName=\"configuration\" />\r\n }\r\n @case (\"Status\") {\r\n <section #statusConfigurationSection>\r\n <mt-status-configuration\r\n [propertyId]=\"statusPropertyId()\"\r\n [contextKey]=\"formulaContextKey()\"\r\n [levelSchemaId]=\"formulaSchemaId()\"\r\n [moduleId]=\"formulaModuleId()\"\r\n />\r\n </section>\r\n }\r\n <!-- @case('ViewList') { REMOVED FOR NOW\r\n <mt-view-list-configuration />\r\n } -->\r\n @case (\"Attachment\") {\r\n <mt-attachment-configuration />\r\n }\r\n <!-- @case('ReferenceProperty') { REMOVED FOR NOW\r\n } -->\r\n @case (\"LookupModuleCheckList\") {\r\n <mt-check-list-form-configuration />\r\n }\r\n <!-- @case('LookupMatrix') { REMOVED FOR NOW\r\n <mt-lookup-configuration />\r\n } -->\r\n @case (\"Location\") {\r\n <mt-location-configuration />\r\n }\r\n }\r\n }\r\n }\r\n @if (isCalculated() && !hideFormulaBuilder()) {\r\n <mt-card>\r\n <ng-template #headless>\r\n <div\r\n class=\"flex items-center justify-between px-4 py-5 border-b border-surface\"\r\n >\r\n <h3 class=\"text-xl font-semibold\">\r\n {{ \"properties.form.formula\" | transloco }}\r\n <span class=\"text-red-500\">*</span>\r\n </h3>\r\n </div>\r\n <div class=\"flex-1 min-h-0 p-4\">\r\n <mt-formula-builder\r\n formControlName=\"formula\"\r\n [contextKey]=\"formulaContextKey()\"\r\n [levelSchemaId]=\"formulaSchemaId()\"\r\n [moduleId]=\"formulaModuleId()\"\r\n />\r\n </div>\r\n </ng-template>\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", "forcedDisabledFieldKeys", "preserveForcedHiddenValues", "visibleSectionKeys", "externalValues"], 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", "moduleId", "contextKey", "contextEntityTypeKey", "templateId", "placeholder", "hideToolbar", "hideStatusBar", "toolbarTabs", "codeOnly", "builderOnly", "valueMode", "isProcessBuilder"], 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", "contextKey", "levelSchemaId", "moduleId"] }, { 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" }] });
3008
3047
  }
3009
3048
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: PropertyForm, decorators: [{
3010
3049
  type: Component,
@@ -3027,7 +3066,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
3027
3066
  SkeletonModule,
3028
3067
  TranslocoModule,
3029
3068
  ], 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($event)\"\r\n />\r\n </ng-template>\r\n <div\r\n [formGroup]=\"propertyForm\"\r\n class=\"h-full py-4 h-full overflow-y-auto flex justify-center\"\r\n >\r\n <div class=\"w-2/3 flex flex-col gap-6\">\r\n @if (loading()) {\r\n <!-- Skeleton Loading State -->\r\n <div class=\"rounded-xl bg-white shadow-sm p-6 space-y-4\">\r\n <div class=\"flex justify-between items-center gap-6\">\r\n <p-skeleton width=\"50%\" height=\"3rem\"></p-skeleton>\r\n <p-skeleton width=\"8rem\" height=\"2.5rem\"></p-skeleton>\r\n </div>\r\n </div>\r\n\r\n <div class=\"rounded-xl bg-white shadow-sm p-6 space-y-4\">\r\n <p-skeleton\r\n width=\"12rem\"\r\n height=\"1.5rem\"\r\n styleClass=\"mb-4\"\r\n ></p-skeleton>\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n <p-skeleton height=\"3rem\"></p-skeleton>\r\n <p-skeleton height=\"3rem\"></p-skeleton>\r\n <p-skeleton height=\"6rem\" styleClass=\"md:col-span-2\"></p-skeleton>\r\n <p-skeleton height=\"3rem\" styleClass=\"md:col-span-2\"></p-skeleton>\r\n </div>\r\n </div>\r\n\r\n <div class=\"rounded-xl bg-white shadow-sm p-6 space-y-4\">\r\n <p-skeleton\r\n width=\"10rem\"\r\n height=\"1.5rem\"\r\n styleClass=\"mb-4\"\r\n ></p-skeleton>\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\r\n <p-skeleton height=\"3rem\"></p-skeleton>\r\n <p-skeleton height=\"3rem\"></p-skeleton>\r\n <p-skeleton height=\"8rem\" styleClass=\"md:col-span-2\"></p-skeleton>\r\n </div>\r\n </div>\r\n } @else {\r\n <mt-dynamic-form\r\n [formConfig]=\"dynamicFormConfigMain()\"\r\n [formControlName]=\"'main'\"\r\n />\r\n @if (configurationFormConfig()) {\r\n <mt-dynamic-form\r\n formControlName=\"configuration\"\r\n [formConfig]=\"configurationFormConfig()!\"\r\n />\r\n } @else {\r\n <ng-container #configurationHost></ng-container>\r\n @if (!configurationComponentExists()) {\r\n @switch (propertyType()) {\r\n @case (\"User\") {\r\n <mt-user-configuration />\r\n }\r\n @case (\"Percentage\") {\r\n <mt-percentage-configuration />\r\n }\r\n @case (\"Lookup\") {\r\n <mt-lookup-configuration />\r\n }\r\n @case (\"LookupMultiSelect\") {\r\n <mt-lookup-configuration />\r\n }\r\n @case (\"EntityList\") {\r\n <mt-entity-list-configuration />\r\n }\r\n @case (\"API\") {\r\n <mt-api-configuration formControlName=\"configuration\" />\r\n }\r\n @case (\"Status\") {\r\n <section #statusConfigurationSection>\r\n <mt-status-configuration\r\n [propertyId]=\"statusPropertyId()\"\r\n [contextKey]=\"formulaContextKey()\"\r\n [levelSchemaId]=\"formulaSchemaId()\"\r\n [moduleId]=\"formulaModuleId()\"\r\n />\r\n </section>\r\n }\r\n <!-- @case('ViewList') { REMOVED FOR NOW\r\n <mt-view-list-configuration />\r\n } -->\r\n @case (\"Attachment\") {\r\n <mt-attachment-configuration />\r\n }\r\n <!-- @case('ReferenceProperty') { REMOVED FOR NOW\r\n } -->\r\n @case (\"LookupModuleCheckList\") {\r\n <mt-check-list-form-configuration />\r\n }\r\n <!-- @case('LookupMatrix') { REMOVED FOR NOW\r\n <mt-lookup-configuration />\r\n } -->\r\n @case (\"Location\") {\r\n <mt-location-configuration />\r\n }\r\n }\r\n }\r\n }\r\n @if (isCalculated() && !hideFormulaBuilder()) {\r\n <mt-card>\r\n <ng-template #headless>\r\n <div\r\n class=\"flex items-center justify-between px-4 py-5 border-b border-surface\"\r\n >\r\n <h3 class=\"text-xl font-semibold\">\r\n {{ \"properties.form.formula\" | transloco }}\r\n <span class=\"text-red-500\">*</span>\r\n </h3>\r\n </div>\r\n <div class=\"flex-1 min-h-0 p-4\">\r\n <mt-formula-builder\r\n formControlName=\"formula\"\r\n [contextKey]=\"formulaContextKey()\"\r\n [levelSchemaId]=\"formulaSchemaId()\"\r\n [moduleId]=\"formulaModuleId()\"\r\n />\r\n </div>\r\n </ng-template>\r\n </mt-card>\r\n }\r\n }\r\n </div>\r\n </div>\r\n</mt-page>\r\n" }]
3030
- }], ctorParameters: () => [], propDecorators: { propertyId: [{ type: i0.Input, args: [{ isSignal: true, alias: "propertyId", required: false }] }], configurationHost: [{
3069
+ }], ctorParameters: () => [], propDecorators: { propertyId: [{ type: i0.Input, args: [{ isSignal: true, alias: "propertyId", required: false }] }], scope: [{ type: i0.Input, args: [{ isSignal: true, alias: "scope", required: false }] }], configurationHost: [{
3031
3070
  type: ViewChild,
3032
3071
  args: ['configurationHost', { read: ViewContainerRef }]
3033
3072
  }], statusConfigurationSection: [{ type: i0.ViewChild, args: ['statusConfigurationSection', { isSignal: true }] }] } });
@@ -3040,5 +3079,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
3040
3079
  * Generated bundle index. Do not edit.
3041
3080
  */
3042
3081
 
3043
- 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 };
3082
+ 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, buildPropertiesScopeContextKey };
3044
3083
  //# sourceMappingURL=masterteam-properties.mjs.map