@acorex/platform 20.9.39 → 20.9.41

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.
@@ -23,7 +23,7 @@ import * as i1$1 from '@acorex/components/avatar';
23
23
  import { AXAvatarModule } from '@acorex/components/avatar';
24
24
  import * as i3$1 from '@acorex/components/image';
25
25
  import { AXImageModule } from '@acorex/components/image';
26
- import { isNil, isEmpty, cloneDeep, isEqual, get, isString, unionBy, sortBy, isArray, set, merge, capitalize } from 'lodash-es';
26
+ import { isNil, isEmpty, cloneDeep, isEqual, get, isString, isPlainObject, unionBy, sortBy, isArray, set, merge, capitalize } from 'lodash-es';
27
27
  import * as i1$3 from '@acorex/components/badge';
28
28
  import { AXBadgeComponent, AXBadgeModule } from '@acorex/components/badge';
29
29
  import { AXPLayoutThemeService, AXPMenuVerticalMode } from '@acorex/platform/themes/shared';
@@ -3308,23 +3308,7 @@ class AXPQueryFiltersComponent {
3308
3308
  const context = this.context();
3309
3309
  const editingField = this.activeFilter()?.field;
3310
3310
  void this.translationEpoch();
3311
- Promise.all(filters.map(async (filter) => {
3312
- const committedEntry = this.getCommittedFilterEntry(filter, context, editingField);
3313
- const val = committedEntry?.value ?? filter.value;
3314
- const displayText = committedEntry?.displayText;
3315
- const rawDisplay = displayText != null && displayText !== '' ? displayText : await this.getDisplayValue(filter, val);
3316
- const displayValue = await this.formatFilterDisplayValue(rawDisplay);
3317
- const operatorType = committedEntry?.operation?.type ?? filter.operator?.type;
3318
- const operatorKey = ALL_DEFAULT_OPERATORS.find((o) => o.name === operatorType)?.title;
3319
- const title = await this.translateLabel(filter.title);
3320
- const operator = operatorKey ? await this.translateLabel(operatorKey) : '';
3321
- return {
3322
- ...filter,
3323
- readOnly: filter.readOnly === true ||
3324
- filter.widget?.options?.['readonly'] === true,
3325
- query: `${title} ${operator} '${displayValue}'`.trim(),
3326
- };
3327
- })).then((results) => {
3311
+ Promise.all(filters.map((filter) => this.buildFilterTag(filter, context, editingField))).then((results) => {
3328
3312
  this.asyncTags.set(results.filter((r) => !r.hidden));
3329
3313
  });
3330
3314
  }, ...(ngDevMode ? [{ debugName: "#updateTagsEffect" }] : /* istanbul ignore next */ []));
@@ -3711,6 +3695,32 @@ class AXPQueryFiltersComponent {
3711
3695
  }
3712
3696
  }
3713
3697
  #updateTagsEffect;
3698
+ /**
3699
+ * Builds a single chip. Never rejects: definitions coming from backend data (e.g. document metadata
3700
+ * fields) can carry unexpected title/value shapes, and one failure used to leave every chip unrendered.
3701
+ */
3702
+ async buildFilterTag(filter, context, editingField) {
3703
+ const readOnly = filter.readOnly === true || filter.widget?.options?.['readonly'] === true;
3704
+ try {
3705
+ const committedEntry = this.getCommittedFilterEntry(filter, context, editingField);
3706
+ const val = committedEntry?.value ?? filter.value;
3707
+ const displayText = committedEntry?.displayText;
3708
+ const rawDisplay = displayText != null && displayText !== '' ? displayText : await this.getDisplayValue(filter, val);
3709
+ const displayValue = await this.formatFilterDisplayValue(rawDisplay);
3710
+ const operatorType = committedEntry?.operation?.type ?? filter.operator?.type;
3711
+ const operatorKey = ALL_DEFAULT_OPERATORS.find((o) => o.name === operatorType)?.title;
3712
+ const title = await this.translateLabel(filter.title);
3713
+ const operator = operatorKey ? await this.translateLabel(operatorKey) : '';
3714
+ return {
3715
+ ...filter,
3716
+ readOnly,
3717
+ query: `${title} ${operator} '${displayValue}'`.trim(),
3718
+ };
3719
+ }
3720
+ catch {
3721
+ return { ...filter, readOnly, query: isString(filter.title) ? filter.title.trim() : '' };
3722
+ }
3723
+ }
3714
3724
  #disabledEvaluationEffect;
3715
3725
  isFilterDisabled(definition) {
3716
3726
  if (typeof definition.disabled === 'boolean') {
@@ -3730,17 +3740,23 @@ class AXPQueryFiltersComponent {
3730
3740
  return '';
3731
3741
  }
3732
3742
  const parts = Array.isArray(value) ? value : [value];
3733
- const labels = await Promise.all(parts.map(async (part) => {
3734
- const text = String(part ?? '').trim();
3735
- if (!text) {
3736
- return '';
3737
- }
3738
- return this.translateLabel(text);
3739
- }));
3743
+ const labels = await Promise.all(parts.map((part) => this.translateLabel(part)));
3740
3744
  return labels.filter(Boolean).join(', ');
3741
3745
  }
3746
+ /**
3747
+ * Resolves a label that may be an i18n key, a plain string, or a multi-language object
3748
+ * (filter definitions built from backend data are not guaranteed to be plain strings).
3749
+ */
3742
3750
  async translateLabel(text) {
3743
- const trimmed = text.trim();
3751
+ if (isNil(text)) {
3752
+ return '';
3753
+ }
3754
+ const resolved = isString(text)
3755
+ ? text
3756
+ : isPlainObject(text)
3757
+ ? this.translate.resolve(text)
3758
+ : String(text);
3759
+ const trimmed = isString(resolved) ? resolved.trim() : '';
3744
3760
  if (!trimmed) {
3745
3761
  return '';
3746
3762
  }