@masterteam/properties 0.0.78 → 0.0.80

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.
@@ -60,6 +60,37 @@ var PropertiesActionKey;
60
60
  PropertiesActionKey["DeletePropertyStatus"] = "deletePropertyStatus";
61
61
  PropertiesActionKey["ReorderPropertyStatuses"] = "reorderPropertyStatuses";
62
62
  })(PropertiesActionKey || (PropertiesActionKey = {}));
63
+ /**
64
+ * The level the current property scope belongs to, or null on a standalone
65
+ * module screen. On a level/module screen the level is the scope parent; on a
66
+ * level screen it is the scope target itself.
67
+ */
68
+ function resolvePropertiesScopeLevelId(state) {
69
+ const levelId = state.parentModuleType?.toString().toLowerCase() === 'level'
70
+ ? state.parentModuleId
71
+ : state.moduleType?.toString().toLowerCase() === 'level'
72
+ ? state.moduleId
73
+ : null;
74
+ return levelId === null || levelId === undefined || levelId === ''
75
+ ? null
76
+ : levelId.toString();
77
+ }
78
+ /**
79
+ * Source-field catalog URL for a configuration picker (Record List, module
80
+ * check list).
81
+ *
82
+ * The root `Properties/Module/{id}` route returns only the source module own
83
+ * properties. When the property is authored inside a level, the picker must
84
+ * offer the level-effective catalog instead — otherwise properties configured
85
+ * on that level are missing from it.
86
+ */
87
+ function buildPropertiesCatalogUrl(baseUrl, state, moduleType, moduleId) {
88
+ const levelId = resolvePropertiesScopeLevelId(state);
89
+ if (levelId && moduleType.toString().toLowerCase() === 'module') {
90
+ return `${baseUrl}/level/${levelId}/module/${moduleId}`;
91
+ }
92
+ return `${baseUrl}/${moduleType}/${moduleId}`;
93
+ }
63
94
 
