@gooddata/sdk-ui-dashboard 11.36.0-alpha.1 → 11.36.0-alpha.2
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.js +1 -1
- package/esm/_staging/drills/drillingUtils.d.ts +9 -0
- package/esm/_staging/drills/drillingUtils.js +19 -1
- package/esm/index.d.ts +2 -2
- package/esm/index.js +1 -1
- package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/index.js +9 -2
- package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/loadMeasureParameterDependencies.d.ts +12 -0
- package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/loadMeasureParameterDependencies.js +98 -0
- package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/resolveDashboardConfig.js +1 -0
- package/esm/model/commandHandlers/drill/common/mergeFilters.d.ts +3 -3
- package/esm/model/commandHandlers/drill/common/mergeFilters.js +26 -1
- package/esm/model/commandHandlers/drill/common/sourceDrillFilters.d.ts +2 -1
- package/esm/model/commandHandlers/drill/common/sourceDrillFilters.js +25 -5
- package/esm/model/commandHandlers/drill/drillToDashboardHandler.js +17 -16
- package/esm/model/commandHandlers/filterContext/changeFilterContextSelectionHandler.js +7 -4
- package/esm/model/commandHandlers/filterContext/measureValueFilter/removeMeasureValueFilterHandler.js +7 -0
- package/esm/model/react/useWidgetFilters.js +4 -1
- package/esm/model/store/catalog/catalogReducers.d.ts +5 -1
- package/esm/model/store/catalog/catalogReducers.js +4 -0
- package/esm/model/store/catalog/catalogSelectors.d.ts +15 -2
- package/esm/model/store/catalog/catalogSelectors.js +13 -0
- package/esm/model/store/catalog/catalogState.d.ts +20 -1
- package/esm/model/store/catalog/catalogState.js +1 -0
- package/esm/model/store/catalog/index.d.ts +1 -0
- package/esm/model/store/tabs/index.d.ts +6 -0
- package/esm/model/store/tabs/layout/layoutReducers.d.ts +4 -0
- package/esm/model/store/tabs/layout/layoutReducers.js +25 -0
- package/esm/model/store/tabs/parameters/parametersSelectors.d.ts +19 -6
- package/esm/model/store/tabs/parameters/parametersSelectors.js +69 -16
- package/esm/presentation/filterBar/parameterFilter/DashboardParameterFilter.js +3 -2
- package/esm/presentation/localization/bundles/en-US.localization-bundle.d.ts +8 -0
- package/esm/presentation/localization/bundles/en-US.localization-bundle.js +8 -0
- package/esm/presentation/widget/common/configuration/FilterConfiguration.js +4 -2
- package/esm/presentation/widget/common/configuration/useMeasureValueFilterCompatibility.d.ts +6 -2
- package/esm/presentation/widget/common/configuration/useMeasureValueFilterCompatibility.js +95 -22
- package/esm/presentation/widget/insight/ViewModeDashboardInsight/InsightDrillDialog/useExcludedDrillDefinitionFilters.js +2 -2
- package/esm/presentation/widget/insight/configuration/DrillFilters/TargetDashboardFiltersContext.d.ts +2 -1
- package/esm/presentation/widget/insight/configuration/DrillFilters/TargetDashboardFiltersContext.js +3 -1
- package/esm/presentation/widget/insight/configuration/DrillFilters/drillFiltersConfigUtils.d.ts +4 -1
- package/esm/presentation/widget/insight/configuration/DrillFilters/drillFiltersConfigUtils.js +15 -1
- package/esm/presentation/widget/insight/configuration/DrillFilters/messages.d.ts +6 -0
- package/esm/presentation/widget/insight/configuration/DrillFilters/messages.js +6 -0
- package/esm/presentation/widget/insight/configuration/DrillFilters/optionMappings/mapDashboardFilterToOption.d.ts +6 -2
- package/esm/presentation/widget/insight/configuration/DrillFilters/optionMappings/mapDashboardFilterToOption.js +18 -3
- package/esm/presentation/widget/insight/configuration/DrillFilters/optionMappings/mapSourceInsightFilterToOption.d.ts +4 -2
- package/esm/presentation/widget/insight/configuration/DrillFilters/optionMappings/mapSourceInsightFilterToOption.js +10 -6
- package/esm/presentation/widget/insight/configuration/DrillFilters/types.d.ts +2 -1
- package/esm/presentation/widget/insight/configuration/DrillFilters/useDrillFiltersConfig.js +78 -6
- package/esm/presentation/widget/insight/configuration/DrillFilters/useFetchTargetDashboardFilters.d.ts +2 -1
- package/esm/presentation/widget/insight/configuration/DrillFilters/useFetchTargetDashboardFilters.js +4 -1
- package/esm/sdk-ui-dashboard.d.ts +53 -6
- package/package.json +20 -20
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ICatalogAttribute, type ICatalogAttributeHierarchy, type ICatalogDateDataset, type ICatalogFact, type ICatalogMeasure, type IDateHierarchyTemplate, type IParameterMetadataObject } from "@gooddata/sdk-model";
|
|
1
|
+
import { type ICatalogAttribute, type ICatalogAttributeHierarchy, type ICatalogDateDataset, type ICatalogFact, type ICatalogMeasure, type IDateHierarchyTemplate, type IParameterMetadataObject, type IdentifierRef } from "@gooddata/sdk-model";
|
|
2
2
|
/**
|
|
3
3
|
* Status of catalog parameters loading.
|
|
4
4
|
*
|
|
@@ -14,6 +14,23 @@ export interface ICatalogParametersState {
|
|
|
14
14
|
status: CatalogParametersStatus;
|
|
15
15
|
parameters: IParameterMetadataObject[];
|
|
16
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Status of the dashboard-wide metric → parameter dependency map.
|
|
19
|
+
*
|
|
20
|
+
* @alpha
|
|
21
|
+
*/
|
|
22
|
+
export type CatalogMeasureParametersStatus = "uninitialized" | "loading" | "loaded" | "failed";
|
|
23
|
+
/**
|
|
24
|
+
* Maps each referenced metric (keyed by `objRefToString(metricRef)`) to the parameter refs the
|
|
25
|
+
* metric depends on, as reported by the workspace references service. Drives runtime parameter
|
|
26
|
+
* applicability for widget execution.
|
|
27
|
+
*
|
|
28
|
+
* @alpha
|
|
29
|
+
*/
|
|
30
|
+
export interface ICatalogMeasureParametersState {
|
|
31
|
+
status: CatalogMeasureParametersStatus;
|
|
32
|
+
byMetric: Record<string, IdentifierRef[]>;
|
|
33
|
+
}
|
|
17
34
|
/**
|
|
18
35
|
* @public
|
|
19
36
|
*/
|
|
@@ -32,5 +49,7 @@ export type CatalogState = {
|
|
|
32
49
|
dateHierarchyTemplates?: IDateHierarchyTemplate[];
|
|
33
50
|
/** @alpha */
|
|
34
51
|
parameters: ICatalogParametersState;
|
|
52
|
+
/** @alpha */
|
|
53
|
+
measureParameters: ICatalogMeasureParametersState;
|
|
35
54
|
};
|
|
36
55
|
export declare const catalogInitialState: CatalogState;
|
|
@@ -11,4 +11,5 @@ export declare const catalogActions: {
|
|
|
11
11
|
updateAttributeHierarchy: import("@reduxjs/toolkit").ActionCreatorWithPayload<import("@gooddata/sdk-model").ICatalogAttributeHierarchy, "catalog/updateAttributeHierarchy">;
|
|
12
12
|
deleteAttributeHierarchy: import("@reduxjs/toolkit").ActionCreatorWithPayload<import("@gooddata/sdk-model").ICatalogAttributeHierarchy, "catalog/deleteAttributeHierarchy">;
|
|
13
13
|
setCatalogParameters: import("@reduxjs/toolkit").ActionCreatorWithPayload<import("./catalogState.js").ICatalogParametersState, "catalog/setCatalogParameters">;
|
|
14
|
+
setCatalogMeasureParameters: import("@reduxjs/toolkit").ActionCreatorWithPayload<import("./catalogState.js").ICatalogMeasureParametersState, "catalog/setCatalogMeasureParameters">;
|
|
14
15
|
};
|
|
@@ -278,6 +278,12 @@ export declare const tabsActions: import("@reduxjs/toolkit").CaseReducerActions<
|
|
|
278
278
|
};
|
|
279
279
|
type: string;
|
|
280
280
|
}) => void | import("./tabsState.js").ITabsState | import("immer").WritableDraft<import("./tabsState.js").ITabsState>;
|
|
281
|
+
readonly removeIgnoredMeasureValueFilter: (state: import("immer").WritableDraft<import("./tabsState.js").ITabsState>, action: {
|
|
282
|
+
payload: {
|
|
283
|
+
measureRefs: import("@gooddata/sdk-model").ObjRef[];
|
|
284
|
+
};
|
|
285
|
+
type: string;
|
|
286
|
+
}) => void | import("./tabsState.js").ITabsState | import("immer").WritableDraft<import("./tabsState.js").ITabsState>;
|
|
281
287
|
readonly addSection: (state: import("immer").WritableDraft<import("./tabsState.js").ITabsState>, action: {
|
|
282
288
|
payload: import("../_infra/undoEnhancer.js").IUndoPayload<import("../../commands/base.js").IDashboardCommand> & {
|
|
283
289
|
section: import("../../types/layoutTypes.js").ExtendedDashboardLayoutSection;
|
|
@@ -129,6 +129,9 @@ type ReplaceWidgetDateDataset = {
|
|
|
129
129
|
type RemoveIgnoredDateFilter = {
|
|
130
130
|
dateDataSets: ObjRef[];
|
|
131
131
|
};
|
|
132
|
+
type RemoveIgnoredMeasureValueFilter = {
|
|
133
|
+
measureRefs: ObjRef[];
|
|
134
|
+
};
|
|
132
135
|
type ReplaceKpiWidgetMeasure = {
|
|
133
136
|
ref: ObjRef;
|
|
134
137
|
measureRef: ObjRef;
|
|
@@ -177,6 +180,7 @@ export declare const layoutReducers: {
|
|
|
177
180
|
updateWidgetIdentitiesForTab: LayoutReducer<UpdateWidgetIdentitiesForTabPayload>;
|
|
178
181
|
removeIgnoredAttributeFilter: LayoutReducer<RemoveIgnoredAttributeFilter>;
|
|
179
182
|
removeIgnoredDateFilter: LayoutReducer<RemoveIgnoredDateFilter>;
|
|
183
|
+
removeIgnoredMeasureValueFilter: LayoutReducer<RemoveIgnoredMeasureValueFilter>;
|
|
180
184
|
addSection: AdaptedLayoutReducer<import("../../_infra/undoEnhancer.js").IUndoPayload<import("../../../commands/base.js").IDashboardCommand> & AddSectionActionPayload>;
|
|
181
185
|
removeSection: AdaptedLayoutReducer<import("../../_infra/undoEnhancer.js").IUndoPayload<import("../../../commands/base.js").IDashboardCommand> & RemoveSectionActionPayload>;
|
|
182
186
|
moveSection: AdaptedLayoutReducer<import("../../_infra/undoEnhancer.js").IUndoPayload<import("../../../commands/base.js").IDashboardCommand> & MoveSectionActionPayload>;
|
|
@@ -523,6 +523,30 @@ const removeIgnoredDateFilter = (state, action) => {
|
|
|
523
523
|
invariant(layoutState?.layout);
|
|
524
524
|
removeIgnoredDateFilterFromLayout(layoutState.layout, action.payload.dateDataSets);
|
|
525
525
|
};
|
|
526
|
+
const removeIgnoredMeasureValueFilterFromLayout = (layout, measureRefs) => {
|
|
527
|
+
layout.sections.forEach((section) => {
|
|
528
|
+
section.items.forEach((item) => {
|
|
529
|
+
const widget = item.widget;
|
|
530
|
+
if (isInsightWidget(widget) || isKpiWidget(widget)) {
|
|
531
|
+
widget.ignoreDashboardFilters = widget.ignoreDashboardFilters.filter((filter) => {
|
|
532
|
+
if (isDashboardAttributeFilterReference(filter) ||
|
|
533
|
+
isDashboardDateFilterReference(filter)) {
|
|
534
|
+
return true;
|
|
535
|
+
}
|
|
536
|
+
return (measureRefs.find((removed) => areObjRefsEqual(removed, filter.measure)) === undefined);
|
|
537
|
+
});
|
|
538
|
+
}
|
|
539
|
+
else if (isDashboardLayout(widget)) {
|
|
540
|
+
removeIgnoredMeasureValueFilterFromLayout(widget, measureRefs);
|
|
541
|
+
}
|
|
542
|
+
});
|
|
543
|
+
});
|
|
544
|
+
};
|
|
545
|
+
const removeIgnoredMeasureValueFilter = (state, action) => {
|
|
546
|
+
const layoutState = getActiveTabLayout(state);
|
|
547
|
+
invariant(layoutState?.layout);
|
|
548
|
+
removeIgnoredMeasureValueFilterFromLayout(layoutState.layout, action.payload.measureRefs);
|
|
549
|
+
};
|
|
526
550
|
const replaceKpiWidgetMeasureCore = (state, action) => {
|
|
527
551
|
invariant(state.layout);
|
|
528
552
|
const { ref, measureRef } = action.payload;
|
|
@@ -628,6 +652,7 @@ export const layoutReducers = {
|
|
|
628
652
|
updateWidgetIdentitiesForTab,
|
|
629
653
|
removeIgnoredAttributeFilter,
|
|
630
654
|
removeIgnoredDateFilter,
|
|
655
|
+
removeIgnoredMeasureValueFilter,
|
|
631
656
|
addSection,
|
|
632
657
|
removeSection,
|
|
633
658
|
moveSection,
|
|
@@ -34,6 +34,15 @@ export declare const selectDashboardParameterEntryByRef: (ref: ObjRef) => Dashbo
|
|
|
34
34
|
* @alpha
|
|
35
35
|
*/
|
|
36
36
|
export declare const selectParameterRuntimeOverrideByRef: (ref: ObjRef) => DashboardSelector<number | undefined>;
|
|
37
|
+
/**
|
|
38
|
+
* Reset value for a parameter chip's dropdown, bound to the kit dropdown's `resetValue` prop.
|
|
39
|
+
*
|
|
40
|
+
* Returns `undefined` (Reset hidden) in edit mode when `parameter.value` is unset or already
|
|
41
|
+
* equals the workspace default — both would be unpin no-ops on next save.
|
|
42
|
+
*
|
|
43
|
+
* @alpha
|
|
44
|
+
*/
|
|
45
|
+
export declare const selectParameterResetValueByRef: (ref: ObjRef) => DashboardSelector<number | undefined>;
|
|
37
46
|
/**
|
|
38
47
|
* Computes the dashboard parameters keyed by tab `localIdentifier` in the shape that would be
|
|
39
48
|
* persisted on save right now.
|
|
@@ -60,12 +69,16 @@ export declare const selectIsParametersChanged: DashboardSelector<boolean>;
|
|
|
60
69
|
* Returns the parameter values to inject into the widget's `IExecutionConfig.parameterValues`.
|
|
61
70
|
*
|
|
62
71
|
* @remarks
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
72
|
+
* For each parameter referenced by the widget's metrics (via the dashboard-wide MAQL
|
|
73
|
+
* metric → parameter dependency map), the value is resolved in this order:
|
|
74
|
+
*
|
|
75
|
+
* 1. dashboard chip on the widget's tab with `runtimeOverride !== undefined`,
|
|
76
|
+
* 2. else `insight.parameters` entry for that ref (AD-authored per-insight override),
|
|
77
|
+
* 3. else nothing (backend uses workspace default).
|
|
78
|
+
*
|
|
79
|
+
* Parameters not referenced by the widget's metrics are excluded so that adding/removing
|
|
80
|
+
* unrelated parameters does not invalidate the widget's `defFingerprint`. Returns `[]` when
|
|
81
|
+
* `enableParameters` is off or while the dependency map has not been loaded.
|
|
69
82
|
*
|
|
70
83
|
* @alpha
|
|
71
84
|
*/
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
// (C) 2026 GoodData Corporation
|
|
2
2
|
import { createSelector } from "@reduxjs/toolkit";
|
|
3
3
|
import { isEqual } from "lodash-es";
|
|
4
|
-
import { areObjRefsEqual, insightParameters, isDashboardLayout, isInsightWidget, isNumberParameterDefinition, isVisualizationSwitcherWidget, objRefToString, } from "@gooddata/sdk-model";
|
|
4
|
+
import { areObjRefsEqual, insightMeasures, insightParameters, isDashboardLayout, isInsightWidget, isMeasureDefinition, isNumberParameterDefinition, isVisualizationSwitcherWidget, objRefToString, } from "@gooddata/sdk-model";
|
|
5
5
|
import { createMemoizedSelector } from "../../_infra/selectors.js";
|
|
6
|
-
import { selectCatalogParameters, selectCatalogParametersIsLoaded } from "../../catalog/catalogSelectors.js";
|
|
6
|
+
import { selectCatalogMeasureParameters, selectCatalogMeasureParametersStatus, selectCatalogParameterByRef, selectCatalogParameters, selectCatalogParametersIsLoaded, } from "../../catalog/catalogSelectors.js";
|
|
7
7
|
import { selectEnableParameters } from "../../config/configSelectors.js";
|
|
8
8
|
import { selectInsightsMap } from "../../insights/insightsSelectors.js";
|
|
9
|
+
import { selectIsInEditMode } from "../../renderMode/renderModeSelectors.js";
|
|
9
10
|
import { selectActiveTab, selectTabs } from "../tabsSelectors.js";
|
|
10
11
|
import { DEFAULT_TAB_ID } from "../tabsState.js";
|
|
11
12
|
import { parametersInitialState, pickTabParametersSource, } from "./parametersState.js";
|
|
12
13
|
const EMPTY_PARAMETERS = [];
|
|
14
|
+
const EMPTY_PARAMETER_VALUES = [];
|
|
13
15
|
const EMPTY_TABS = [];
|
|
14
16
|
const selectParametersState = createSelector(selectActiveTab, (activeTab) => activeTab?.parameters ?? parametersInitialState);
|
|
15
17
|
const selectPersistedParametersFromMeta = (state) => state.meta?.persistedDashboard?.parameters ?? EMPTY_PARAMETERS;
|
|
@@ -47,6 +49,31 @@ export const selectDashboardParameterEntryByRef = createMemoizedSelector((ref) =
|
|
|
47
49
|
* @alpha
|
|
48
50
|
*/
|
|
49
51
|
export const selectParameterRuntimeOverrideByRef = createMemoizedSelector((ref) => createSelector(selectDashboardParameterEntryByRef(ref), (entry) => entry?.runtimeOverride));
|
|
52
|
+
/**
|
|
53
|
+
* Reset value for a parameter chip's dropdown, bound to the kit dropdown's `resetValue` prop.
|
|
54
|
+
*
|
|
55
|
+
* Returns `undefined` (Reset hidden) in edit mode when `parameter.value` is unset or already
|
|
56
|
+
* equals the workspace default — both would be unpin no-ops on next save.
|
|
57
|
+
*
|
|
58
|
+
* @alpha
|
|
59
|
+
*/
|
|
60
|
+
export const selectParameterResetValueByRef = createMemoizedSelector((ref) => createSelector(selectDashboardParameterEntryByRef(ref), selectCatalogParameterByRef(ref), selectIsInEditMode, (entry, workspaceParameter, isInEditMode) => {
|
|
61
|
+
if (!entry) {
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
if (!workspaceParameter || !isNumberParameterDefinition(workspaceParameter.definition)) {
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
const workspaceDefault = workspaceParameter.definition.defaultValue;
|
|
68
|
+
const dashboardOverride = entry.parameter.value;
|
|
69
|
+
if (isInEditMode) {
|
|
70
|
+
if (dashboardOverride === undefined || dashboardOverride === workspaceDefault) {
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
return workspaceDefault;
|
|
74
|
+
}
|
|
75
|
+
return dashboardOverride ?? workspaceDefault;
|
|
76
|
+
}));
|
|
50
77
|
/**
|
|
51
78
|
* Computes the dashboard parameters keyed by tab `localIdentifier` in the shape that would be
|
|
52
79
|
* persisted on save right now.
|
|
@@ -124,35 +151,61 @@ export const selectIsParametersChanged = createSelector(selectSmartPersistedTabs
|
|
|
124
151
|
* Returns the parameter values to inject into the widget's `IExecutionConfig.parameterValues`.
|
|
125
152
|
*
|
|
126
153
|
* @remarks
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
154
|
+
* For each parameter referenced by the widget's metrics (via the dashboard-wide MAQL
|
|
155
|
+
* metric → parameter dependency map), the value is resolved in this order:
|
|
156
|
+
*
|
|
157
|
+
* 1. dashboard chip on the widget's tab with `runtimeOverride !== undefined`,
|
|
158
|
+
* 2. else `insight.parameters` entry for that ref (AD-authored per-insight override),
|
|
159
|
+
* 3. else nothing (backend uses workspace default).
|
|
160
|
+
*
|
|
161
|
+
* Parameters not referenced by the widget's metrics are excluded so that adding/removing
|
|
162
|
+
* unrelated parameters does not invalidate the widget's `defFingerprint`. Returns `[]` when
|
|
163
|
+
* `enableParameters` is off or while the dependency map has not been loaded.
|
|
133
164
|
*
|
|
134
165
|
* @alpha
|
|
135
166
|
*/
|
|
136
|
-
export const selectEffectiveParameterValuesForWidget = createMemoizedSelector((ref) => createSelector(selectParameterExecutionContextByWidgetRef(ref), selectInsightsMap, selectEnableParameters, (context, insights, isEnabled) => {
|
|
137
|
-
if (!isEnabled || !context) {
|
|
138
|
-
return
|
|
167
|
+
export const selectEffectiveParameterValuesForWidget = createMemoizedSelector((ref) => createSelector(selectParameterExecutionContextByWidgetRef(ref), selectInsightsMap, selectEnableParameters, selectCatalogMeasureParameters, selectCatalogMeasureParametersStatus, (context, insights, isEnabled, measureParameters, measureParametersStatus) => {
|
|
168
|
+
if (!isEnabled || !context || measureParametersStatus !== "loaded") {
|
|
169
|
+
return EMPTY_PARAMETER_VALUES;
|
|
139
170
|
}
|
|
140
171
|
const insight = insights.get(context.widget.insight);
|
|
141
172
|
if (!insight) {
|
|
142
|
-
return
|
|
173
|
+
return EMPTY_PARAMETER_VALUES;
|
|
174
|
+
}
|
|
175
|
+
const referencedRefs = new Set();
|
|
176
|
+
for (const measure of insightMeasures(insight)) {
|
|
177
|
+
const def = measure.measure.definition;
|
|
178
|
+
if (!isMeasureDefinition(def)) {
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
const parameterRefs = measureParameters[objRefToString(def.measureDefinition.item)] ?? [];
|
|
182
|
+
for (const parameterRef of parameterRefs) {
|
|
183
|
+
referencedRefs.add(objRefToString(parameterRef));
|
|
184
|
+
}
|
|
143
185
|
}
|
|
144
186
|
const entries = context.tab.parameters?.parameters ?? parametersInitialState.parameters;
|
|
145
|
-
const referencedRefs = new Set(insightParameters(insight).map((parameter) => objRefToString(parameter.ref)));
|
|
146
187
|
const result = [];
|
|
188
|
+
const seen = new Set();
|
|
147
189
|
for (const entry of entries) {
|
|
148
190
|
if (entry.runtimeOverride === undefined) {
|
|
149
191
|
continue;
|
|
150
192
|
}
|
|
151
|
-
|
|
152
|
-
|
|
193
|
+
const refKey = objRefToString(entry.parameter.ref);
|
|
194
|
+
if (!referencedRefs.has(refKey)) {
|
|
195
|
+
continue;
|
|
153
196
|
}
|
|
197
|
+
result.push({ ref: entry.parameter.ref, value: entry.runtimeOverride });
|
|
198
|
+
seen.add(refKey);
|
|
154
199
|
}
|
|
155
|
-
|
|
200
|
+
for (const insightParameter of insightParameters(insight)) {
|
|
201
|
+
const refKey = objRefToString(insightParameter.ref);
|
|
202
|
+
if (!referencedRefs.has(refKey) || seen.has(refKey)) {
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
result.push(insightParameter);
|
|
206
|
+
seen.add(refKey);
|
|
207
|
+
}
|
|
208
|
+
return result.length === 0 ? EMPTY_PARAMETER_VALUES : result;
|
|
156
209
|
}));
|
|
157
210
|
const selectParameterExecutionContextByWidgetRef = createMemoizedSelector((ref) => createSelector(selectTabs, (tabs) => findParameterExecutionContext(tabs, ref)));
|
|
158
211
|
function findParameterExecutionContext(tabs, ref) {
|
|
@@ -5,7 +5,7 @@ import { useDashboardDispatch, useDashboardSelector } from "../../../model/react
|
|
|
5
5
|
import { selectCatalogParameterByRef } from "../../../model/store/catalog/catalogSelectors.js";
|
|
6
6
|
import { selectIsInEditMode } from "../../../model/store/renderMode/renderModeSelectors.js";
|
|
7
7
|
import { tabsActions } from "../../../model/store/tabs/index.js";
|
|
8
|
-
import { selectParameterRuntimeOverrideByRef } from "../../../model/store/tabs/parameters/parametersSelectors.js";
|
|
8
|
+
import { selectParameterResetValueByRef, selectParameterRuntimeOverrideByRef, } from "../../../model/store/tabs/parameters/parametersSelectors.js";
|
|
9
9
|
import { DraggableChipSource } from "../../dragAndDrop/DraggableChipSource.js";
|
|
10
10
|
/**
|
|
11
11
|
* Renders a chip for a single dashboard parameter.
|
|
@@ -16,6 +16,7 @@ export function DashboardParameterFilter({ parameter }) {
|
|
|
16
16
|
const dispatch = useDashboardDispatch();
|
|
17
17
|
const workspaceParameter = useDashboardSelector(selectCatalogParameterByRef(parameter.ref));
|
|
18
18
|
const runtimeOverride = useDashboardSelector(selectParameterRuntimeOverrideByRef(parameter.ref));
|
|
19
|
+
const resetValue = useDashboardSelector(selectParameterResetValueByRef(parameter.ref));
|
|
19
20
|
const isInEditMode = useDashboardSelector(selectIsInEditMode);
|
|
20
21
|
if (parameter.mode === DashboardParameterModeValues.HIDDEN || runtimeOverride === undefined) {
|
|
21
22
|
return null;
|
|
@@ -29,7 +30,7 @@ export function DashboardParameterFilter({ parameter }) {
|
|
|
29
30
|
if (parameter.mode === DashboardParameterModeValues.READONLY) {
|
|
30
31
|
return (_jsx(DraggableChipSource, { dragItem: dragItem, canDrag: isInEditMode, children: _jsx(ParameterControlButton, { name: name, value: runtimeOverride, isActive: false, isDraggable: isInEditMode, "data-testid": `dashboard-parameter-${objRefToString(parameter.ref)}` }) }));
|
|
31
32
|
}
|
|
32
|
-
return (_jsx(DraggableChipSource, { dragItem: dragItem, canDrag: isInEditMode, children: _jsx(Dropdown, { renderButton: ({ isOpen, toggleDropdown }) => (_jsx(ParameterControlButton, { name: name, value: runtimeOverride, isActive: isOpen, isDraggable: isInEditMode, onClick: () => toggleDropdown(), "data-testid": `dashboard-parameter-${objRefToString(parameter.ref)}` })), renderBody: ({ closeDropdown }) => (_jsx(ParameterControlDropdown, { name: name, value: runtimeOverride, constraints: constraints, onApply: (value) => {
|
|
33
|
+
return (_jsx(DraggableChipSource, { dragItem: dragItem, canDrag: isInEditMode, children: _jsx(Dropdown, { renderButton: ({ isOpen, toggleDropdown }) => (_jsx(ParameterControlButton, { name: name, value: runtimeOverride, isActive: isOpen, isDraggable: isInEditMode, onClick: () => toggleDropdown(), "data-testid": `dashboard-parameter-${objRefToString(parameter.ref)}` })), renderBody: ({ closeDropdown }) => (_jsx(ParameterControlDropdown, { name: name, value: runtimeOverride, resetValue: resetValue, constraints: constraints, onApply: (value) => {
|
|
33
34
|
dispatch(tabsActions.setParameterRuntimeValue({ ref: parameter.ref, value }));
|
|
34
35
|
closeDropdown();
|
|
35
36
|
}, onCancel: closeDropdown })) }) }));
|
|
@@ -1931,6 +1931,14 @@ export declare const en_US: {
|
|
|
1931
1931
|
text: string;
|
|
1932
1932
|
crowdinContext: string;
|
|
1933
1933
|
};
|
|
1934
|
+
"configurationPanel.drillConfig.filterSelection.drillToDashboardDuplicateMetricFilter.tooltip": {
|
|
1935
|
+
text: string;
|
|
1936
|
+
crowdinContext: string;
|
|
1937
|
+
};
|
|
1938
|
+
"configurationPanel.drillConfig.filterSelection.drillToInsightMeasureValueFilter.tooltip": {
|
|
1939
|
+
text: string;
|
|
1940
|
+
crowdinContext: string;
|
|
1941
|
+
};
|
|
1934
1942
|
"configurationPanel.drillConfig.filterSelection.drillToDashboardRankingFilter.tooltip": {
|
|
1935
1943
|
text: string;
|
|
1936
1944
|
crowdinContext: string;
|
|
@@ -1933,6 +1933,14 @@ export const en_US = {
|
|
|
1933
1933
|
"text": "Metric filters cannot be passed to the target dashboard.",
|
|
1934
1934
|
"crowdinContext": "Tooltip shown for disabled metric value filters in drill-to-dashboard configuration because metric filters are not supported on the target dashboard"
|
|
1935
1935
|
},
|
|
1936
|
+
"configurationPanel.drillConfig.filterSelection.drillToDashboardDuplicateMetricFilter.tooltip": {
|
|
1937
|
+
"text": "Another filter for this metric is already being passed.",
|
|
1938
|
+
"crowdinContext": "Tooltip shown for a disabled dashboard or visualization metric filter in drill-to-dashboard configuration when another filter for the same metric is already selected"
|
|
1939
|
+
},
|
|
1940
|
+
"configurationPanel.drillConfig.filterSelection.drillToInsightMeasureValueFilter.tooltip": {
|
|
1941
|
+
"text": "Filter is not applicable to the drill destination.",
|
|
1942
|
+
"crowdinContext": "Tooltip shown for disabled measure value filters in drill-to-insight configuration because measure value filters are not supported on the target dashboard"
|
|
1943
|
+
},
|
|
1936
1944
|
"configurationPanel.drillConfig.filterSelection.drillToDashboardRankingFilter.tooltip": {
|
|
1937
1945
|
"text": "Top/bottom filters can’t be passed to the target dashboard.",
|
|
1938
1946
|
"crowdinContext": "Tooltip shown for disabled ranking filters in drill-to-dashboard configuration because top and bottom filters are not transferred to the target dashboard"
|
|
@@ -2,11 +2,12 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
// (C) 2022-2026 GoodData Corporation
|
|
3
3
|
import { useMemo } from "react";
|
|
4
4
|
import { invariant } from "ts-invariant";
|
|
5
|
-
import { dashboardAttributeFilterItemDisplayForm, dashboardAttributeFilterItemLocalIdentifier, dashboardAttributeFilterItemTitle, isAttributeMetadataObject, isDashboardAttributeFilterItem, isDashboardDateFilterWithDimension, isDashboardMeasureValueFilter, objRefToString, } from "@gooddata/sdk-model";
|
|
5
|
+
import { dashboardAttributeFilterItemDisplayForm, dashboardAttributeFilterItemLocalIdentifier, dashboardAttributeFilterItemTitle, isAttributeMetadataObject, isDashboardAttributeFilterItem, isDashboardDateFilterWithDimension, isDashboardMeasureValueFilter, isInsightWidget, objRefToString, } from "@gooddata/sdk-model";
|
|
6
6
|
import { useAttributeFilterDisplayFormFromMap } from "../../../../_staging/sharedHooks/useAttributeFilterDisplayFormFromMap.js";
|
|
7
7
|
import { useAttributes } from "../../../../_staging/sharedHooks/useAttributes.js";
|
|
8
8
|
import { useDashboardSelector } from "../../../../model/react/DashboardStoreProvider.js";
|
|
9
9
|
import { selectAllCatalogAttributesMap, selectAllCatalogDateDatasetsMap, selectAllCatalogMeasuresMap, } from "../../../../model/store/catalog/catalogSelectors.js";
|
|
10
|
+
import { selectInsightByRef } from "../../../../model/store/insights/insightsSelectors.js";
|
|
10
11
|
import { selectAttributeFilterConfigsDisplayAsLabelMap } from "../../../../model/store/tabs/attributeFilterConfigs/attributeFilterConfigsSelectors.js";
|
|
11
12
|
import { selectFilterContextFilters } from "../../../../model/store/tabs/filterContext/filterContextSelectors.js";
|
|
12
13
|
import { AttributeFilterConfigurationItem } from "./AttributeFilterConfigurationItem.js";
|
|
@@ -34,7 +35,8 @@ export function FilterConfiguration({ widget }) {
|
|
|
34
35
|
}, [attributeFilters]);
|
|
35
36
|
const { attributes, attributesLoading } = useAttributes(displayForms);
|
|
36
37
|
const measureValueFilters = useMemo(() => draggableFilters.filter(isDashboardMeasureValueFilter), [draggableFilters]);
|
|
37
|
-
const
|
|
38
|
+
const insight = useDashboardSelector(selectInsightByRef(isInsightWidget(widget) ? widget.insight : undefined));
|
|
39
|
+
const { isCompatible } = useMeasureValueFilterCompatibility(insight, measureValueFilters);
|
|
38
40
|
if (attributesLoading) {
|
|
39
41
|
return _jsx("span", { className: "gd-spinner small s-attribute-filter-configuration-loading" });
|
|
40
42
|
}
|
package/esm/presentation/widget/common/configuration/useMeasureValueFilterCompatibility.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import { type IDashboardMeasureValueFilter, type
|
|
2
|
-
|
|
1
|
+
import { type IDashboardMeasureValueFilter, type IInsight, type IInsightDefinition, type ObjRef } from "@gooddata/sdk-model";
|
|
2
|
+
import { useBackendStrict } from "@gooddata/sdk-ui";
|
|
3
|
+
export declare function useMeasureValueFilterCompatibility(insight: IInsight | undefined, filters: IDashboardMeasureValueFilter[]): {
|
|
3
4
|
status: "error" | "loading" | "pending" | "success";
|
|
4
5
|
isCompatible: (measureRef: ObjRef) => boolean;
|
|
6
|
+
compatibleMeasureRefs: ObjRef[] | undefined;
|
|
7
|
+
compatibleMeasureValueFilters: IDashboardMeasureValueFilter[];
|
|
5
8
|
};
|
|
9
|
+
export declare function loadCompatibleMeasureRefs(backend: ReturnType<typeof useBackendStrict>, workspace: string, insight: IInsightDefinition, measureRefs: ObjRef[]): Promise<ObjRef[]>;
|
|
@@ -1,40 +1,78 @@
|
|
|
1
1
|
// (C) 2026 GoodData Corporation
|
|
2
2
|
import { useMemo } from "react";
|
|
3
|
-
import { areObjRefsEqual, insightMeasures,
|
|
3
|
+
import { areObjRefsEqual, insightBuckets, insightFilters, insightMeasures, isObjRef, measureItem, objRefToString, } from "@gooddata/sdk-model";
|
|
4
4
|
import { useBackendStrict, useCancelablePromise, useWorkspaceStrict } from "@gooddata/sdk-ui";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
export function useMeasureValueFilterCompatibility(
|
|
5
|
+
const COMPATIBLE_MEASURE_REFS_CACHE_SIZE = 50;
|
|
6
|
+
const compatibleMeasureRefsCache = new Map();
|
|
7
|
+
const compatibleMeasureRefsPromises = new Map();
|
|
8
|
+
export function useMeasureValueFilterCompatibility(insight, filters) {
|
|
9
9
|
const backend = useBackendStrict();
|
|
10
10
|
const workspace = useWorkspaceStrict();
|
|
11
|
-
const insight = useDashboardSelector(selectInsightByRef(isInsightWidget(widget) ? widget.insight : undefined));
|
|
12
11
|
const measureRefs = useMemo(() => filters.map((filter) => filter.dashboardMeasureValueFilter.measure), [filters]);
|
|
13
12
|
const measureRefsDigest = useMemo(() => measureRefs.map(objRefToString).join("|"), [measureRefs]);
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
13
|
+
const insightIdentifier = getInsightIdentifier(insight);
|
|
14
|
+
const cacheKey = useMemo(() => insight && measureRefs.length
|
|
15
|
+
? getCompatibleMeasureRefsCacheKey(workspace, insight, measureRefsDigest)
|
|
16
|
+
: undefined, [insight, measureRefs.length, measureRefsDigest, workspace]);
|
|
17
|
+
const cachedCompatibleMeasureRefs = useMemo(() => {
|
|
18
|
+
if (!measureRefs.length) {
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
if (!insight) {
|
|
22
|
+
return measureRefs;
|
|
23
|
+
}
|
|
24
|
+
return cacheKey ? getCachedValue(compatibleMeasureRefsCache, cacheKey) : undefined;
|
|
25
|
+
}, [cacheKey, insight, measureRefs]);
|
|
26
|
+
const insightToLoadCompatibleMeasureRefsFor = cachedCompatibleMeasureRefs ? undefined : insight;
|
|
27
|
+
const { result: loadedCompatibleMeasureRefs, status } = useCancelablePromise({
|
|
28
|
+
promise: insightToLoadCompatibleMeasureRefsFor
|
|
29
|
+
? async () => loadCompatibleMeasureRefs(backend, workspace, insightToLoadCompatibleMeasureRefsFor, measureRefs)
|
|
30
|
+
: undefined,
|
|
24
31
|
}, [
|
|
25
32
|
backend,
|
|
26
33
|
workspace,
|
|
27
34
|
measureRefsDigest,
|
|
28
|
-
|
|
29
|
-
|
|
35
|
+
insightIdentifier,
|
|
36
|
+
cachedCompatibleMeasureRefs,
|
|
37
|
+
insightToLoadCompatibleMeasureRefsFor,
|
|
30
38
|
]);
|
|
39
|
+
const compatibleMeasureRefs = cachedCompatibleMeasureRefs ?? loadedCompatibleMeasureRefs;
|
|
40
|
+
const compatibleMeasureValueFilters = useMemo(() => compatibleMeasureRefs
|
|
41
|
+
? filters.filter((filter) => isMeasureRefCompatible(filter.dashboardMeasureValueFilter.measure, compatibleMeasureRefs))
|
|
42
|
+
: filters, [compatibleMeasureRefs, filters]);
|
|
31
43
|
return {
|
|
32
|
-
status,
|
|
33
|
-
isCompatible: (measureRef) =>
|
|
34
|
-
|
|
44
|
+
status: cachedCompatibleMeasureRefs ? "success" : status,
|
|
45
|
+
isCompatible: (measureRef) => isMeasureRefCompatible(measureRef, compatibleMeasureRefs),
|
|
46
|
+
compatibleMeasureRefs,
|
|
47
|
+
compatibleMeasureValueFilters,
|
|
35
48
|
};
|
|
36
49
|
}
|
|
37
|
-
|
|
50
|
+
function isMeasureRefCompatible(measureRef, compatibleMeasureRefs) {
|
|
51
|
+
return (!compatibleMeasureRefs ||
|
|
52
|
+
compatibleMeasureRefs.some((compatibleMeasureRef) => areObjRefsEqual(compatibleMeasureRef, measureRef)));
|
|
53
|
+
}
|
|
54
|
+
export async function loadCompatibleMeasureRefs(backend, workspace, insight, measureRefs) {
|
|
55
|
+
const cacheKey = getCompatibleMeasureRefsCacheKey(workspace, insight, measureRefs.map(objRefToString).join("|"));
|
|
56
|
+
const cachedCompatibleMeasureRefs = getCachedValue(compatibleMeasureRefsCache, cacheKey);
|
|
57
|
+
if (cachedCompatibleMeasureRefs) {
|
|
58
|
+
return cachedCompatibleMeasureRefs;
|
|
59
|
+
}
|
|
60
|
+
const pendingCompatibleMeasureRefs = getCachedValue(compatibleMeasureRefsPromises, cacheKey);
|
|
61
|
+
if (pendingCompatibleMeasureRefs) {
|
|
62
|
+
return pendingCompatibleMeasureRefs;
|
|
63
|
+
}
|
|
64
|
+
const compatibleMeasureRefsPromise = loadCompatibleMeasureRefsFromBackend(backend, workspace, insight, measureRefs)
|
|
65
|
+
.then((compatibleMeasureRefs) => {
|
|
66
|
+
setCachedValue(compatibleMeasureRefsCache, cacheKey, compatibleMeasureRefs);
|
|
67
|
+
return compatibleMeasureRefs;
|
|
68
|
+
})
|
|
69
|
+
.finally(() => {
|
|
70
|
+
compatibleMeasureRefsPromises.delete(cacheKey);
|
|
71
|
+
});
|
|
72
|
+
setCachedValue(compatibleMeasureRefsPromises, cacheKey, compatibleMeasureRefsPromise);
|
|
73
|
+
return compatibleMeasureRefsPromise;
|
|
74
|
+
}
|
|
75
|
+
async function loadCompatibleMeasureRefsFromBackend(backend, workspace, insight, measureRefs) {
|
|
38
76
|
const catalog = await backend
|
|
39
77
|
.workspace(workspace)
|
|
40
78
|
.catalog()
|
|
@@ -49,3 +87,38 @@ async function loadCompatibleMeasureRefs(backend, workspace, insight, measureRef
|
|
|
49
87
|
const validMeasureRefs = [...availableMeasureRefs, ...insightMeasureRefs];
|
|
50
88
|
return measureRefs.filter((measureRef) => validMeasureRefs.some((validMeasureRef) => areObjRefsEqual(validMeasureRef, measureRef)));
|
|
51
89
|
}
|
|
90
|
+
function getCompatibleMeasureRefsCacheKey(workspace, insight, measureRefsDigest) {
|
|
91
|
+
return JSON.stringify([
|
|
92
|
+
workspace,
|
|
93
|
+
getInsightIdentifier(insight),
|
|
94
|
+
insightBuckets(insight),
|
|
95
|
+
insightFilters(insight),
|
|
96
|
+
measureRefsDigest,
|
|
97
|
+
]);
|
|
98
|
+
}
|
|
99
|
+
function getInsightIdentifier(insight) {
|
|
100
|
+
if (!insight) {
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
if ("identifier" in insight.insight && typeof insight.insight.identifier === "string") {
|
|
104
|
+
return insight.insight.identifier;
|
|
105
|
+
}
|
|
106
|
+
if ("ref" in insight.insight && isObjRef(insight.insight.ref)) {
|
|
107
|
+
return objRefToString(insight.insight.ref);
|
|
108
|
+
}
|
|
109
|
+
return undefined;
|
|
110
|
+
}
|
|
111
|
+
function getCachedValue(cache, key) {
|
|
112
|
+
return cache.get(key);
|
|
113
|
+
}
|
|
114
|
+
function setCachedValue(cache, key, value) {
|
|
115
|
+
cache.delete(key);
|
|
116
|
+
cache.set(key, value);
|
|
117
|
+
while (cache.size > COMPATIBLE_MEASURE_REFS_CACHE_SIZE) {
|
|
118
|
+
const oldestKey = cache.keys().next().value;
|
|
119
|
+
if (oldestKey === undefined) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
cache.delete(oldestKey);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// (C) 2020-2026 GoodData Corporation
|
|
2
2
|
import { useMemo } from "react";
|
|
3
|
-
import { filterLocalIdentifier, isAttributeFilter, isDateFilter, isDrillToInsight, } from "@gooddata/sdk-model";
|
|
3
|
+
import { filterLocalIdentifier, isAttributeFilter, isDateFilter, isDrillToInsight, isMeasureValueFilter, } from "@gooddata/sdk-model";
|
|
4
4
|
export function useExcludedDrillDefinitionFilters(filtersForInsight, drillStep) {
|
|
5
5
|
const ignoredDashboardFilterIds = useMemo(() => {
|
|
6
6
|
if (!drillStep || !isDrillToInsight(drillStep.drillDefinition)) {
|
|
@@ -9,7 +9,7 @@ export function useExcludedDrillDefinitionFilters(filtersForInsight, drillStep)
|
|
|
9
9
|
return new Set(drillStep.drillDefinition.ignoredDashboardFilters ?? []);
|
|
10
10
|
}, [drillStep]);
|
|
11
11
|
return useMemo(() => filtersForInsight?.filter((filter) => {
|
|
12
|
-
if (!isAttributeFilter(filter) && !isDateFilter(filter)) {
|
|
12
|
+
if (!isAttributeFilter(filter) && !isDateFilter(filter) && !isMeasureValueFilter(filter)) {
|
|
13
13
|
return true;
|
|
14
14
|
}
|
|
15
15
|
const localIdentifier = filterLocalIdentifier(filter);
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { type ReactNode } from "react";
|
|
2
|
-
import { type DashboardTextAttributeFilter, type FilterContextItem, type IDashboardAttributeFilter, type IDashboardAttributeFilterConfig, type ObjRef } from "@gooddata/sdk-model";
|
|
2
|
+
import { type DashboardTextAttributeFilter, type FilterContextItem, type IDashboardAttributeFilter, type IDashboardAttributeFilterConfig, type IDashboardMeasureValueFilter, type ObjRef } from "@gooddata/sdk-model";
|
|
3
3
|
type TTargetDashboardFiltersCacheStatus = "loading" | "success" | "error";
|
|
4
4
|
interface ITargetDashboardFiltersCacheEntry {
|
|
5
5
|
status: TTargetDashboardFiltersCacheStatus;
|
|
6
6
|
targetDashboardFilters: FilterContextItem[];
|
|
7
7
|
targetDashboardAttributeFilters: IDashboardAttributeFilter[];
|
|
8
8
|
targetDashboardTextAttributeFilters: DashboardTextAttributeFilter[];
|
|
9
|
+
targetDashboardMeasureValueFilters: IDashboardMeasureValueFilter[];
|
|
9
10
|
targetDashboardAttributeFilterConfigs: IDashboardAttributeFilterConfig[];
|
|
10
11
|
}
|
|
11
12
|
interface ITargetDashboardFiltersContextValue {
|
package/esm/presentation/widget/insight/configuration/DrillFilters/TargetDashboardFiltersContext.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
// (C) 2020-2026 GoodData Corporation
|
|
3
3
|
import { createContext, useCallback, useContext, useMemo, useRef, useState } from "react";
|
|
4
|
-
import { isDashboardAttributeFilter, isDashboardTextAttributeFilter, } from "@gooddata/sdk-model";
|
|
4
|
+
import { isDashboardAttributeFilter, isDashboardMeasureValueFilter, isDashboardTextAttributeFilter, } from "@gooddata/sdk-model";
|
|
5
5
|
import { useBackendStrict, useWorkspaceStrict } from "@gooddata/sdk-ui";
|
|
6
6
|
import { dashboardFilterContextDefinition } from "../../../../../_staging/dashboard/dashboardFilterContext.js";
|
|
7
7
|
import { defaultDateFilterConfig } from "../../../../../_staging/dateFilterConfig/defaultConfig.js";
|
|
@@ -24,6 +24,7 @@ function getTargetDashboardFilterData(dashboard, targetTabLocalIdentifier) {
|
|
|
24
24
|
targetDashboardFilters,
|
|
25
25
|
targetDashboardAttributeFilters: targetDashboardFilters.filter(isDashboardAttributeFilter),
|
|
26
26
|
targetDashboardTextAttributeFilters: targetDashboardFilters.filter(isDashboardTextAttributeFilter),
|
|
27
|
+
targetDashboardMeasureValueFilters: targetDashboardFilters.filter(isDashboardMeasureValueFilter),
|
|
27
28
|
targetDashboardAttributeFilterConfigs: targetDashboard.attributeFilterConfigs ?? [],
|
|
28
29
|
};
|
|
29
30
|
}
|
|
@@ -33,6 +34,7 @@ function createEmptyCacheEntry(status) {
|
|
|
33
34
|
targetDashboardFilters: [],
|
|
34
35
|
targetDashboardAttributeFilters: [],
|
|
35
36
|
targetDashboardTextAttributeFilters: [],
|
|
37
|
+
targetDashboardMeasureValueFilters: [],
|
|
36
38
|
targetDashboardAttributeFilterConfigs: [],
|
|
37
39
|
};
|
|
38
40
|
}
|
package/esm/presentation/widget/insight/configuration/DrillFilters/drillFiltersConfigUtils.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type IntlShape } from "react-intl";
|
|
2
|
-
import { type DashboardTextAttributeFilter, type FilterContextItem, type IAttributeDisplayFormMetadataObject, type ICatalogMeasure, type IDashboardAttributeFilter, type IDashboardAttributeFilterConfig, type IDashboardDateFilterConfigItem, type IMeasure, type ObjRef, type ObjRefInScope, type SourceInsightFilterObjRef } from "@gooddata/sdk-model";
|
|
2
|
+
import { type DashboardTextAttributeFilter, type FilterContextItem, type IAttributeDisplayFormMetadataObject, type ICatalogMeasure, type IDashboardAttributeFilter, type IDashboardAttributeFilterConfig, type IDashboardDateFilterConfigItem, type IDashboardMeasureValueFilter, type IMeasure, type ObjRef, type ObjRefInScope, type SourceInsightFilterObjRef } from "@gooddata/sdk-model";
|
|
3
3
|
import { type ObjRefMap } from "../../../../../_staging/metadata/objRefMap.js";
|
|
4
4
|
import { type IDrillFiltersConfigOption } from "./types.js";
|
|
5
5
|
export declare function getMeasureTitleFromSourceInsightMeasures(sourceInsightMeasures: IMeasure[], measureRef: ObjRefInScope | undefined, allCatalogMeasures: ICatalogMeasure[], intl: IntlShape): string | undefined;
|
|
@@ -23,9 +23,12 @@ export declare function getDashboardDateFilterCustomTitle({ datasetRef, allDateF
|
|
|
23
23
|
datasetRef: ObjRefInScope;
|
|
24
24
|
allDateFilterConfigsOverrides: IDashboardDateFilterConfigItem[];
|
|
25
25
|
}): string | undefined;
|
|
26
|
+
export declare function getCatalogMeasureTitle(measureRef: ObjRef, allCatalogMeasures: ICatalogMeasure[]): string;
|
|
26
27
|
export declare function hasMatchingTargetDashboardAttributeFilterDisplayForm(displayFormRef: ObjRef, targetDashboardAttributeFilters: IDashboardAttributeFilter[]): boolean;
|
|
27
28
|
export declare function hasMatchingTargetDashboardAttributeFilter(dashboardFilter: IDashboardAttributeFilter, sourceDashboardAttributeFilterConfigs: IDashboardAttributeFilterConfig[], targetDashboardAttributeFilters: IDashboardAttributeFilter[], targetDashboardAttributeFilterConfigs: IDashboardAttributeFilterConfig[], allCatalogDisplayFormsMap: ObjRefMap<IAttributeDisplayFormMetadataObject>): boolean;
|
|
28
29
|
export declare function hasMatchingTargetDashboardDateFilter(datasetRef: ObjRef, targetDashboardFilters: FilterContextItem[]): boolean;
|
|
30
|
+
export declare function hasMatchingTargetDashboardMeasureValueFilter(measureRef: ObjRefInScope | undefined, targetDashboardFilters: FilterContextItem[]): boolean;
|
|
31
|
+
export declare function hasCompatibleTargetInsightMeasureValueFilter(measureRef: ObjRef, targetInsightCompatibleMeasureValueFilters: IDashboardMeasureValueFilter[]): boolean;
|
|
29
32
|
export declare function isDateIntersectionAttribute(displayFormRef: ObjRef, allCatalogDateAttributeDisplayForms: Array<{
|
|
30
33
|
ref: ObjRef;
|
|
31
34
|
title?: string;
|