cat-qw-lib 2.6.31 → 2.6.33

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,45 @@ 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
+ const hasRecord = !!record && (!!record._id ||
3970
+ !!record.apiConfigId ||
3971
+ (record.dataItems?.length ?? 0) > 0 ||
3972
+ (record.badges?.length ?? 0) > 0 ||
3973
+ !!record.headerDictionaryID);
3974
+ // Ignore initial empty emissions to avoid clearing edit values before actual record arrives.
3975
+ if (!hasRecord) {
3976
+ return;
3977
+ }
3978
+ // recordChange can emit readonly store objects; clone before normalization/mutation.
3979
+ const editableRecord = structuredClone((record || {}));
3980
+ const withAliases = this.normalizeIncomingDictionaryAliases(editableRecord);
3981
+ const withStyles = this.normalizeLoadedRecordStyles(withAliases);
3982
+ this.record = withStyles;
3983
+ // Hydrate dependent dictionary-item dropdown arrays immediately on edit load.
3984
+ this.refreshDictionaryItemListsForRecord();
3974
3985
  // Dictionaries are scoped by apiConfigId (not queueID — that field does not exist on widget).
3975
- this.handleAPIChange(record.apiConfigId);
3986
+ this.handleAPIChange(this.record.apiConfigId);
3976
3987
  });
3977
3988
  }
