@gooddata/sdk-ui-dashboard 11.65.1 → 11.66.0-alpha.1

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.
@@ -1,4 +1,4 @@
1
- export declare const LIB_VERSION = "11.65.1";
1
+ export declare const LIB_VERSION = "11.66.0-alpha.1";
2
2
  export declare const LIB_DESCRIPTION = "GoodData SDK - Dashboard Component";
3
3
  export declare const LIB_NAME = "@gooddata/sdk-ui-dashboard";
4
4
  //# sourceMappingURL=__version.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"__version.d.ts","sourceRoot":"","sources":["../src/__version.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,WAAW,YAAY,CAAC;AAErC,eAAO,MAAM,eAAe,uCAAuC,CAAC;AAEpE,eAAO,MAAM,QAAQ,+BAA+B,CAAC"}
1
+ {"version":3,"file":"__version.d.ts","sourceRoot":"","sources":["../src/__version.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,WAAW,oBAAoB,CAAC;AAE7C,eAAO,MAAM,eAAe,uCAAuC,CAAC;AAEpE,eAAO,MAAM,QAAQ,+BAA+B,CAAC"}
package/esm/__version.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // (C) 2021 GoodData Corporation
2
2
  // DO NOT CHANGE THIS FILE, IT IS RE-GENERATED ON EVERY BUILD
3
- export const LIB_VERSION = "11.65.1";
3
+ export const LIB_VERSION = "11.66.0-alpha.1";
4
4
  export const LIB_DESCRIPTION = "GoodData SDK - Dashboard Component";
5
5
  export const LIB_NAME = "@gooddata/sdk-ui-dashboard";
@@ -1 +1 @@
1
- {"version":3,"file":"filterViews.d.ts","sourceRoot":"","sources":["../../../../../src/model/commandHandlers/dashboard/common/filterViews.ts"],"names":[],"mappings":"AAIA,OAAO,EACH,KAAK,wBAAwB,EAC7B,KAAK,8BAA8B,EACtC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAGH,KAAK,iBAAiB,EACtB,KAAK,UAAU,EAGf,KAAK,+BAA+B,EAEpC,KAAK,oBAAoB,EAGzB,KAAK,cAAc,EACnB,KAAK,MAAM,EAqBd,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,sBAAsB,CAAC;AA+PvD,KAAK,oBAAoB,GAAG;IAAE,cAAc,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAkBnE,UAAU,6BAA6B;IACnC,aAAa,EAAE,cAAc,CAAC;IAC9B,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;CACpD;AAED,eAAO,MAAM,4BAA4B,kBACtB,cAAc,qBACV,iBAAiB,EAAE,8BACV,WAAW,CAAC,MAAM,CAAC,2BACtB,+BAA+B,EAAE,KAC3D,6BAuJF,CAAC;AAIF;;GAEG;AACH,MAAM,WAAW,8BAA8B;IAC3C;;;OAGG;IACH,QAAQ,CAAC,wBAAwB,CAAC,EAAE,OAAO,CAAC;IAC5C;;OAEG;IACH,QAAQ,CAAC,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAC3C;;;;OAIG;IACH,QAAQ,CAAC,wBAAwB,CAAC,EAAE,wBAAwB,EAAE,CAAC;CAClE;AAED;;;;;GAKG;AACH,wBAAgB,mCAAmC,CAC/C,SAAS,EAAE,UAAU,EACrB,WAAW,EAAE,oBAAoB,EAAE,EACnC,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,8BAA8B,GACxC,OAAO,CAUT;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACpC,WAAW,EAAE,oBAAoB,EAAE,EACnC,kBAAkB,EAAE,MAAM,EAC1B,UAAU,EAAE,OAAO,GACpB,oBAAoB,GAAG,SAAS,CAQlC;AAED;;;;GAIG;AACH,wBAAgB,mCAAmC,CAC/C,SAAS,EAAE,UAAU,EACrB,WAAW,EAAE,oBAAoB,EAAE,EACnC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,kBAAkB,EAAE,aAAa,CAAC,8BAA8B,CAAC,EACjE,UAAU,EAAE,UAAU,EACtB,OAAO,CAAC,EAAE,8BAA8B,GACzC,UAAU,CAIZ;AAED,wBAAgB,sBAAsB,CAClC,SAAS,EAAE,UAAU,EACrB,WAAW,EAAE,oBAAoB,EAAE,EACnC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,kBAAkB,EAAE,aAAa,CAAC,8BAA8B,CAAC,EACjE,OAAO,GAAE,8BAAmC,GAC7C,UAAU,CAuDZ"}
1
+ {"version":3,"file":"filterViews.d.ts","sourceRoot":"","sources":["../../../../../src/model/commandHandlers/dashboard/common/filterViews.ts"],"names":[],"mappings":"AAIA,OAAO,EACH,KAAK,wBAAwB,EAC7B,KAAK,8BAA8B,EACtC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAGH,KAAK,iBAAiB,EACtB,KAAK,UAAU,EAGf,KAAK,+BAA+B,EAEpC,KAAK,oBAAoB,EAGzB,KAAK,cAAc,EACnB,KAAK,MAAM,EAqBd,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAgQvD,KAAK,oBAAoB,GAAG;IAAE,cAAc,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAkBnE,UAAU,6BAA6B;IACnC,aAAa,EAAE,cAAc,CAAC;IAC9B,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;CACpD;AAED,eAAO,MAAM,4BAA4B,kBACtB,cAAc,qBACV,iBAAiB,EAAE,8BACV,WAAW,CAAC,MAAM,CAAC,2BACtB,+BAA+B,EAAE,KAC3D,6BAuJF,CAAC;AAIF;;GAEG;AACH,MAAM,WAAW,8BAA8B;IAC3C;;;OAGG;IACH,QAAQ,CAAC,wBAAwB,CAAC,EAAE,OAAO,CAAC;IAC5C;;OAEG;IACH,QAAQ,CAAC,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAC3C;;;;OAIG;IACH,QAAQ,CAAC,wBAAwB,CAAC,EAAE,wBAAwB,EAAE,CAAC;CAClE;AAED;;;;;GAKG;AACH,wBAAgB,mCAAmC,CAC/C,SAAS,EAAE,UAAU,EACrB,WAAW,EAAE,oBAAoB,EAAE,EACnC,UAAU,EAAE,UAAU,EACtB,OAAO,EAAE,8BAA8B,GACxC,OAAO,CAUT;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACpC,WAAW,EAAE,oBAAoB,EAAE,EACnC,kBAAkB,EAAE,MAAM,EAC1B,UAAU,EAAE,OAAO,GACpB,oBAAoB,GAAG,SAAS,CAQlC;AAED;;;;GAIG;AACH,wBAAgB,mCAAmC,CAC/C,SAAS,EAAE,UAAU,EACrB,WAAW,EAAE,oBAAoB,EAAE,EACnC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,kBAAkB,EAAE,aAAa,CAAC,8BAA8B,CAAC,EACjE,UAAU,EAAE,UAAU,EACtB,OAAO,CAAC,EAAE,8BAA8B,GACzC,UAAU,CAIZ;AAED,wBAAgB,sBAAsB,CAClC,SAAS,EAAE,UAAU,EACrB,WAAW,EAAE,oBAAoB,EAAE,EACnC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,kBAAkB,EAAE,aAAa,CAAC,8BAA8B,CAAC,EACjE,OAAO,GAAE,8BAAmC,GAC7C,UAAU,CAuDZ"}
@@ -3,7 +3,7 @@ import { isEqual, omit } from "lodash-es";
3
3
  import { areObjRefsEqual, dashboardAttributeFilterItemDisplayForm, dashboardAttributeFilterItemFilterElementsBy, dashboardAttributeFilterItemFilterElementsByDate, dashboardAttributeFilterItemLocalIdentifier, dashboardAttributeFilterItemTitle, dashboardAttributeFilterItemValidateElementsBy, dashboardFilterLocalIdentifier, dashboardMeasureValueFilterLocalIdentifier, isDashboardArbitraryAttributeFilter, isDashboardAttributeFilter, isDashboardAttributeFilterItem, isDashboardCommonDateFilter, isDashboardDateFilter, isDashboardMatchAttributeFilter, isDashboardMeasureValueFilter, isDashboardTextAttributeFilter, isExportOverrideFilterContext, isFilterContext, isSingleSelectionFilter, } from "@gooddata/sdk-model";
4
4
  import { filterLocalIdentifiers } from "../../../store/filtering/dashboardFilterSelectors.js";
5
5
  import { getRestrictedDashboardFilters } from "../../../store/filtering/restrictedFilterUtils.js";
6
- import { applyMirroredFilterValue, findCounterpartFilter, } from "../../../store/tabs/filterContext/filterSync.js";
6
+ import { applyMirroredFilterValue, findCounterpartFilter, targetAcceptsAttributeFilterValue, } from "../../../store/tabs/filterContext/filterSync.js";
7
7
  import { isFilterTypeCompatibleWithSelectionType } from "../../../utils/attributeFilterSelectionTypeCompatibility.js";
8
8
  const findMatchingAttributeFilterByLocalIdentifier = (filter, viewFilters) => viewFilters.find((item) => isDashboardAttributeFilter(item) &&
9
9
  item.attributeFilter.localIdentifier === filter.attributeFilter.localIdentifier);
@@ -422,9 +422,15 @@ function mirrorTabSelection(sourceBefore, sourceAfter, target, filterView, unava
422
422
  continue;
423
423
  }
424
424
  const counterpart = findCounterpartFilter(sourceState, before, targetState, attributesWithReferences);
425
- if (counterpart && !isRestricted(targetRestricted, counterpart)) {
426
- replacements.set(counterpart, applyMirroredFilterValue(after, counterpart));
425
+ // a filter keeps its own value when its selection type cannot store the mirrored one
426
+ if (!counterpart ||
427
+ isRestricted(targetRestricted, counterpart) ||
428
+ (isDashboardAttributeFilterItem(counterpart) &&
429
+ isDashboardAttributeFilterItem(after) &&
430
+ !targetAcceptsAttributeFilterValue(targetState, counterpart, after))) {
431
+ continue;
427
432
  }
433
+ replacements.set(counterpart, applyMirroredFilterValue(after, counterpart));
428
434
  }
429
435
  const mirroredFilters = target.filterContext.filters
430
436
  .filter((filter) => !isCommonDateFilter(filter))
@@ -1 +1 @@
1
- {"version":3,"file":"tabSyncRules.d.ts","sourceRoot":"","sources":["../../../../../src/model/commandHandlers/filterContext/tabSync/tabSyncRules.ts"],"names":[],"mappings":"AAoCA,OAAO,EAA4B,KAAK,kBAAkB,EAAoB,MAAM,mBAAmB,CAAC;AAExG,KAAK,cAAc,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;AAuZ9C;;;;;GAKG;AACH,eAAO,MAAM,YAAY,EAAE,WAAW,CAAC,MAAM,EAAE,cAAc,CAG3D,CAAC"}
1
+ {"version":3,"file":"tabSyncRules.d.ts","sourceRoot":"","sources":["../../../../../src/model/commandHandlers/filterContext/tabSync/tabSyncRules.ts"],"names":[],"mappings":"AAqCA,OAAO,EAA4B,KAAK,kBAAkB,EAAoB,MAAM,mBAAmB,CAAC;AAExG,KAAK,cAAc,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;AAye9C;;;;;GAKG;AACH,eAAO,MAAM,YAAY,EAAE,WAAW,CAAC,MAAM,EAAE,cAAc,CAG3D,CAAC"}
@@ -1,6 +1,6 @@
1
1
  // (C) 2026 GoodData Corporation
2
2
  import { areObjRefsEqual, dashboardAttributeFilterItemLocalIdentifier, dashboardFilterLocalIdentifier, isAllTimeDashboardDateFilter, isDashboardAttributeFilter, isDashboardAttributeFilterItem, isDashboardCommonDateFilter, isDashboardDateFilter, isDashboardDateFilterWithDimension, isDashboardMeasureValueFilter, isNoopAllTimeDashboardDateFilter, } from "@gooddata/sdk-model";
3
- import { applyMirroredFilterValue, findAppliedFilterForStaged, findCounterpartFilter, findOriginalFilter, isCrossFilteringVirtualFilter, retargetAttributeFilterItem, } from "../../../store/tabs/filterContext/filterSync.js";
3
+ import { applyMirroredFilterValue, findAppliedFilterForStaged, findCounterpartFilter, findOriginalFilter, isCrossFilteringVirtualFilter, retargetAttributeFilterItem, targetAcceptsAttributeFilterValue, } from "../../../store/tabs/filterContext/filterSync.js";
4
4
  import { tabsActions } from "../../../store/tabs/index.js";
5
5
  function defineRule(actionCreator, rule) {
6
6
  return defineActionsRule(actionCreator, (payload, target, ctx) => {
@@ -37,6 +37,24 @@ function findCounterpart(ctx, target, sourceLocalId) {
37
37
  const sourceFilter = findFilterByLocalId(ctx.source, sourceLocalId);
38
38
  return sourceFilter ? findCounterpartOf(ctx, ctx.source, sourceFilter, target) : undefined;
39
39
  }
40
+ /**
41
+ * Attribute-filter counterpart of a replacement.
42
+ *
43
+ * The first lookup uses the filter before the action. A value the target cannot store, such as a
44
+ * text value on a list-only filter, leaves the tabs on different kinds, so the next value is matched
45
+ * from the filter after the action. A reset does the same: the restored source value is a list again,
46
+ * and the target restores its own original.
47
+ */
48
+ function findReplacedAttributeCounterpart(ctx, target, sourceFilter, sourceLocalId) {
49
+ const counterpart = findCounterpartOf(ctx, ctx.source, sourceFilter, target);
50
+ if (isDashboardAttributeFilterItem(counterpart)) {
51
+ return counterpart;
52
+ }
53
+ const sourceFilterAfter = findFilterByLocalId(ctx.sourceAfter, sourceLocalId);
54
+ return isDashboardAttributeFilterItem(sourceFilterAfter)
55
+ ? findCounterpartOf(ctx, ctx.sourceAfter, sourceFilterAfter, target)
56
+ : undefined;
57
+ }
40
58
  function counterpartLocalId(ctx, target, sourceLocalId) {
41
59
  const counterpart = findCounterpart(ctx, target, sourceLocalId);
42
60
  return counterpart ? dashboardFilterLocalIdentifier(counterpart) : undefined;
@@ -57,6 +75,22 @@ function findSelectionCounterpart(ctx, target, sourceLocalId) {
57
75
  ? counterpart
58
76
  : undefined;
59
77
  }
78
+ /**
79
+ * The list filter on `target` that stores a list selection from `sourceLocalId`.
80
+ * A list value is written onto a list filter and onto a list-or-text filter, and is not written
81
+ * onto a text-only filter. A reset still resolves the counterpart, so the tab restores its own value.
82
+ */
83
+ function mirroredListSelection(ctx, target, sourceLocalId, restoreTargetOriginal) {
84
+ const counterpart = findSelectionCounterpart(ctx, target, sourceLocalId);
85
+ if (!counterpart || restoreTargetOriginal) {
86
+ return counterpart;
87
+ }
88
+ const sourceFilter = findFilterByLocalId(ctx.source, sourceLocalId);
89
+ return isDashboardAttributeFilter(sourceFilter) &&
90
+ targetAcceptsAttributeFilterValue(target, counterpart, sourceFilter)
91
+ ? counterpart
92
+ : undefined;
93
+ }
60
94
  function findMeasureValueCounterpart(ctx, target, sourceLocalId) {
61
95
  const sourceFilter = findFilterByLocalId(ctx.source, sourceLocalId);
62
96
  if (!isDashboardMeasureValueFilter(sourceFilter)) {
@@ -110,6 +144,11 @@ function committedFilterValues(ctx, target) {
110
144
  }
111
145
  const counterpart = findCounterpartOf(ctx, ctx.sourceAfter, committed, target);
112
146
  if (counterpart) {
147
+ if (isDashboardAttributeFilterItem(committed) &&
148
+ isDashboardAttributeFilterItem(counterpart) &&
149
+ !targetAcceptsAttributeFilterValue(target, counterpart, committed)) {
150
+ return [];
151
+ }
113
152
  return [applyMirroredFilterValue(committed, counterpart)];
114
153
  }
115
154
  // A tab without a common date filter is all time, so it receives the committed value
@@ -144,6 +183,12 @@ const filterContextRules = [
144
183
  if (!isDashboardAttributeFilter(counterpart)) {
145
184
  return [];
146
185
  }
186
+ const sourceFilter = findFilterByLocalId(ctx.source, payload.filterLocalId);
187
+ if (!payload.restoreTargetOriginal &&
188
+ (!isDashboardAttributeFilter(sourceFilter) ||
189
+ !targetAcceptsAttributeFilterValue(target, counterpart, sourceFilter))) {
190
+ return [];
191
+ }
147
192
  const filterLocalId = dashboardFilterLocalIdentifier(counterpart);
148
193
  if (!payload.restoreTargetOriginal) {
149
194
  const changeDisplayForm = tabsActions.changeAttributeDisplayForm({ ...payload, filterLocalId });
@@ -201,7 +246,7 @@ const selectionRules = [
201
246
  if (payload.isWorkingSelectionChange || payload.isResultOfMigration) {
202
247
  return undefined;
203
248
  }
204
- const counterpart = findSelectionCounterpart(ctx, target, payload.filterLocalId);
249
+ const counterpart = mirroredListSelection(ctx, target, payload.filterLocalId, payload.restoreTargetOriginal);
205
250
  if (!counterpart) {
206
251
  return undefined;
207
252
  }
@@ -230,7 +275,7 @@ const selectionRules = [
230
275
  if (!isDashboardAttributeFilterItem(sourceFilter)) {
231
276
  return undefined;
232
277
  }
233
- const counterpart = findCounterpartOf(ctx, ctx.source, sourceFilter, target);
278
+ const counterpart = findReplacedAttributeCounterpart(ctx, target, sourceFilter, payload.filterLocalId);
234
279
  if (!isDashboardAttributeFilterItem(counterpart)) {
235
280
  return undefined;
236
281
  }
@@ -243,11 +288,15 @@ const selectionRules = [
243
288
  return undefined;
244
289
  }
245
290
  const replacement = isDashboardAttributeFilterItem(original) ? original : payload.filter;
291
+ if (!payload.restoreTargetOriginal &&
292
+ !targetAcceptsAttributeFilterValue(target, counterpart, replacement)) {
293
+ return undefined;
294
+ }
246
295
  return { ...payload, filterLocalId, filter: retargetAttributeFilterItem(replacement, filterLocalId) };
247
296
  }),
248
297
  defineRule(tabsActions.clearAttributeFiltersSelection, (payload, target, ctx) => {
249
298
  const filterLocalIds = payload.filterLocalIds.flatMap((filterLocalId) => {
250
- const counterpart = findSelectionCounterpart(ctx, target, filterLocalId);
299
+ const counterpart = mirroredListSelection(ctx, target, filterLocalId, payload.restoreTargetOriginal);
251
300
  return counterpart ? [counterpart.attributeFilter.localIdentifier] : [];
252
301
  });
253
302
  if (filterLocalIds.length === 0) {
@@ -28,10 +28,11 @@ export type CrossFilteringLocalIdsByTab = Readonly<Record<string, readonly strin
28
28
  export declare function isCrossFilteringVirtualFilter(tab: ITabState, localIdentifier: string | undefined, crossFilteringLocalIdsByTab: CrossFilteringLocalIdsByTab | undefined): boolean;
29
29
  /**
30
30
  * Finds the filter on `targetTab` that is the same logical filter as `sourceFilter`.
31
- * An attribute filter is a counterpart only when it is of the same type (list or text), has the
32
- * same display-as label and selection type, both with their defaults applied, and the same single
33
- * or multiple value selection mode.
34
- * A missing or incompatible counterpart is a no-op for the caller.
31
+ * An attribute filter is a counterpart when it is of the same type (list or text), shows the same
32
+ * label, and selects either a single value or multiple values. Selection type is not part of that
33
+ * identity: it only limits how a value can be entered on a tab. Whether the value itself can be
34
+ * stored on the counterpart is decided by {@link targetAcceptsAttributeFilterValue}.
35
+ * A missing counterpart is a no-op for the caller.
35
36
  *
36
37
  * Assumes at most one filter per display form, date data set, and measure with a given
37
38
  * dimensionality on a tab.
@@ -119,5 +120,16 @@ export interface ISyncedTabSeed {
119
120
  * @internal
120
121
  */
121
122
  export declare function seedSyncedTabFilters(sourceTab: ITabState, base: IFilterContextDefinition, crossFilteringLocalIdsByTab?: CrossFilteringLocalIdsByTab): ISyncedTabSeed;
123
+ /**
124
+ * Whether `value` can be stored on `targetFilter`.
125
+ *
126
+ * A list selection is valid on a list filter and on a list-or-text filter, so it syncs in both
127
+ * directions. A text value, such as a "contains" match, is valid on a text filter and on a
128
+ * list-or-text filter, and cannot be applied to a list-only filter. An omitted selection type
129
+ * means list-or-text, except a single-value list filter, which means list.
130
+ *
131
+ * @internal
132
+ */
133
+ export declare function targetAcceptsAttributeFilterValue(targetTab: ITabState, targetFilter: DashboardAttributeFilterItem, value: DashboardAttributeFilterItem): boolean;
122
134
  export {};
123
135
  //# sourceMappingURL=filterSync.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"filterSync.d.ts","sourceRoot":"","sources":["../../../../../src/model/store/tabs/filterContext/filterSync.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"filterSync.d.ts","sourceRoot":"","sources":["../../../../../src/model/store/tabs/filterContext/filterSync.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  // (C) 2026 GoodData Corporation
2
2
  import { areObjRefsEqual, dashboardAttributeFilterItemDisplayForm, dashboardAttributeFilterItemFilterElementsBy, dashboardAttributeFilterItemFilterElementsByDate, dashboardAttributeFilterItemLocalIdentifier, dashboardAttributeFilterItemValidateElementsBy, dashboardFilterLocalIdentifier, isDashboardArbitraryAttributeFilter, isDashboardAttributeFilter, isDashboardAttributeFilterItem, isDashboardCommonDateFilter, isDashboardDateFilter, isDashboardMatchAttributeFilter, isDashboardMeasureValueFilter, isSingleSelectionFilter, } from "@gooddata/sdk-model";
3
3
  import { displayFormsEquivalent, findAttributeFilterCounterpart, } from "../../../utils/attributeFilterMatching.js";
4
- import { effectiveSelectionTypeOf } from "../../../utils/attributeFilterSelectionTypeCompatibility.js";
4
+ import { canApplyFilterTypeToTarget } from "../../../utils/attributeFilterSelectionTypeCompatibility.js";
5
5
  /**
6
6
  * True when `localIdentifier` belongs to a cross-filtering virtual filter on `tab`.
7
7
  * Those filters are applied on their own tab only and are not mirrored to or from other tabs.
@@ -16,10 +16,11 @@ export function isCrossFilteringVirtualFilter(tab, localIdentifier, crossFilteri
16
16
  }
17
17
  /**
18
18
  * Finds the filter on `targetTab` that is the same logical filter as `sourceFilter`.
19
- * An attribute filter is a counterpart only when it is of the same type (list or text), has the
20
- * same display-as label and selection type, both with their defaults applied, and the same single
21
- * or multiple value selection mode.
22
- * A missing or incompatible counterpart is a no-op for the caller.
19
+ * An attribute filter is a counterpart when it is of the same type (list or text), shows the same
20
+ * label, and selects either a single value or multiple values. Selection type is not part of that
21
+ * identity: it only limits how a value can be entered on a tab. Whether the value itself can be
22
+ * stored on the counterpart is decided by {@link targetAcceptsAttributeFilterValue}.
23
+ * A missing counterpart is a no-op for the caller.
23
24
  *
24
25
  * Assumes at most one filter per display form, date data set, and measure with a given
25
26
  * dimensionality on a tab.
@@ -339,17 +340,33 @@ function attributeFilterPresentation(tab, filter) {
339
340
  : undefined;
340
341
  return {
341
342
  displayAsLabel: config?.displayAsLabel ?? dashboardAttributeFilterItemDisplayForm(filter),
342
- selectionType: effectiveSelectionTypeOf(config?.selectionType, filter),
343
343
  isSingleSelection: isDashboardAttributeFilter(filter) && isSingleSelectionFilter(filter),
344
344
  };
345
345
  }
346
346
  /**
347
- * Attribute filters sync only when they show the same label, accept the same selection type
348
- * and both select either a single value or multiple values.
347
+ * Whether `value` can be stored on `targetFilter`.
348
+ *
349
+ * A list selection is valid on a list filter and on a list-or-text filter, so it syncs in both
350
+ * directions. A text value, such as a "contains" match, is valid on a text filter and on a
351
+ * list-or-text filter, and cannot be applied to a list-only filter. An omitted selection type
352
+ * means list-or-text, except a single-value list filter, which means list.
353
+ *
354
+ * @internal
355
+ */
356
+ export function targetAcceptsAttributeFilterValue(targetTab, targetFilter, value) {
357
+ const localIdentifier = dashboardAttributeFilterItemLocalIdentifier(targetFilter);
358
+ const selectionType = localIdentifier
359
+ ? targetTab.attributeFilterConfigs?.attributeFilterConfigs?.find((config) => config.localIdentifier === localIdentifier)?.selectionType
360
+ : undefined;
361
+ const valueType = isDashboardAttributeFilter(value) ? "list" : "text";
362
+ return canApplyFilterTypeToTarget(valueType, selectionType, targetFilter);
363
+ }
364
+ /**
365
+ * Attribute filters are the same filter when they show the same label and both select either a
366
+ * single value or multiple values.
349
367
  */
350
368
  function samePresentation(left, right, displayForms) {
351
- return (left.selectionType === right.selectionType &&
352
- left.isSingleSelection === right.isSingleSelection &&
369
+ return (left.isSingleSelection === right.isSingleSelection &&
353
370
  displayFormsEquivalent(left.displayAsLabel, right.displayAsLabel, displayForms));
354
371
  }
355
372
  function findDateCounterpart(sourceFilter, targets) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gooddata/sdk-ui-dashboard",
3
- "version": "11.65.1",
3
+ "version": "11.66.0-alpha.1",
4
4
  "description": "GoodData SDK - Dashboard Component",
5
5
  "license": "LicenseRef-LICENSE",
6
6
  "author": "GoodData Corporation",
@@ -60,22 +60,22 @@
60
60
  "ts-invariant": "0.10.3",
61
61
  "tslib": "2.8.1",
62
62
  "uuid": "11.1.1",
63
- "@gooddata/sdk-backend-base": "11.65.1",
64
- "@gooddata/sdk-backend-spi": "11.65.1",
65
- "@gooddata/sdk-embedding": "11.65.1",
66
- "@gooddata/sdk-model": "11.65.1",
67
- "@gooddata/sdk-ui": "11.65.1",
68
- "@gooddata/sdk-ui-analytical-designer": "11.65.1",
69
- "@gooddata/sdk-ui-charts": "11.65.1",
70
- "@gooddata/sdk-ui-ext": "11.65.1",
71
- "@gooddata/sdk-ui-filters": "11.65.1",
72
- "@gooddata/sdk-ui-geo": "11.65.1",
73
- "@gooddata/sdk-ui-pivot": "11.65.1",
74
- "@gooddata/sdk-ui-kit": "11.65.1",
75
- "@gooddata/sdk-ui-semantic-search": "11.65.1",
76
- "@gooddata/sdk-ui-theme-provider": "11.65.1",
77
- "@gooddata/sdk-ui-vis-commons": "11.65.1",
78
- "@gooddata/util": "11.65.1"
63
+ "@gooddata/sdk-backend-base": "11.66.0-alpha.1",
64
+ "@gooddata/sdk-backend-spi": "11.66.0-alpha.1",
65
+ "@gooddata/sdk-embedding": "11.66.0-alpha.1",
66
+ "@gooddata/sdk-model": "11.66.0-alpha.1",
67
+ "@gooddata/sdk-ui": "11.66.0-alpha.1",
68
+ "@gooddata/sdk-ui-analytical-designer": "11.66.0-alpha.1",
69
+ "@gooddata/sdk-ui-charts": "11.66.0-alpha.1",
70
+ "@gooddata/sdk-ui-ext": "11.66.0-alpha.1",
71
+ "@gooddata/sdk-ui-filters": "11.66.0-alpha.1",
72
+ "@gooddata/sdk-ui-geo": "11.66.0-alpha.1",
73
+ "@gooddata/sdk-ui-pivot": "11.66.0-alpha.1",
74
+ "@gooddata/sdk-ui-kit": "11.66.0-alpha.1",
75
+ "@gooddata/sdk-ui-semantic-search": "11.66.0-alpha.1",
76
+ "@gooddata/sdk-ui-theme-provider": "11.66.0-alpha.1",
77
+ "@gooddata/sdk-ui-vis-commons": "11.66.0-alpha.1",
78
+ "@gooddata/util": "11.66.0-alpha.1"
79
79
  },
80
80
  "devDependencies": {
81
81
  "@microsoft/api-documenter": "7.30.16",
@@ -117,12 +117,12 @@
117
117
  "svgo": "2.8.4",
118
118
  "typescript": "7.0.2",
119
119
  "vitest": "5.0.4",
120
- "@gooddata/i18n-toolkit": "11.65.1",
121
- "@gooddata/eslint-config": "11.65.1",
122
- "@gooddata/oxlint-config": "11.65.1",
123
- "@gooddata/reference-workspace": "11.65.1",
124
- "@gooddata/sdk-backend-mockingbird": "11.65.1",
125
- "@gooddata/stylelint-config": "11.65.1"
120
+ "@gooddata/i18n-toolkit": "11.66.0-alpha.1",
121
+ "@gooddata/eslint-config": "11.66.0-alpha.1",
122
+ "@gooddata/oxlint-config": "11.66.0-alpha.1",
123
+ "@gooddata/reference-workspace": "11.66.0-alpha.1",
124
+ "@gooddata/sdk-backend-mockingbird": "11.66.0-alpha.1",
125
+ "@gooddata/stylelint-config": "11.66.0-alpha.1"
126
126
  },
127
127
  "peerDependencies": {
128
128
  "react": "^18.0.0 || ^19.0.0",