@gooddata/sdk-ui-dashboard 11.65.0 → 11.65.2-alpha.0
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.
- package/esm/__version.d.ts +1 -1
- package/esm/__version.d.ts.map +1 -1
- package/esm/__version.js +1 -1
- package/esm/model/commandHandlers/dashboard/common/filterViews.d.ts.map +1 -1
- package/esm/model/commandHandlers/dashboard/common/filterViews.js +9 -3
- package/esm/model/commandHandlers/filterContext/tabSync/tabSyncRules.d.ts.map +1 -1
- package/esm/model/commandHandlers/filterContext/tabSync/tabSyncRules.js +53 -4
- package/esm/model/store/tabs/filterContext/filterSync.d.ts +16 -4
- package/esm/model/store/tabs/filterContext/filterSync.d.ts.map +1 -1
- package/esm/model/store/tabs/filterContext/filterSync.js +27 -10
- package/package.json +23 -23
package/esm/__version.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const LIB_VERSION = "11.65.0";
|
|
1
|
+
export declare const LIB_VERSION = "11.65.2-alpha.0";
|
|
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
|
package/esm/__version.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"__version.d.ts","sourceRoot":"","sources":["../src/__version.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,WAAW,
|
|
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.0";
|
|
3
|
+
export const LIB_VERSION = "11.65.2-alpha.0";
|
|
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;
|
|
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
|
-
|
|
426
|
-
|
|
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":"
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
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":"AAEA,OAAO,EAAE,KAAK,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAC1E,OAAO,EACH,KAAK,4BAA4B,
|
|
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 {
|
|
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
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
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
|
-
*
|
|
348
|
-
*
|
|
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.
|
|
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.0",
|
|
3
|
+
"version": "11.65.2-alpha.0",
|
|
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.0",
|
|
64
|
-
"@gooddata/sdk-
|
|
65
|
-
"@gooddata/sdk-
|
|
66
|
-
"@gooddata/sdk-model": "11.65.0",
|
|
67
|
-
"@gooddata/sdk-ui": "11.65.0",
|
|
68
|
-
"@gooddata/sdk-ui-analytical-designer": "11.65.0",
|
|
69
|
-
"@gooddata/sdk-ui-charts": "11.65.0",
|
|
70
|
-
"@gooddata/sdk-ui-ext": "11.65.0",
|
|
71
|
-
"@gooddata/sdk-ui-filters": "11.65.0",
|
|
72
|
-
"@gooddata/sdk-ui-geo": "11.65.0",
|
|
73
|
-
"@gooddata/sdk-ui-kit": "11.65.0",
|
|
74
|
-
"@gooddata/sdk-ui-pivot": "11.65.0",
|
|
75
|
-
"@gooddata/sdk-ui-semantic-search": "11.65.0",
|
|
76
|
-
"@gooddata/sdk-ui-
|
|
77
|
-
"@gooddata/
|
|
78
|
-
"@gooddata/
|
|
63
|
+
"@gooddata/sdk-backend-base": "11.65.2-alpha.0",
|
|
64
|
+
"@gooddata/sdk-backend-spi": "11.65.2-alpha.0",
|
|
65
|
+
"@gooddata/sdk-embedding": "11.65.2-alpha.0",
|
|
66
|
+
"@gooddata/sdk-model": "11.65.2-alpha.0",
|
|
67
|
+
"@gooddata/sdk-ui": "11.65.2-alpha.0",
|
|
68
|
+
"@gooddata/sdk-ui-analytical-designer": "11.65.2-alpha.0",
|
|
69
|
+
"@gooddata/sdk-ui-charts": "11.65.2-alpha.0",
|
|
70
|
+
"@gooddata/sdk-ui-ext": "11.65.2-alpha.0",
|
|
71
|
+
"@gooddata/sdk-ui-filters": "11.65.2-alpha.0",
|
|
72
|
+
"@gooddata/sdk-ui-geo": "11.65.2-alpha.0",
|
|
73
|
+
"@gooddata/sdk-ui-kit": "11.65.2-alpha.0",
|
|
74
|
+
"@gooddata/sdk-ui-pivot": "11.65.2-alpha.0",
|
|
75
|
+
"@gooddata/sdk-ui-semantic-search": "11.65.2-alpha.0",
|
|
76
|
+
"@gooddata/sdk-ui-vis-commons": "11.65.2-alpha.0",
|
|
77
|
+
"@gooddata/util": "11.65.2-alpha.0",
|
|
78
|
+
"@gooddata/sdk-ui-theme-provider": "11.65.2-alpha.0"
|
|
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/eslint-config": "11.65.0",
|
|
121
|
-
"@gooddata/i18n-toolkit": "11.65.0",
|
|
122
|
-
"@gooddata/
|
|
123
|
-
"@gooddata/
|
|
124
|
-
"@gooddata/sdk-backend-mockingbird": "11.65.0",
|
|
125
|
-
"@gooddata/stylelint-config": "11.65.0"
|
|
120
|
+
"@gooddata/eslint-config": "11.65.2-alpha.0",
|
|
121
|
+
"@gooddata/i18n-toolkit": "11.65.2-alpha.0",
|
|
122
|
+
"@gooddata/reference-workspace": "11.65.2-alpha.0",
|
|
123
|
+
"@gooddata/oxlint-config": "11.65.2-alpha.0",
|
|
124
|
+
"@gooddata/sdk-backend-mockingbird": "11.65.2-alpha.0",
|
|
125
|
+
"@gooddata/stylelint-config": "11.65.2-alpha.0"
|
|
126
126
|
},
|
|
127
127
|
"peerDependencies": {
|
|
128
128
|
"react": "^18.0.0 || ^19.0.0",
|