cat-qw-lib 2.6.31 → 2.6.32

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.
@@ -3945,6 +3945,7 @@ class WidgetAdminFormComponent extends BaseFormComponent {
3945
3945
  badgeDictionaryItemArray = [];
3946
3946
  widgetOptionsArray = [];
3947
3947
  widgetLayoutTypeList = widgetLayoutTypeList;
3948
+ enableDictionaryDebugLogs = true;
3948
3949
  constructor(service, validatorService, widgetStore, query, router, activatedRoute, baseStore, baseQuery) {
3949
3950
  super(service, validatorService, router, activatedRoute);
3950
3951
  this.service = service;
@@ -3965,16 +3966,36 @@ class WidgetAdminFormComponent extends BaseFormComponent {
3965
3966
  super.init();
3966
3967
  this.baseStore.setIsApiValidated(null);
3967
3968
  this.recordChange.asObservable().subscribe((record) => {
3968
- // Ensure arrays are initialized
3969
- if (!record.dataItems)
3970
- record.dataItems = [];
3971
- if (!record.badges)
3972
- record.badges = [];
3973
- this.normalizeLoadedRecordStyles(record);
3969
+ // recordChange can emit readonly store objects; clone before normalization/mutation.
3970
+ const editableRecord = structuredClone((record || {}));
3971
+ const withAliases = this.normalizeIncomingDictionaryAliases(editableRecord);
3972
+ const withStyles = this.normalizeLoadedRecordStyles(withAliases);
3973
+ this.record = withStyles;
3974
+ // Hydrate dependent dictionary-item dropdown arrays immediately on edit load.
3975
+ this.refreshDictionaryItemListsForRecord();
3974
3976
  // Dictionaries are scoped by apiConfigId (not queueID — that field does not exist on widget).
3975
- this.handleAPIChange(record.apiConfigId);
3977
+ this.handleAPIChange(this.record.apiConfigId);
3976
3978
  });
3977
3979
  }
3980
+ /**
3981
+ * Normalize backend dictionary keys into UI form keys on edit load.
3982
+ * This lets dropdowns preselect values immediately without user re-selection.
3983
+ */
3984
+ normalizeIncomingDictionaryAliases(record) {
3985
+ return {
3986
+ ...record,
3987
+ dataItems: (record.dataItems || []).map((item) => ({
3988
+ ...item,
3989
+ dataDictionaryId: item.dataDictionaryId || item.dictionaryID || '',
3990
+ dictionaryItemId: item.dictionaryItemId || item.dictionaryItemID || '',
3991
+ })),
3992
+ badges: (record.badges || []).map((badge) => ({
3993
+ ...badge,
3994
+ dataDictionaryId: badge.dataDictionaryId || badge.dictionaryID || '',
3995
+ dictionaryItemId: badge.dictionaryItemId || badge.dictionaryItemID || '',
3996
+ })),
3997
+ };
3998
+ }
3978
3999
  handleWidgetItemAddBtnClick() {
3979
4000
  if (!(this.record.name && this.record.apiConfigId))
3980
4001
  return;
@@ -3999,9 +4020,25 @@ class WidgetAdminFormComponent extends BaseFormComponent {
3999
4020
  }
4000
4021
  handleAPIChange(apiConfigId) {
4001
4022
  this.query.getLists().subscribe((allLists) => {
4002
- const allDictionaryRecords = allLists.find((list) => list.forProperty === 'dataDictionaryId')?.records;
4023
+ const dictionaryListMeta = allLists.find((list) => list.forProperty === 'dataDictionaryId' || list.forProperty === 'dictionaryID');
4024
+ const allDictionaryRecords = dictionaryListMeta?.records;
4025
+ if (this.enableDictionaryDebugLogs) {
4026
+ console.log('[WidgetAdmin] dictionary list resolved', {
4027
+ expectedForProperty: ['dataDictionaryId', 'dictionaryID'],
4028
+ actualForProperty: dictionaryListMeta?.forProperty,
4029
+ dataSource: dictionaryListMeta?.dataSource,
4030
+ totalRecords: allDictionaryRecords?.length || 0,
4031
+ selectedApiConfigId: apiConfigId
4032
+ });
4033
+ }
4003
4034
  this.dictionaries =
4004
4035
  allDictionaryRecords?.filter((item) => String(item.apiConfigId ?? item.apiConfigID ?? '') === String(apiConfigId ?? '')) || [];
4036
+ if (this.enableDictionaryDebugLogs) {
4037
+ console.log('[WidgetAdmin] dictionary records after apiConfigId filter', {
4038
+ selectedApiConfigId: apiConfigId,
4039
+ filteredCount: this.dictionaries.length,
4040
+ });
4041
+ }
4005
4042
  this.refreshDictionaryItemListsForRecord();
4006
4043
  });
4007
4044
  }
@@ -4011,7 +4048,16 @@ class WidgetAdminFormComponent extends BaseFormComponent {
4011
4048
  */
4012
4049
  refreshDictionaryItemListsForRecord() {
4013
4050
  this.query.getLists().subscribe((allLists) => {
4014
- const allDictionaryItemRecords = allLists.find((list) => list.forProperty === 'dictionaryItemId')?.records || [];
4051
+ const dictionaryItemListMeta = allLists.find((list) => list.forProperty === 'dictionaryItemId' || list.forProperty === 'dictionaryItemID');
4052
+ const allDictionaryItemRecords = dictionaryItemListMeta?.records || [];
4053
+ if (this.enableDictionaryDebugLogs) {
4054
+ console.log('[WidgetAdmin] dictionary item list resolved', {
4055
+ expectedForProperty: ['dictionaryItemId', 'dictionaryItemID'],
4056
+ actualForProperty: dictionaryItemListMeta?.forProperty,
4057
+ dataSource: dictionaryItemListMeta?.dataSource,
4058
+ totalRecords: allDictionaryItemRecords.length,
4059
+ });
4060
+ }
4015
4061
  const itemsForDictionary = (dictionaryId) => this.getDictionaryItemsByDictionaryId(allDictionaryItemRecords, dictionaryId);
4016
4062
  const r = this.record;
4017
4063
  this.headerDictionaryItems = itemsForDictionary(r.headerDictionaryID);
@@ -4024,8 +4070,14 @@ class WidgetAdminFormComponent extends BaseFormComponent {
4024
4070
  if (!dictionaryId) {
4025
4071
  return [];
4026
4072
  }
4027
- const byLegacyDictionaryId = allDictionaryItemRecords.filter((item) => item.dataDictionaryId === dictionaryId);
4073
+ const byLegacyDictionaryId = allDictionaryItemRecords.filter((item) => item.dataDictionaryId === dictionaryId || item.dictionaryID === dictionaryId);
4028
4074
  if (byLegacyDictionaryId.length > 0) {
4075
+ if (this.enableDictionaryDebugLogs) {
4076
+ console.log('[WidgetAdmin] dictionary items matched by dictionary id relation', {
4077
+ dictionaryId,
4078
+ matchedCount: byLegacyDictionaryId.length
4079
+ });
4080
+ }
4029
4081
  return byLegacyDictionaryId;
4030
4082
  }
4031
4083
  const selectedDictionary = this.dictionaries.find((d) => d._id === dictionaryId);
@@ -4034,23 +4086,31 @@ class WidgetAdminFormComponent extends BaseFormComponent {
4034
4086
  return [];
4035
4087
  }
4036
4088
  const dictionaryItemsIdSet = new Set(dictionaryItemsIds.map((id) => String(id)));
4037
- return allDictionaryItemRecords.filter((item) => dictionaryItemsIdSet.has(String(item._id)));
4089
+ const byDictionaryItemsIds = allDictionaryItemRecords.filter((item) => dictionaryItemsIdSet.has(String(item._id)));
4090
+ if (this.enableDictionaryDebugLogs) {
4091
+ console.log('[WidgetAdmin] dictionary items matched by dictionaryItemsIds fallback', {
4092
+ dictionaryId,
4093
+ dictionaryItemsIdsCount: dictionaryItemsIds.length,
4094
+ matchedCount: byDictionaryItemsIds.length
4095
+ });
4096
+ }
4097
+ return byDictionaryItemsIds;
4038
4098
  }
4039
4099
  handleHeaderDictionarySelect(dictionaryId) {
4040
4100
  this.query.getLists().subscribe((allLists) => {
4041
- const allDictionaryItemRecords = allLists.find((list) => list.forProperty === 'dictionaryItemId')?.records;
4101
+ const allDictionaryItemRecords = allLists.find((list) => list.forProperty === 'dictionaryItemId' || list.forProperty === 'dictionaryItemID')?.records;
4042
4102
  this.headerDictionaryItems = this.getDictionaryItemsByDictionaryId(allDictionaryItemRecords || [], dictionaryId);
4043
4103
  });
4044
4104
  }
4045
4105
  handleSubHeaderDictionarySelect(dictionaryId) {
4046
4106
  this.query.getLists().subscribe((allLists) => {
4047
- const allDictionaryItemRecords = allLists.find((list) => list.forProperty === 'dictionaryItemId')?.records;
4107
+ const allDictionaryItemRecords = allLists.find((list) => list.forProperty === 'dictionaryItemId' || list.forProperty === 'dictionaryItemID')?.records;
4048
4108
  this.subHeaderDictionaryItems = this.getDictionaryItemsByDictionaryId(allDictionaryItemRecords || [], dictionaryId);
4049
4109
  });
4050
4110
  }
4051
4111
  handleWidgetItemDictionarySelect(dictionaryId, index) {
4052
4112
  this.query.getLists().subscribe((allLists) => {
4053
- const allDictionaryItemRecords = allLists.find((list) => list.forProperty === 'dictionaryItemId')?.records;
4113
+ const allDictionaryItemRecords = allLists.find((list) => list.forProperty === 'dictionaryItemId' || list.forProperty === 'dictionaryItemID')?.records;
4054
4114
  this.dictionaryItemArray[index] = this.getDictionaryItemsByDictionaryId(allDictionaryItemRecords || [], dictionaryId);
4055
4115
  });
4056
4116
  }
@@ -4077,7 +4137,7 @@ class WidgetAdminFormComponent extends BaseFormComponent {
4077
4137
  }
4078
4138
  handleBadgeDictionarySelect(dictionaryId, index) {
4079
4139
  this.query.getLists().subscribe((allLists) => {
4080
- const allDictionaryItemRecords = allLists.find((list) => list.forProperty === 'dictionaryItemId')?.records;
4140
+ const allDictionaryItemRecords = allLists.find((list) => list.forProperty === 'dictionaryItemId' || list.forProperty === 'dictionaryItemID')?.records;
4081
4141
  this.badgeDictionaryItemArray[index] = this.getDictionaryItemsByDictionaryId(allDictionaryItemRecords || [], dictionaryId);
4082
4142
  });
4083
4143
  }
@@ -4103,14 +4163,18 @@ class WidgetAdminFormComponent extends BaseFormComponent {
4103
4163
  * Text-box controls expect stringified JSON; API returns nested objects → "[object Object]" without this.
4104
4164
  */
4105
4165
  normalizeLoadedRecordStyles(record) {
4106
- // Always normalize top-level style for text-box binding.
4107
- record.style = this.service.coerceStyleToJsonText(record.style);
4108
- record.dataItems?.forEach((item) => {
4109
- item.style = this.service.coerceStyleToJsonText(item.style);
4110
- });
4111
- record.badges?.forEach((badge) => {
4112
- badge.style = this.service.coerceStyleToJsonText(badge.style);
4113
- });
4166
+ return {
4167
+ ...record,
4168
+ style: this.service.coerceStyleToJsonText(record.style),
4169
+ dataItems: (record.dataItems || []).map((item) => ({
4170
+ ...item,
4171
+ style: this.service.coerceStyleToJsonText(item.style),
4172
+ })),
4173
+ badges: (record.badges || []).map((badge) => ({
4174
+ ...badge,
4175
+ style: this.service.coerceStyleToJsonText(badge.style),
4176
+ })),
4177
+ };
4114
4178
  }
4115
4179
  handleSubmit() {
4116
4180
  this.record.style = this.service.parseStylePayload(this.record.style);