64
95
  class GetProperties {
65
96
  params;
@@ -281,22 +312,22 @@ let PropertiesState = class PropertiesState extends CrudStateBase {
281
312
  return state.parentModuleId ?? null;
282
313
  }
283
314
  /**
284
- * Canonical formula-builder context key for the current scope, in the same
285
- * format used for the catalog request: `Level:5/Module:10` (module under a
286
- * level), `Level:5` (level), or `Module:10` (standalone module). Returns
287
- * null when no scope is set. This lets the formula builder address a
288
- * standalone module as `Module:{id}` instead of mistaking it for a level.
315
+ * Canonical context key for the current scope, in the same format used for
316
+ * the catalog request: `Level:5/Module:10` (module under a level), `Level:5`
317
+ * (level), or `Module:10` (standalone module). Returns null when no scope is
318
+ * set. Callers use it to tell which scope a loaded catalog belongs to, so a
319
+ * catalog fetched for another level/module is never reused.
320
+ */
321
+ static scopeContextKey(state) {
322
+ return resolveScopeContextKey(state);
323
+ }
324
+ /**
325
+ * The formula builder addresses the current scope by that same key, so a
326
+ * standalone module reads as `Module:{id}` instead of being mistaken for a
327
+ * level.
289
328
  */
290
329
  static formulaContextKey(state) {
291
- if (state.moduleType == null || state.moduleId == null) {
292
- return null;
293
- }
294
- return buildPropertiesScopeContextKey({
295
- target: { type: state.moduleType, id: state.moduleId },
296
- parent: state.parentModuleType != null && state.parentModuleId != null
297
- ? { type: state.parentModuleType, id: state.parentModuleId }
298
- : undefined,
299
- });
330
+ return resolveScopeContextKey(state);
300
331
  }
301
332
  static lookups(state) {
302
333
  return state.lookups;
@@ -573,7 +604,7 @@ let PropertiesState = class PropertiesState extends CrudStateBase {
573
604
  }
574
605
  getPropertiesForConfigType(ctx, action) {
575
606
  const { moduleType, moduleId } = action;
576
- const req$ = this.http.get(`${this.configPropertiesUrl}/${moduleType}/${moduleId}`);
607
+ const req$ = this.http.get(buildPropertiesCatalogUrl(this.configPropertiesUrl, ctx.getState(), moduleType, moduleId));
577
608
  return handleApiRequest({
578
609
  ctx,
579
610
  key: PropertiesActionKey.GetConfigProperties,
@@ -840,6 +871,9 @@ __decorate([
840
871
  __decorate([
841
872
  Selector()
842
873
  ], PropertiesState, "parentModuleId", null);
874
+ __decorate([
875
+ Selector()
876
+ ], PropertiesState, "scopeContextKey", null);
843
877
  __decorate([
844
878
  Selector()
845
879
  ], PropertiesState, "formulaContextKey", null);
@@ -894,6 +928,17 @@ PropertiesState = PropertiesState_1 = __decorate([
894
928
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: PropertiesState, decorators: [{
895
929
  type: Injectable
896
930
  }], 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: [] } });
931
+ function resolveScopeContextKey(state) {
932
+ if (state.moduleType == null || state.moduleId == null) {
933
+ return null;
934
+ }
935
+ return buildPropertiesScopeContextKey({
936
+ target: { type: state.moduleType, id: state.moduleId },
937
+ parent: state.parentModuleType != null && state.parentModuleId != null
938
+ ? { type: state.parentModuleType, id: state.parentModuleId }
939
+ : undefined,
940
+ });
941
+ }
897
942
  function mapCatalogProperty(property) {
898
943
  return {
899
944
  id: property.id,
@@ -922,6 +967,7 @@ class PropertiesFacade {
922
967
  moduleId = select(PropertiesState.moduleId);
923
968
  parentModuleId = select(PropertiesState.parentModuleId);
924
969
  formulaContextKey = select(PropertiesState.formulaContextKey);
970
+ scopeContextKey = select(PropertiesState.scopeContextKey);
925
971
  lookups = select(PropertiesState.lookups);
926
972
  configProperties = select(PropertiesState.configTypeProperties);
927
973
  groups = select(PropertiesState.groups);
@@ -1570,6 +1616,13 @@ class CheckListFormConfiguration {
1570
1616
  controlContainer = inject(ControlContainer);
1571
1617
  parentGroup = this.controlContainer.control;
1572
1618
  transloco = inject(TranslocoService);
1619
+ /**
1620
+ * Scope + source module the loaded catalog belongs to, e.g.
1621
+ * `Level:9/Module:25|26`. Keyed on the scope as well as the source module so
1622
+ * a catalog loaded for another level is never reused — the request itself is
1623
+ * level-scoped.
1624
+ */
1625
+ loadedCatalogKey = signal(null, ...(ngDevMode ? [{ debugName: "loadedCatalogKey" }] : /* istanbul ignore next */ []));
1573
1626
  lookups = this.propertiesFacade.lookups;
1574
1627
  configScopes = this.propertiesFacade.configScopes;
1575
1628
  configProperties = this.propertiesFacade.configProperties;
@@ -1583,8 +1636,8 @@ class CheckListFormConfiguration {
1583
1636
  {
1584
1637
  key: 'configuration',
1585
1638
  label: this.transloco.translate('properties.form.configurationSection'),
1586
- cssClass: ' rounded-xl bg-content \
1587
- shadow-sm \
1639
+ cssClass: ' rounded-xl bg-content \
1640
+ shadow-sm \
1588
1641
  px-6 py-4',
1589
1642
  type: 'header',
1590
1643
  bodyClass: 'grid grid-cols-1 md:grid-cols-2 gap-3',
@@ -1631,12 +1684,25 @@ class CheckListFormConfiguration {
1631
1684
  });
1632
1685
  effect(() => {
1633
1686
  const scopeId = this.configuration()?.scopeId;
1634
- if (scopeId) {
1635
- const scopeType = this.configScopes()[0]?.scope;
1636
- if (scopeType) {
1637
- this.propertiesFacade.loadPropertiesForConfigType(scopeType, scopeId);
1638
- }
1687
+ if (!scopeId) {
1688
+ return;
1689
+ }
1690
+ const scopeType = this.configScopes()[0]?.scope;
1691
+ if (!scopeType) {
1692
+ return;
1693
+ }
1694
+ // Wait for the scope: the catalog request is level-scoped, so loading
1695
+ // before the scope is known would show the unscoped catalog first.
1696
+ const scopeKey = this.propertiesFacade.scopeContextKey();
1697
+ if (!scopeKey) {
1698
+ return;
1639
1699
  }
1700
+ const catalogKey = `${scopeKey}|${scopeId}`;
1701
+ if (catalogKey === this.loadedCatalogKey()) {
1702
+ return;
1703
+ }
1704
+ this.loadedCatalogKey.set(catalogKey);
1705
+ this.propertiesFacade.loadPropertiesForConfigType(scopeType, scopeId);
1640
1706
  });
1641
1707
  }
1642
1708
  ngOnDestroy() {
@@ -1659,7 +1725,13 @@ class EntityListConfiguration {
1659
1725
  controlContainer = inject(ControlContainer);
1660
1726
  parentGroup = this.controlContainer.control;
1661
1727
  transloco = inject(TranslocoService);
1662
- previousModuleId = signal(null, ...(ngDevMode ? [{ debugName: "previousModuleId" }] : /* istanbul ignore next */ []));
1728
+ /**
1729
+ * Scope + source module the loaded catalog belongs to, e.g.
1730
+ * `Level:9/Module:25|26`. Keyed on the scope as well as the source module so
1731
+ * a catalog loaded for another level is never reused — the request itself is
1732
+ * level-scoped.
1733
+ */
1734
+ loadedCatalogKey = signal(null, ...(ngDevMode ? [{ debugName: "loadedCatalogKey" }] : /* istanbul ignore next */ []));
1663
1735
  configurationControl = this.parentGroup.get('configuration');
1664
1736
  configScopes = this.propertiesFacade.configScopes;
1665
1737
  configProperties = this.propertiesFacade.configProperties;
@@ -1692,8 +1764,8 @@ class EntityListConfiguration {
1692
1764
  {
1693
1765
  key: 'configuration',
1694
1766
  label: this.transloco.translate('properties.form.configurationSection'),
1695
- cssClass: ' rounded-xl bg-content \
1696
- shadow-sm \
1767
+ cssClass: ' rounded-xl bg-content \
1768
+ shadow-sm \
1697
1769
  px-6 py-4',
1698
1770
  type: 'header',
1699
1771
  bodyClass: 'grid grid-cols-1 md:grid-cols-2 gap-3',
@@ -1766,14 +1838,24 @@ class EntityListConfiguration {
1766
1838
  effect(() => {
1767
1839
  const config = this.configuration();
1768
1840
  const moduleId = config?.moduleId;
1769
- if (!moduleId || moduleId === this.previousModuleId()) {
1841
+ if (!moduleId) {
1770
1842
  return;
1771
1843
  }
1772
1844
  const scopeType = this.configScopes()[0]?.scope;
1773
1845
  if (!scopeType) {
1774
1846
  return;
1775
1847
  }
1776
- this.previousModuleId.set(moduleId);
1848
+ // Wait for the scope: the catalog request is level-scoped, so loading
1849
+ // before the scope is known would show the unscoped catalog first.
1850
+ const scopeKey = this.propertiesFacade.scopeContextKey();
1851
+ if (!scopeKey) {
1852
+ return;
1853
+ }
1854
+ const catalogKey = `${scopeKey}|${moduleId}`;
1855
+ if (catalogKey === this.loadedCatalogKey()) {
1856
+ return;
1857
+ }
1858
+ this.loadedCatalogKey.set(catalogKey);
1777
1859
  this.propertiesFacade.loadPropertiesForConfigType(scopeType, moduleId);
1778
1860
  });
1779
1861
  }
@@ -1920,9 +2002,9 @@ const PERCENTAGE_MAX_VALUE = 100;
1920
2002
  */
1921
2003
  const PERCENTAGE_DEFAULT_COLOR_RULES = [
1922
2004
  { minValue: 0, maxValue: 25, color: '#ed2517' },
1923
- { minValue: 25, maxValue: 50, color: '#FFB300' },
1924
- { minValue: 50, maxValue: 75, color: '#0A5EBE' },
1925
- { minValue: 75, maxValue: 100, color: '#4caf50' },
2005
+ { minValue: 26, maxValue: 50, color: '#FFB300' },
2006
+ { minValue: 51, maxValue: 75, color: '#0A5EBE' },
2007
+ { minValue: 76, maxValue: 100, color: '#4caf50' },
1926
2008
  ];
1927
2009
  const HEX_COLOR_PATTERN = /^#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$/;
1928
2010
  function toFiniteNumber(value) {
@@ -3578,5 +3660,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
3578
3660
  * Generated bundle index. Do not edit.
3579
3661
  */
3580
3662
 
3581
- 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 };
3663
+ 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, buildPropertiesCatalogUrl, buildPropertiesScopeContextKey, resolvePropertiesScopeLevelId };
3582
3664
  //# sourceMappingURL=masterteam-properties.mjs.map