3989
+ /**
3990
+ * Normalize backend dictionary keys into UI form keys on edit load.
3991
+ * This lets dropdowns preselect values immediately without user re-selection.
3992
+ */
3993
+ normalizeIncomingDictionaryAliases(record) {
3994
+ return {
3995
+ ...record,
3996
+ dataItems: (record.dataItems || []).map((item) => ({
3997
+ ...item,
3998
+ dataDictionaryId: item.dataDictionaryId || item.dictionaryID || '',
3999
+ dictionaryItemId: item.dictionaryItemId || item.dictionaryItemID || '',
4000
+ })),
4001
+ badges: (record.badges || []).map((badge) => ({
4002
+ ...badge,
4003
+ dataDictionaryId: badge.dataDictionaryId || badge.dictionaryID || '',
4004
+ dictionaryItemId: badge.dictionaryItemId || badge.dictionaryItemID || '',
4005
+ })),
4006
+ };
4007
+ }
3978
4008
  handleWidgetItemAddBtnClick() {
3979
4009
  if (!(this.record.name && this.record.apiConfigId))
3980
4010
  return;
@@ -3999,9 +4029,46 @@ class WidgetAdminFormComponent extends BaseFormComponent {
3999
4029
  }
4000
4030
  handleAPIChange(apiConfigId) {
4001
4031
  this.query.getLists().subscribe((allLists) => {
4002
- const allDictionaryRecords = allLists.find((list) => list.forProperty === 'dataDictionaryId')?.records;
4003
- this.dictionaries =
4004
- allDictionaryRecords?.filter((item) => String(item.apiConfigId ?? item.apiConfigID ?? '') === String(apiConfigId ?? '')) || [];
4032
+ const dictionaryListMeta = allLists.find((list) => list.forProperty === 'dataDictionaryId' || list.forProperty === 'dictionaryID');
4033
+ const allDictionaryRecords = dictionaryListMeta?.records;
4034
+ if (this.enableDictionaryDebugLogs) {
4035
+ console.log('[WidgetAdmin] dictionary list resolved', {
4036
+ expectedForProperty: ['dataDictionaryId', 'dictionaryID'],
4037
+ actualForProperty: dictionaryListMeta?.forProperty,
4038
+ dataSource: dictionaryListMeta?.dataSource,
4039
+ totalRecords: allDictionaryRecords?.length || 0,
4040
+ selectedApiConfigId: apiConfigId
4041
+ });
4042
+ }
4043
+ if (apiConfigId) {
4044
+ this.dictionaries =
4045
+ allDictionaryRecords?.filter((item) => String(item.apiConfigId ?? item.apiConfigID ?? '') === String(apiConfigId ?? '')) || [];
4046
+ }
4047
+ else {
4048
+ // Edit fallback when apiConfigId is not yet available: keep dictionaries needed by currently selected IDs.
4049
+ const selectedDictionaryIds = new Set();
4050
+ if (this.record?.headerDictionaryID)
4051
+ selectedDictionaryIds.add(String(this.record.headerDictionaryID));
4052
+ if (this.record?.subHeaderDictionaryID)
4053
+ selectedDictionaryIds.add(String(this.record.subHeaderDictionaryID));
4054
+ (this.record?.dataItems || []).forEach((item) => {
4055
+ const id = item?.dataDictionaryId || item?.dictionaryID;
4056
+ if (id)
4057
+ selectedDictionaryIds.add(String(id));
4058
+ });
4059
+ (this.record?.badges || []).forEach((badge) => {
4060
+ const id = badge?.dataDictionaryId || badge?.dictionaryID;
4061
+ if (id)
4062
+ selectedDictionaryIds.add(String(id));
4063
+ });
4064
+ this.dictionaries = (allDictionaryRecords || []).filter((d) => selectedDictionaryIds.has(String(d?._id)));
4065
+ }
4066
+ if (this.enableDictionaryDebugLogs) {
4067
+ console.log('[WidgetAdmin] dictionary records after apiConfigId filter', {
4068
+ selectedApiConfigId: apiConfigId,
4069
+ filteredCount: this.dictionaries.length,
4070
+ });
4071
+ }
4005
4072
  this.refreshDictionaryItemListsForRecord();
4006
4073
  });
4007
4074
  }
@@ -4011,7 +4078,16 @@ class WidgetAdminFormComponent extends BaseFormComponent {
4011
4078
  */
4012
4079
  refreshDictionaryItemListsForRecord() {
4013
4080
  this.query.getLists().subscribe((allLists) => {
4014
- const allDictionaryItemRecords = allLists.find((list) => list.forProperty === 'dictionaryItemId')?.records || [];
4081
+ const dictionaryItemListMeta = allLists.find((list) => list.forProperty === 'dictionaryItemId' || list.forProperty === 'dictionaryItemID');
4082
+ const allDictionaryItemRecords = dictionaryItemListMeta?.records || [];
4083
+ if (this.enableDictionaryDebugLogs) {
4084
+ console.log('[WidgetAdmin] dictionary item list resolved', {
4085
+ expectedForProperty: ['dictionaryItemId', 'dictionaryItemID'],
4086
+ actualForProperty: dictionaryItemListMeta?.forProperty,
4087
+ dataSource: dictionaryItemListMeta?.dataSource,
4088
+ totalRecords: allDictionaryItemRecords.length,
4089
+ });
4090
+ }
4015
4091
  const itemsForDictionary = (dictionaryId) => this.getDictionaryItemsByDictionaryId(allDictionaryItemRecords, dictionaryId);
4016
4092
  const r = this.record;
4017
4093
  this.headerDictionaryItems = itemsForDictionary(r.headerDictionaryID);
@@ -4024,8 +4100,14 @@ class WidgetAdminFormComponent extends BaseFormComponent {
4024
4100
  if (!dictionaryId) {
4025
4101
  return [];
4026
4102
  }
4027
- const byLegacyDictionaryId = allDictionaryItemRecords.filter((item) => item.dataDictionaryId === dictionaryId);
4103
+ const byLegacyDictionaryId = allDictionaryItemRecords.filter((item) => item.dataDictionaryId === dictionaryId || item.dictionaryID === dictionaryId);
4028
4104
  if (byLegacyDictionaryId.length > 0) {
4105
+ if (this.enableDictionaryDebugLogs) {
4106
+ console.log('[WidgetAdmin] dictionary items matched by dictionary id relation', {
4107
+ dictionaryId,
4108
+ matchedCount: byLegacyDictionaryId.length
4109
+ });
4110
+ }
4029
4111
  return byLegacyDictionaryId;
4030
4112
  }
4031
4113
  const selectedDictionary = this.dictionaries.find((d) => d._id === dictionaryId);
@@ -4034,23 +4116,31 @@ class WidgetAdminFormComponent extends BaseFormComponent {
4034
4116
  return [];
4035
4117
  }
4036
4118
  const dictionaryItemsIdSet = new Set(dictionaryItemsIds.map((id) => String(id)));
4037
- return allDictionaryItemRecords.filter((item) => dictionaryItemsIdSet.has(String(item._id)));
4119
+ const byDictionaryItemsIds = allDictionaryItemRecords.filter((item) => dictionaryItemsIdSet.has(String(item._id)));
4120
+ if (this.enableDictionaryDebugLogs) {
4121
+ console.log('[WidgetAdmin] dictionary items matched by dictionaryItemsIds fallback', {
4122
+ dictionaryId,
4123
+ dictionaryItemsIdsCount: dictionaryItemsIds.length,
4124
+ matchedCount: byDictionaryItemsIds.length
4125
+ });
4126
+ }
4127
+ return byDictionaryItemsIds;
4038
4128
  }
4039
4129
  handleHeaderDictionarySelect(dictionaryId) {
4040
4130
  this.query.getLists().subscribe((allLists) => {
4041
- const allDictionaryItemRecords = allLists.find((list) => list.forProperty === 'dictionaryItemId')?.records;
4131
+ const allDictionaryItemRecords = allLists.find((list) => list.forProperty === 'dictionaryItemId' || list.forProperty === 'dictionaryItemID')?.records;
4042
4132
  this.headerDictionaryItems = this.getDictionaryItemsByDictionaryId(allDictionaryItemRecords || [], dictionaryId);
4043
4133
  });
4044
4134
  }
4045
4135
  handleSubHeaderDictionarySelect(dictionaryId) {
4046
4136
  this.query.getLists().subscribe((allLists) => {
4047
- const allDictionaryItemRecords = allLists.find((list) => list.forProperty === 'dictionaryItemId')?.records;
4137
+ const allDictionaryItemRecords = allLists.find((list) => list.forProperty === 'dictionaryItemId' || list.forProperty === 'dictionaryItemID')?.records;
4048
4138
  this.subHeaderDictionaryItems = this.getDictionaryItemsByDictionaryId(allDictionaryItemRecords || [], dictionaryId);
4049
4139
  });
4050
4140
  }
4051
4141
  handleWidgetItemDictionarySelect(dictionaryId, index) {
4052
4142
  this.query.getLists().subscribe((allLists) => {
4053
- const allDictionaryItemRecords = allLists.find((list) => list.forProperty === 'dictionaryItemId')?.records;
4143
+ const allDictionaryItemRecords = allLists.find((list) => list.forProperty === 'dictionaryItemId' || list.forProperty === 'dictionaryItemID')?.records;
4054
4144
  this.dictionaryItemArray[index] = this.getDictionaryItemsByDictionaryId(allDictionaryItemRecords || [], dictionaryId);
4055
4145
  });
4056
4146
  }
@@ -4077,7 +4167,7 @@ class WidgetAdminFormComponent extends BaseFormComponent {
4077
4167
  }
4078
4168
  handleBadgeDictionarySelect(dictionaryId, index) {
4079
4169
  this.query.getLists().subscribe((allLists) => {
4080
- const allDictionaryItemRecords = allLists.find((list) => list.forProperty === 'dictionaryItemId')?.records;
4170
+ const allDictionaryItemRecords = allLists.find((list) => list.forProperty === 'dictionaryItemId' || list.forProperty === 'dictionaryItemID')?.records;
4081
4171
  this.badgeDictionaryItemArray[index] = this.getDictionaryItemsByDictionaryId(allDictionaryItemRecords || [], dictionaryId);
4082
4172
  });
4083
4173
  }
@@ -4103,14 +4193,18 @@ class WidgetAdminFormComponent extends BaseFormComponent {
4103
4193
  * Text-box controls expect stringified JSON; API returns nested objects → "[object Object]" without this.
4104
4194
  */
4105
4195
  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
- });
4196
+ return {
4197
+ ...record,
4198
+ style: this.service.coerceStyleToJsonText(record.style),
4199
+ dataItems: (record.dataItems || []).map((item) => ({
4200
+ ...item,
4201
+ style: this.service.coerceStyleToJsonText(item.style),
4202
+ })),
4203
+ badges: (record.badges || []).map((badge) => ({
4204
+ ...badge,
4205
+ style: this.service.coerceStyleToJsonText(badge.style),
4206
+ })),
4207
+ };
4114
4208
  }
4115
4209
  handleSubmit() {
4116
4210
  this.record.style = this.service.parseStylePayload(this.record.style);