@gooddata/sdk-ui-dashboard 11.36.0-alpha.3 → 11.36.0-alpha.7
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/NOTICE +74 -162
- package/esm/__version.d.ts +1 -1
- package/esm/__version.js +1 -1
- package/esm/index.d.ts +5 -13
- package/esm/index.js +2 -10
- package/esm/internal.d.ts +1 -1
- package/esm/model/commandHandlers/dashboard/common/filterViews.js +24 -1
- package/esm/model/commandHandlers/dashboard/common/parameterHydration.d.ts +7 -1
- package/esm/model/commandHandlers/dashboard/common/parameterHydration.js +16 -2
- package/esm/model/commandHandlers/dashboard/common/stateInitializers.js +4 -2
- package/esm/model/commandHandlers/drill/resolveDrillToCustomUrl.d.ts +7 -1
- package/esm/model/commandHandlers/drill/resolveDrillToCustomUrl.js +80 -4
- package/esm/model/commandHandlers/filterContext/filterViewHandler.js +10 -0
- package/esm/model/commandHandlers/filterContext/filterViewParameters.d.ts +7 -0
- package/esm/model/commandHandlers/filterContext/filterViewParameters.js +11 -0
- package/esm/model/store/config/configSelectors.d.ts +0 -12
- package/esm/model/store/config/configSelectors.js +2 -18
- package/esm/model/store/tabs/index.d.ts +4 -0
- package/esm/model/store/tabs/parameters/parametersReducers.d.ts +11 -1
- package/esm/model/store/tabs/parameters/parametersReducers.js +16 -8
- package/esm/model/store/tabs/parameters/parametersSelectors.d.ts +7 -0
- package/esm/model/store/tabs/parameters/parametersSelectors.js +17 -0
- package/esm/model/store/widgetDrills/widgetDrillSelectors.js +10 -18
- package/esm/model/types/commonTypes.d.ts +11 -2
- package/esm/model/utils/measureValueFilterUtils.d.ts +14 -0
- package/esm/model/utils/measureValueFilterUtils.js +21 -0
- package/esm/presentation/alerting/DefaultAlertingDialog/{DefaultAlertingDialogNew.d.ts → DefaultAlertingDialog.d.ts} +1 -1
- package/esm/presentation/alerting/DefaultAlertingDialog/{DefaultAlertingDialogNew.js → DefaultAlertingDialog.js} +6 -12
- package/esm/presentation/alerting/DefaultAlertingDialog/components/AlertAttributeSelect.js +43 -9
- package/esm/presentation/alerting/DefaultAlertingDialog/hooks/useSaveAlertToBackend.js +13 -25
- package/esm/presentation/alerting/DefaultAlertingDialog/utils/items.js +5 -2
- package/esm/presentation/alerting/types.d.ts +1 -72
- package/esm/presentation/automationFilters/hooks/useValidateExistingAutomationFilters.d.ts +1 -2
- package/esm/presentation/automationFilters/hooks/useValidateExistingAutomationFilters.js +5 -5
- package/esm/presentation/dashboard/DashboardHeader/AlertingDialogProvider.js +1 -8
- package/esm/presentation/dashboard/DashboardHeader/ScheduledEmailDialogProvider.js +17 -8
- package/esm/presentation/dashboard/DashboardHeader/ShareDialogDashboardHeader.js +5 -2
- package/esm/presentation/dashboard/components/DashboardRenderer.js +2 -2
- package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditor.js +97 -13
- package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParameters.d.ts +1 -1
- package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParameters.js +3 -3
- package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParametersSections/DashboardParametersSection.d.ts +3 -2
- package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParametersSections/DashboardParametersSection.js +17 -4
- package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParametersSections/InsightParametersSection.d.ts +4 -2
- package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParametersSections/InsightParametersSection.js +37 -4
- package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParametersSections/Parameter.d.ts +4 -3
- package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParametersSections/Parameter.js +3 -4
- package/esm/presentation/drill/DrillSelect/DrillSelectDropdown.js +1 -3
- package/esm/presentation/drill/hooks/useDrillSelectDropdownMenuItems.js +1 -5
- package/esm/presentation/export/DefaultDashboardExportVariables.js +5 -2
- package/esm/presentation/export/hooks/useDashboardRelatedFilters.d.ts +2 -1
- package/esm/presentation/export/hooks/useDashboardRelatedFilters.js +9 -0
- package/esm/presentation/export/types.d.ts +2 -1
- package/esm/presentation/export/types.js +1 -1
- package/esm/presentation/export/useExportData.js +4 -0
- package/esm/presentation/filterBar/attributeFilter/DefaultDashboardAttributeFilter.js +4 -1
- package/esm/presentation/filterBar/filterBar/DefaultDashboardFilterGroup.js +4 -1
- package/esm/presentation/localization/bundles/de-DE.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/de-DE.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/en-AU.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/en-AU.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/en-GB.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/en-GB.localization-bundle.js +4 -10
- package/esm/presentation/localization/bundles/en-US.localization-bundle.d.ts +4 -36
- package/esm/presentation/localization/bundles/en-US.localization-bundle.js +4 -36
- package/esm/presentation/localization/bundles/es-419.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/es-419.localization-bundle.js +4 -10
- package/esm/presentation/localization/bundles/es-ES.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/es-ES.localization-bundle.js +4 -10
- package/esm/presentation/localization/bundles/fi-FI.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/fi-FI.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/fr-CA.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/fr-CA.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/fr-FR.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/fr-FR.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/id-ID.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/id-ID.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/it-IT.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/it-IT.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/ja-JP.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/ja-JP.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/ko-KR.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/ko-KR.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/nl-NL.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/nl-NL.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/pl-PL.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/pl-PL.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/pt-BR.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/pt-BR.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/pt-PT.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/pt-PT.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/ru-RU.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/ru-RU.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/sl-SI.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/sl-SI.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/th-TH.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/th-TH.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/tr-TR.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/tr-TR.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/uk-UA.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/uk-UA.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/vi-VN.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/vi-VN.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/zh-HK.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/zh-HK.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.js +3 -9
- package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.d.ts +3 -9
- package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.js +3 -9
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/DefaultScheduledEmailDialog.js +26 -59
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/hooks/useEditScheduledEmail.d.ts +2 -6
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/hooks/useEditScheduledEmail.js +22 -104
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/hooks/useSaveScheduledEmailToBackend.js +12 -33
- package/esm/presentation/scheduledEmail/hooks/useWidgetAutomationFilters.d.ts +3 -0
- package/esm/presentation/scheduledEmail/hooks/useWidgetAutomationFilters.js +46 -0
- package/esm/presentation/scheduledEmail/types.d.ts +1 -7
- package/esm/presentation/scheduledEmail/utils/filters.d.ts +2 -0
- package/esm/presentation/scheduledEmail/utils/filters.js +5 -0
- package/esm/presentation/shareDialog/DefaultShareDialog.d.ts +1 -1
- package/esm/presentation/shareDialog/DefaultShareDialog.js +2 -2
- package/esm/presentation/shareDialog/types.d.ts +5 -1
- package/esm/presentation/widget/insight/configuration/DrillTargets/useInvalidFilteringParametersIdentifiers.d.ts +2 -2
- package/esm/presentation/widget/insight/configuration/DrillTargets/useInvalidFilteringParametersIdentifiers.js +36 -5
- package/esm/presentation/widget/insight/configuration/InsightAlertConfig/EditAlert.js +2 -2
- package/esm/presentation/widget/insight/configuration/InsightAlertConfig/hooks/useInsightWidgetAlerting.js +3 -6
- package/esm/presentation/widget/insight/configuration/InsightAlerts.js +1 -9
- package/esm/presentation/widget/insight/configuration/InsightDrillConfigPanel/useInsightDrillConfigPanel.js +4 -10
- package/esm/sdk-ui-dashboard.d.ts +31 -249
- package/package.json +20 -20
- package/esm/model/react/filtering/shared.d.ts +0 -6
- package/esm/model/react/filtering/shared.js +0 -38
- package/esm/model/react/filtering/useAutomationAvailableDashboardFilters.d.ts +0 -13
- package/esm/model/react/filtering/useAutomationAvailableDashboardFilters.js +0 -54
- package/esm/model/react/filtering/useDashboardScheduledExportFilters.d.ts +0 -19
- package/esm/model/react/filtering/useDashboardScheduledExportFilters.js +0 -18
- package/esm/model/react/filtering/useScheduledExportFilters.d.ts +0 -26
- package/esm/model/react/filtering/useScheduledExportFilters.js +0 -23
- package/esm/model/react/filtering/useWidgetAlertFilters.d.ts +0 -33
- package/esm/model/react/filtering/useWidgetAlertFilters.js +0 -48
- package/esm/model/react/filtering/useWidgetScheduledExportFilters.d.ts +0 -33
- package/esm/model/react/filtering/useWidgetScheduledExportFilters.js +0 -48
- package/esm/model/react/useDashboardAlerting/useEnableAutomationFilterContext.d.ts +0 -4
- package/esm/model/react/useDashboardAlerting/useEnableAutomationFilterContext.js +0 -20
- package/esm/model/react/useDashboardAlertsOld.d.ts +0 -32
- package/esm/model/react/useDashboardAlertsOld.js +0 -141
- package/esm/presentation/alerting/DefaultAlertingDialog/DefaultAlertingDialogOld.d.ts +0 -5
- package/esm/presentation/alerting/DefaultAlertingDialog/DefaultAlertingDialogOld.js +0 -36
- package/esm/presentation/alerting/DefaultAlertingDialog/components/AlertAttributeSelectOld.d.ts +0 -17
- package/esm/presentation/alerting/DefaultAlertingDialog/components/AlertAttributeSelectOld.js +0 -103
- package/esm/presentation/alerting/DefaultAlertingManagementDialog/DefaultAlertingManagementDialogOld.d.ts +0 -5
- package/esm/presentation/alerting/DefaultAlertingManagementDialog/DefaultAlertingManagementDialogOld.js +0 -53
- package/esm/presentation/alerting/DefaultAlertingManagementDialog/components/AlertOld.d.ts +0 -9
- package/esm/presentation/alerting/DefaultAlertingManagementDialog/components/AlertOld.js +0 -84
- package/esm/presentation/alerting/DefaultAlertingManagementDialog/components/AlertsListOld.d.ts +0 -11
- package/esm/presentation/alerting/DefaultAlertingManagementDialog/components/AlertsListOld.js +0 -16
- package/esm/presentation/dashboard/DashboardHeader/AlertingDialogProviderOld.d.ts +0 -1
- package/esm/presentation/dashboard/DashboardHeader/AlertingDialogProviderOld.js +0 -12
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentFilters.d.ts +0 -29
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentFilters.js +0 -61
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentFiltersList.d.ts +0 -6
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentFiltersList.js +0 -12
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentItems.d.ts +0 -17
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentItems.js +0 -68
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentsWrapper.d.ts +0 -4
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentsWrapper.js +0 -6
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/DashboardAttachments.d.ts +0 -15
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/DashboardAttachments.js +0 -42
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/WidgetAttachments.d.ts +0 -18
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/WidgetAttachments.js +0 -25
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/types.d.ts +0 -2
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/types.js +0 -2
- package/esm/presentation/widget/insight/configuration/InsightAlertsOld.d.ts +0 -2
- package/esm/presentation/widget/insight/configuration/InsightAlertsOld.js +0 -43
|
@@ -306,15 +306,17 @@ export function applyDefaultFilterView(dashboard, filterViews, settings) {
|
|
|
306
306
|
// Use tab-specific default, or fall back to legacy global default only for the first tab
|
|
307
307
|
const isFirstTab = index === 0;
|
|
308
308
|
const effectiveDefaultView = tabDefaultView ?? (isFirstTab ? legacyDefaultView : undefined);
|
|
309
|
+
const parameters = applyFilterViewParameterValues(tab.parameters, effectiveDefaultView?.parameters);
|
|
309
310
|
if (effectiveDefaultView && tab.filterContext && isFilterContext(tab.filterContext)) {
|
|
310
311
|
const { filterContext: updatedFilterContext, configUpdates } = changeFilterContextSelection(tab.filterContext, effectiveDefaultView.filterContext.filters, tab.attributeFilterConfigs);
|
|
311
312
|
return {
|
|
312
313
|
...tab,
|
|
314
|
+
...(parameters === undefined ? {} : { parameters }),
|
|
313
315
|
filterContext: updatedFilterContext,
|
|
314
316
|
attributeFilterConfigs: applyConfigUpdates(tab.attributeFilterConfigs, configUpdates),
|
|
315
317
|
};
|
|
316
318
|
}
|
|
317
|
-
return tab;
|
|
319
|
+
return parameters === undefined ? tab : { ...tab, parameters };
|
|
318
320
|
});
|
|
319
321
|
return {
|
|
320
322
|
...dashboard,
|
|
@@ -329,7 +331,28 @@ export function applyDefaultFilterView(dashboard, filterViews, settings) {
|
|
|
329
331
|
...dashboard,
|
|
330
332
|
filterContext: updatedFilterContext,
|
|
331
333
|
attributeFilterConfigs: applyConfigUpdates(dashboard.attributeFilterConfigs, configUpdates),
|
|
334
|
+
parameters: applyFilterViewParameterValues(dashboard.parameters, defaultFilterView.parameters),
|
|
332
335
|
};
|
|
333
336
|
}
|
|
334
337
|
return dashboard;
|
|
335
338
|
}
|
|
339
|
+
/**
|
|
340
|
+
* Default filter views are applied before tab parameters are hydrated into runtime state.
|
|
341
|
+
* Copy captured filter view values into matching dashboard parameters so hydration initializes chips
|
|
342
|
+
* from the default view.
|
|
343
|
+
*/
|
|
344
|
+
function applyFilterViewParameterValues(dashboardParameters, filterViewParameters) {
|
|
345
|
+
if (!dashboardParameters || !filterViewParameters || filterViewParameters.length === 0) {
|
|
346
|
+
return dashboardParameters;
|
|
347
|
+
}
|
|
348
|
+
return dashboardParameters.map((parameter) => {
|
|
349
|
+
const filterViewParameter = filterViewParameters.find((item) => areObjRefsEqual(item.ref, parameter.ref));
|
|
350
|
+
if (!filterViewParameter) {
|
|
351
|
+
return parameter;
|
|
352
|
+
}
|
|
353
|
+
if (filterViewParameter.value === undefined) {
|
|
354
|
+
return omit(parameter, ["value"]);
|
|
355
|
+
}
|
|
356
|
+
return { ...parameter, value: filterViewParameter.value };
|
|
357
|
+
});
|
|
358
|
+
}
|
|
@@ -17,5 +17,11 @@ export declare function hydrateParameterEntries(dashboardParameters: IDashboardP
|
|
|
17
17
|
*
|
|
18
18
|
* For legacy single-tab dashboards (no `tabs[]`), a synthetic tab with `DEFAULT_TAB_ID` is used
|
|
19
19
|
* so the V1 root-level `parameters` migrate transparently.
|
|
20
|
+
*
|
|
21
|
+
* `activeTabOverride` patches `runtimeOverride` on its named tab for refs that match an entry;
|
|
22
|
+
* non-matching refs are silently ignored (see `overrideDefaultParameters` on DashboardConfig).
|
|
20
23
|
*/
|
|
21
|
-
export declare function distributeParametersToTabs(tabs: IDashboardTab[] | undefined, rootParameters: IDashboardParameter[] | undefined, workspaceParameters: IParameterMetadataObject[]
|
|
24
|
+
export declare function distributeParametersToTabs(tabs: IDashboardTab[] | undefined, rootParameters: IDashboardParameter[] | undefined, workspaceParameters: IParameterMetadataObject[], activeTabOverride?: {
|
|
25
|
+
tabId: string;
|
|
26
|
+
overrides: IDashboardParameter[];
|
|
27
|
+
}): Record<string, IDashboardParameterEntry[]>;
|
|
@@ -34,15 +34,29 @@ export function hydrateParameterEntries(dashboardParameters, workspaceParameters
|
|
|
34
34
|
*
|
|
35
35
|
* For legacy single-tab dashboards (no `tabs[]`), a synthetic tab with `DEFAULT_TAB_ID` is used
|
|
36
36
|
* so the V1 root-level `parameters` migrate transparently.
|
|
37
|
+
*
|
|
38
|
+
* `activeTabOverride` patches `runtimeOverride` on its named tab for refs that match an entry;
|
|
39
|
+
* non-matching refs are silently ignored (see `overrideDefaultParameters` on DashboardConfig).
|
|
37
40
|
*/
|
|
38
|
-
export function distributeParametersToTabs(tabs, rootParameters, workspaceParameters) {
|
|
41
|
+
export function distributeParametersToTabs(tabs, rootParameters, workspaceParameters, activeTabOverride) {
|
|
39
42
|
const effectiveTabs = tabs ?? [
|
|
40
43
|
{ localIdentifier: DEFAULT_TAB_ID, title: "", parameters: rootParameters },
|
|
41
44
|
];
|
|
42
45
|
const result = {};
|
|
43
46
|
for (const tab of effectiveTabs) {
|
|
44
47
|
const source = pickTabParametersSource(tab, effectiveTabs, rootParameters);
|
|
45
|
-
|
|
48
|
+
const entries = hydrateParameterEntries(source, workspaceParameters);
|
|
49
|
+
result[tab.localIdentifier] =
|
|
50
|
+
tab.localIdentifier === activeTabOverride?.tabId
|
|
51
|
+
? applyRuntimeOverrides(entries, activeTabOverride.overrides)
|
|
52
|
+
: entries;
|
|
46
53
|
}
|
|
47
54
|
return result;
|
|
48
55
|
}
|
|
56
|
+
function applyRuntimeOverrides(entries, overrides) {
|
|
57
|
+
const overrideByRef = new Map(overrides.map((o) => [objRefToString(o.ref), o.value]));
|
|
58
|
+
return entries.map((entry) => {
|
|
59
|
+
const key = objRefToString(entry.parameter.ref);
|
|
60
|
+
return overrideByRef.has(key) ? { ...entry, runtimeOverride: overrideByRef.get(key) } : entry;
|
|
61
|
+
});
|
|
62
|
+
}
|
|
@@ -394,8 +394,10 @@ export function* actionsToInitializeExistingDashboard(ctx, dashboard, insights,
|
|
|
394
394
|
*/
|
|
395
395
|
const dashboardLayout = dashboardLayoutSanitize(customizedDashboard.layout ?? EmptyDashboardLayout, insights, settings);
|
|
396
396
|
const screen = yield select(selectScreen);
|
|
397
|
-
const
|
|
398
|
-
const parametersByTab = distributeParametersToTabs(
|
|
397
|
+
const overrideDefaultParameters = ctx.config?.overrideDefaultParameters;
|
|
398
|
+
const parametersByTab = distributeParametersToTabs(dashboard.tabs, dashboard.parameters, workspaceParameters, overrideDefaultParameters
|
|
399
|
+
? { tabId: effectiveActiveTabId, overrides: overrideDefaultParameters }
|
|
400
|
+
: undefined);
|
|
399
401
|
// Process tabs with complete filterContext initialization for each tab
|
|
400
402
|
let tabsAction = null;
|
|
401
403
|
const validationResults = [];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type SagaIterator } from "redux-saga";
|
|
2
|
-
import { type DashboardTextAttributeFilter, type IAttributeDisplayFormMetadataObject, type IDrillToCustomUrl as IDrillToCustomUrlModel, type ObjRef, type TextAttributeFilter } from "@gooddata/sdk-model";
|
|
2
|
+
import { type DashboardTextAttributeFilter, type IAttributeDisplayFormMetadataObject, type IDrillToCustomUrl as IDrillToCustomUrlModel, type MeasureValueFilterCondition, type ObjRef, type TextAttributeFilter } from "@gooddata/sdk-model";
|
|
3
3
|
import { type IDrillEvent, type IDrillEventIntersectionElement } from "@gooddata/sdk-ui";
|
|
4
4
|
import { type IDrillToCustomUrl } from "../../commands/drill.js";
|
|
5
5
|
import { type DashboardContext } from "../../types/commonTypes.js";
|
|
@@ -22,6 +22,8 @@ export declare function loadAttributeElementsForDrillIntersection(drillIntersect
|
|
|
22
22
|
export declare function getAttributeDisplayForms(projectId: string, objRefs: ObjRef[], ctx: DashboardContext): Promise<IAttributeDisplayFormMetadataObject[]>;
|
|
23
23
|
export declare function getAttributeIdentifiersReplacements(url: string, drillIntersectionElements: IDrillEventIntersectionElement[], ctx: DashboardContext): SagaIterator<IDrillToUrlPlaceholderReplacement[]>;
|
|
24
24
|
export declare function getDashboardAttributeFilterReplacements(url: string, ctx: DashboardContext): SagaIterator<IDrillToUrlPlaceholderReplacement[]>;
|
|
25
|
+
export declare function getDashboardMeasureValueFilterReplacements(url: string): SagaIterator<IDrillToUrlPlaceholderReplacement[]>;
|
|
26
|
+
export declare function getInsightMeasureValueFilterReplacements(url: string, widgetRef: ObjRef): SagaIterator<IDrillToUrlPlaceholderReplacement[]>;
|
|
25
27
|
export declare function getInsightAttributeFilterReplacements(url: string, widgetRef: ObjRef): SagaIterator<IDrillToUrlPlaceholderReplacement[]>;
|
|
26
28
|
export declare function getInsightIdentifiersReplacements(customUrl: string, widgetRef: ObjRef, ctx: DashboardContext): SagaIterator<IDrillToUrlPlaceholderReplacement[]>;
|
|
27
29
|
export declare function resolveDrillToCustomUrl(drillConfig: IDrillToCustomUrlModel, widgetRef: ObjRef, event: IDrillEvent, ctx: DashboardContext, cmd: IDrillToCustomUrl): SagaIterator<string>;
|
|
@@ -29,4 +31,8 @@ export declare function resolveDrillToCustomUrl(drillConfig: IDrillToCustomUrlMo
|
|
|
29
31
|
* @internal
|
|
30
32
|
*/
|
|
31
33
|
export declare function stringifyTextFilterSelection(filter: DashboardTextAttributeFilter | TextAttributeFilter): string;
|
|
34
|
+
/**
|
|
35
|
+
* @internal
|
|
36
|
+
*/
|
|
37
|
+
export declare function stringifyMeasureValueFilterCondition(conditions: MeasureValueFilterCondition[] | undefined): string;
|
|
32
38
|
export {};
|
|
@@ -2,19 +2,21 @@
|
|
|
2
2
|
import stringify from "json-stable-stringify";
|
|
3
3
|
import { groupBy } from "lodash-es";
|
|
4
4
|
import { all, call, select } from "redux-saga/effects";
|
|
5
|
-
import { areObjRefsEqual, dashboardAttributeFilterItemDisplayForm, filterAttributeElements, filterObjRef, idRef, insightId, isArbitraryAttributeFilter, isAttributeDescriptor, isAttributeElementsByValue, isDashboardArbitraryAttributeFilter, isDashboardAttributeFilter, isDashboardTextAttributeFilter, isNegativeAttributeFilter, isTextAttributeFilter, } from "@gooddata/sdk-model";
|
|
6
|
-
import { getAttributeIdentifiersPlaceholdersFromUrl, getDashboardAttributeFilterPlaceholdersFromUrl, getInsightAttributeFilterPlaceholdersFromUrl, } from "@gooddata/sdk-model/internal";
|
|
5
|
+
import { areObjRefsEqual, dashboardAttributeFilterItemDisplayForm, dashboardFilterObjRef, filterAttributeElements, filterObjRef, idRef, insightFilters as insightDefinitionFilters, insightId, isArbitraryAttributeFilter, isAttributeDescriptor, isAttributeElementsByValue, isComparisonCondition, isDashboardArbitraryAttributeFilter, isDashboardAttributeFilter, isDashboardTextAttributeFilter, isMeasureValueFilter, isNegativeAttributeFilter, isRangeCondition, isTextAttributeFilter, measureValueFilterConditions, measureValueFilterMeasure, } from "@gooddata/sdk-model";
|
|
6
|
+
import { getAttributeIdentifiersPlaceholdersFromUrl, getDashboardAttributeFilterPlaceholdersFromUrl, getDashboardMeasureValueFilterPlaceholdersFromUrl, getInsightAttributeFilterPlaceholdersFromUrl, getInsightMeasureValueFilterPlaceholdersFromUrl, } from "@gooddata/sdk-model/internal";
|
|
7
7
|
import { isDrillIntersectionAttributeItem, } from "@gooddata/sdk-ui";
|
|
8
8
|
import { invalidArgumentsProvided } from "../../events/general.js";
|
|
9
9
|
import { queryWidgetFilters } from "../../queries/widgets.js";
|
|
10
10
|
import { query } from "../../store/_infra/queryCall.js";
|
|
11
|
-
import { selectAllCatalogDisplayFormsMap, selectCatalogDateAttributes, } from "../../store/catalog/catalogSelectors.js";
|
|
11
|
+
import { selectAllCatalogDisplayFormsMap, selectAllCatalogMeasuresMap, selectCatalogDateAttributes, } from "../../store/catalog/catalogSelectors.js";
|
|
12
|
+
import { selectEnableMeasureValueFilterKD } from "../../store/config/configSelectors.js";
|
|
12
13
|
import { selectInsightByRef } from "../../store/insights/insightsSelectors.js";
|
|
13
14
|
import { selectDashboardId } from "../../store/meta/metaSelectors.js";
|
|
14
15
|
import { selectAttributeFilterConfigsOverrides } from "../../store/tabs/attributeFilterConfigs/attributeFilterConfigsSelectors.js";
|
|
15
|
-
import { selectFilterContextAttributeFilterItems } from "../../store/tabs/filterContext/filterContextSelectors.js";
|
|
16
|
+
import { selectFilterContextAttributeFilterItems, selectFilterContextMeasureValueFilters, } from "../../store/tabs/filterContext/filterContextSelectors.js";
|
|
16
17
|
import { selectAnalyticalWidgetByRef } from "../../store/tabs/layout/layoutSelectors.js";
|
|
17
18
|
import { DRILL_TO_URL_PLACEHOLDER } from "../../types/drillTypes.js";
|
|
19
|
+
import { dashboardMeasureValueFilterMatchesIdentifier, insightMeasureValueFilterMatchesIdentifier, } from "../../utils/measureValueFilterUtils.js";
|
|
18
20
|
import { getElementTitle, getElementsSecondaryTitles } from "./getElementTitle.js";
|
|
19
21
|
export function* loadElementTitle(dfRef, dfIdentifier, attrElementUri, ctx) {
|
|
20
22
|
const elementTitle = yield call(getElementTitle, ctx.workspace, dfRef, attrElementUri, ctx);
|
|
@@ -164,6 +166,49 @@ export function* getDashboardAttributeFilterReplacements(url, ctx) {
|
|
|
164
166
|
const attributeFilterConfigs = yield select(selectAttributeFilterConfigsOverrides);
|
|
165
167
|
return yield all(attributeFilterPlaceholders.map((placeholder) => call(resolveDashboardAttributeFilterReplacement, placeholder, attributeFilters, catalogDisplayForms, attributeFilterConfigs, ctx)));
|
|
166
168
|
}
|
|
169
|
+
function resolveDashboardMeasureValueFilterReplacement({ placeholder: toBeReplaced, identifier }, measureValueFilters, catalogMeasures) {
|
|
170
|
+
const usedFilter = measureValueFilters.find((filter) => {
|
|
171
|
+
const measureRef = dashboardFilterObjRef(filter);
|
|
172
|
+
return dashboardMeasureValueFilterMatchesIdentifier(measureRef, identifier, catalogMeasures);
|
|
173
|
+
});
|
|
174
|
+
const parsedFilter = stringifyMeasureValueFilterCondition(usedFilter?.dashboardMeasureValueFilter.conditions);
|
|
175
|
+
const replacement = usedFilter ? encodeParameterIfSet(parsedFilter) : undefined;
|
|
176
|
+
return {
|
|
177
|
+
toBeReplaced,
|
|
178
|
+
replacement: replacement,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
export function* getDashboardMeasureValueFilterReplacements(url) {
|
|
182
|
+
const measureValueFilterPlaceholders = getDashboardMeasureValueFilterPlaceholdersFromUrl(url);
|
|
183
|
+
if (measureValueFilterPlaceholders.length === 0) {
|
|
184
|
+
return [];
|
|
185
|
+
}
|
|
186
|
+
const measureValueFilters = yield select(selectFilterContextMeasureValueFilters);
|
|
187
|
+
const catalogMeasures = yield select(selectAllCatalogMeasuresMap);
|
|
188
|
+
return measureValueFilterPlaceholders.map((placeholder) => resolveDashboardMeasureValueFilterReplacement(placeholder, measureValueFilters, catalogMeasures));
|
|
189
|
+
}
|
|
190
|
+
function resolveInsightMeasureValueFilterReplacement({ placeholder: toBeReplaced, identifier }, measureValueFilters) {
|
|
191
|
+
const usedFilter = measureValueFilters.find((filter) => {
|
|
192
|
+
const measureRef = measureValueFilterMeasure(filter);
|
|
193
|
+
return insightMeasureValueFilterMatchesIdentifier(measureRef, identifier);
|
|
194
|
+
});
|
|
195
|
+
const parsedFilter = stringifyMeasureValueFilterCondition(usedFilter ? measureValueFilterConditions(usedFilter) : undefined);
|
|
196
|
+
const replacement = usedFilter ? encodeParameterIfSet(parsedFilter) : undefined;
|
|
197
|
+
return {
|
|
198
|
+
toBeReplaced,
|
|
199
|
+
replacement: replacement,
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
export function* getInsightMeasureValueFilterReplacements(url, widgetRef) {
|
|
203
|
+
const measureValueFilterPlaceholders = getInsightMeasureValueFilterPlaceholdersFromUrl(url);
|
|
204
|
+
if (measureValueFilterPlaceholders.length === 0) {
|
|
205
|
+
return [];
|
|
206
|
+
}
|
|
207
|
+
const widget = yield select(selectAnalyticalWidgetByRef(widgetRef));
|
|
208
|
+
const insight = yield select(selectInsightByRef(widget.insight));
|
|
209
|
+
const measureValueFilters = insight ? insightDefinitionFilters(insight).filter(isMeasureValueFilter) : [];
|
|
210
|
+
return measureValueFilterPlaceholders.map((placeholder) => resolveInsightMeasureValueFilterReplacement(placeholder, measureValueFilters));
|
|
211
|
+
}
|
|
167
212
|
export function* getInsightAttributeFilterReplacements(url, widgetRef) {
|
|
168
213
|
const attributeFilterPlaceholders = getInsightAttributeFilterPlaceholdersFromUrl(url);
|
|
169
214
|
if (attributeFilterPlaceholders.length === 0) {
|
|
@@ -224,10 +269,20 @@ export function* resolveDrillToCustomUrl(drillConfig, widgetRef, event, ctx, cmd
|
|
|
224
269
|
const attributeIdentifiersReplacements = yield call(getAttributeIdentifiersReplacements, customUrl, event.drillContext.intersection, ctx);
|
|
225
270
|
const dashboardAttributeFilterReplacements = yield call(getDashboardAttributeFilterReplacements, customUrl, ctx);
|
|
226
271
|
const insightAttributeFilterReplacements = yield call(getInsightAttributeFilterReplacements, customUrl, widgetRef);
|
|
272
|
+
const dashboardMeasureValueFilterReplacements = yield call(getDashboardMeasureValueFilterReplacements, customUrl);
|
|
273
|
+
const enableMeasureValueFilterKD = yield select(selectEnableMeasureValueFilterKD);
|
|
274
|
+
const insightMeasureValueFilterReplacements = enableMeasureValueFilterKD
|
|
275
|
+
? yield call(getInsightMeasureValueFilterReplacements, customUrl, widgetRef)
|
|
276
|
+
: getInsightMeasureValueFilterPlaceholdersFromUrl(customUrl).map(({ placeholder }) => ({
|
|
277
|
+
toBeReplaced: placeholder,
|
|
278
|
+
replacement: undefined,
|
|
279
|
+
}));
|
|
227
280
|
const missingReplacement = [
|
|
228
281
|
...attributeIdentifiersReplacements,
|
|
229
282
|
...dashboardAttributeFilterReplacements,
|
|
230
283
|
...insightAttributeFilterReplacements,
|
|
284
|
+
...dashboardMeasureValueFilterReplacements,
|
|
285
|
+
...insightMeasureValueFilterReplacements,
|
|
231
286
|
].find(({ replacement }) => replacement === undefined);
|
|
232
287
|
if (missingReplacement) {
|
|
233
288
|
throw invalidArgumentsProvided(ctx, cmd, `Drill to custom URL unable to resolve missing parameter ${missingReplacement.toBeReplaced}`);
|
|
@@ -237,6 +292,8 @@ export function* resolveDrillToCustomUrl(drillConfig, widgetRef, event, ctx, cmd
|
|
|
237
292
|
...attributeIdentifiersReplacements,
|
|
238
293
|
...dashboardAttributeFilterReplacements,
|
|
239
294
|
...insightAttributeFilterReplacements,
|
|
295
|
+
...dashboardMeasureValueFilterReplacements,
|
|
296
|
+
...insightMeasureValueFilterReplacements,
|
|
240
297
|
...insightIdentifiersReplacements,
|
|
241
298
|
];
|
|
242
299
|
return applyReplacements(customUrl, replacements);
|
|
@@ -265,3 +322,22 @@ function stringifyMatchFilterSelection(literal, operator, isNegative) {
|
|
|
265
322
|
const prefix = isNegative ? `NOT_${operatorStr}` : operatorStr;
|
|
266
323
|
return `${prefix}${stringify([literal])}`;
|
|
267
324
|
}
|
|
325
|
+
/**
|
|
326
|
+
* @internal
|
|
327
|
+
*/
|
|
328
|
+
export function stringifyMeasureValueFilterCondition(conditions) {
|
|
329
|
+
if (!conditions || conditions.length === 0) {
|
|
330
|
+
return "ALL";
|
|
331
|
+
}
|
|
332
|
+
return conditions
|
|
333
|
+
.map((condition) => {
|
|
334
|
+
if (isComparisonCondition(condition)) {
|
|
335
|
+
return `${condition.comparison.operator}(${condition.comparison.value})`;
|
|
336
|
+
}
|
|
337
|
+
if (isRangeCondition(condition)) {
|
|
338
|
+
return `${condition.range.operator}(${condition.range.from},${condition.range.to})`;
|
|
339
|
+
}
|
|
340
|
+
return "ALL";
|
|
341
|
+
})
|
|
342
|
+
.join("|");
|
|
343
|
+
}
|
|
@@ -4,6 +4,7 @@ import { areObjRefsEqual, isDashboardAttributeFilter, } from "@gooddata/sdk-mode
|
|
|
4
4
|
import { defaultErrorHandler } from "@gooddata/sdk-ui";
|
|
5
5
|
import { changeFilterContextSelectionByParams, reloadFilterViews, } from "../../commands/filters.js";
|
|
6
6
|
import { filterViewApplicationFailed, filterViewApplicationSucceeded, filterViewCreationFailed, filterViewCreationSucceeded, filterViewDefaultStatusChangeFailed, filterViewDefaultStatusChangeSucceeded, filterViewDeletionFailed, filterViewDeletionSucceeded, } from "../../events/filters.js";
|
|
7
|
+
import { selectCatalogParameters } from "../../store/catalog/catalogSelectors.js";
|
|
7
8
|
import { selectIsApplyFiltersAllAtOnceEnabledAndSet } from "../../store/config/configSelectors.js";
|
|
8
9
|
import { selectCrossFilteringFiltersLocalIdentifiers } from "../../store/drill/drillSelectors.js";
|
|
9
10
|
import { selectFilterViews } from "../../store/filterViews/filterViewsReducersSelectors.js";
|
|
@@ -11,9 +12,11 @@ import { filterViewsActions } from "../../store/filterViews/index.js";
|
|
|
11
12
|
import { selectAttributeFilterConfigsOverrides } from "../../store/tabs/attributeFilterConfigs/attributeFilterConfigsSelectors.js";
|
|
12
13
|
import { selectFilterContextDefinition, selectWorkingFilterContextDefinition, } from "../../store/tabs/filterContext/filterContextSelectors.js";
|
|
13
14
|
import { tabsActions } from "../../store/tabs/index.js";
|
|
15
|
+
import { selectFilterViewParameters } from "../../store/tabs/parameters/parametersSelectors.js";
|
|
14
16
|
import { selectActiveTabLocalIdentifier } from "../../store/tabs/tabsSelectors.js";
|
|
15
17
|
import { loadFilterViews } from "../dashboard/initializeDashboardHandler/loadFilterViews.js";
|
|
16
18
|
import { resetCrossFiltering } from "./common.js";
|
|
19
|
+
import { resolveFilterViewParameterValues } from "./filterViewParameters.js";
|
|
17
20
|
function createFilterView(ctx, filterView) {
|
|
18
21
|
return ctx.backend.workspace(ctx.workspace).dashboards().createFilterView(filterView);
|
|
19
22
|
}
|
|
@@ -36,6 +39,7 @@ export function* saveFilterViewHandler(ctx, cmd) {
|
|
|
36
39
|
!filter.attributeFilter.localIdentifier ||
|
|
37
40
|
!virtualFilters.includes(filter.attributeFilter.localIdentifier)),
|
|
38
41
|
};
|
|
42
|
+
const parameters = yield select(selectFilterViewParameters);
|
|
39
43
|
const filterView = {
|
|
40
44
|
name: cmd.payload.name,
|
|
41
45
|
dashboard: ctx.dashboardRef,
|
|
@@ -43,6 +47,7 @@ export function* saveFilterViewHandler(ctx, cmd) {
|
|
|
43
47
|
isDefault: cmd.payload.isDefault,
|
|
44
48
|
// Include tabId if there's an active tab
|
|
45
49
|
...(activeTabLocalIdentifier ? { tabLocalIdentifier: activeTabLocalIdentifier } : {}),
|
|
50
|
+
...(parameters ? { parameters } : {}),
|
|
46
51
|
};
|
|
47
52
|
try {
|
|
48
53
|
const newFilterView = yield call(createFilterView, ctx, filterView);
|
|
@@ -91,6 +96,11 @@ export function* applyFilterViewHandler(ctx, cmd) {
|
|
|
91
96
|
resetOthers: true,
|
|
92
97
|
correlationId: cmd.correlationId,
|
|
93
98
|
}));
|
|
99
|
+
if (filterView.parameters && filterView.parameters.length > 0) {
|
|
100
|
+
const workspaceParameters = yield select(selectCatalogParameters);
|
|
101
|
+
const values = resolveFilterViewParameterValues(filterView.parameters, workspaceParameters);
|
|
102
|
+
yield put(tabsActions.setParameterRuntimeValues({ values }));
|
|
103
|
+
}
|
|
94
104
|
yield put(filterViewApplicationSucceeded(ctx, filterView, cmd.correlationId));
|
|
95
105
|
}
|
|
96
106
|
else {
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type IDashboardParameter, type IParameterMetadataObject, type ObjRef } from "@gooddata/sdk-model";
|
|
2
|
+
interface IResolvedFilterViewParameter {
|
|
3
|
+
ref: ObjRef;
|
|
4
|
+
value: number | undefined;
|
|
5
|
+
}
|
|
6
|
+
export declare function resolveFilterViewParameterValues(parameters: ReadonlyArray<IDashboardParameter>, workspaceParameters: ReadonlyArray<IParameterMetadataObject>): IResolvedFilterViewParameter[];
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// (C) 2026 GoodData Corporation
|
|
2
|
+
import { areObjRefsEqual, } from "@gooddata/sdk-model";
|
|
3
|
+
export function resolveFilterViewParameterValues(parameters, workspaceParameters) {
|
|
4
|
+
return parameters.map((parameter) => {
|
|
5
|
+
if (parameter.value !== undefined) {
|
|
6
|
+
return { ref: parameter.ref, value: parameter.value };
|
|
7
|
+
}
|
|
8
|
+
const workspaceParameter = workspaceParameters.find((item) => areObjRefsEqual(item.ref, parameter.ref));
|
|
9
|
+
return { ref: parameter.ref, value: workspaceParameter?.definition.defaultValue };
|
|
10
|
+
});
|
|
11
|
+
}
|
|
@@ -467,12 +467,6 @@ export declare const selectEnableExecutionCancelling: DashboardSelector<boolean>
|
|
|
467
467
|
* @internal
|
|
468
468
|
*/
|
|
469
469
|
export declare const selectEnableDashboardShareLink: DashboardSelector<boolean>;
|
|
470
|
-
/**
|
|
471
|
-
* Selector for the automation filter context feature flag
|
|
472
|
-
*
|
|
473
|
-
* @internal
|
|
474
|
-
*/
|
|
475
|
-
export declare const selectEnableAutomationFilterContext: DashboardSelector<boolean>;
|
|
476
470
|
/**
|
|
477
471
|
* Selector for the date filter local identifiers feature flag
|
|
478
472
|
*
|
|
@@ -563,12 +557,6 @@ export declare const selectEnableSnapshotExport: DashboardSelector<boolean>;
|
|
|
563
557
|
* @internal
|
|
564
558
|
*/
|
|
565
559
|
export declare const selectEnableAccessibilityMode: DashboardSelector<boolean>;
|
|
566
|
-
/**
|
|
567
|
-
* Returns whether implicit drill to url feature is enabled.
|
|
568
|
-
*
|
|
569
|
-
* @alpha
|
|
570
|
-
*/
|
|
571
|
-
export declare const selectEnableImplicitDrillToUrl: DashboardSelector<boolean>;
|
|
572
560
|
/**
|
|
573
561
|
* Returns the timeout to use when polling for export results (in milliseconds).
|
|
574
562
|
*
|
|
@@ -630,14 +630,6 @@ export const selectEnableExecutionCancelling = createSelector(selectConfig, (sta
|
|
|
630
630
|
export const selectEnableDashboardShareLink = createSelector(selectConfig, (state) => {
|
|
631
631
|
return Boolean(state.settings?.enableDashboardShareLink);
|
|
632
632
|
});
|
|
633
|
-
/**
|
|
634
|
-
* Selector for the automation filter context feature flag
|
|
635
|
-
*
|
|
636
|
-
* @internal
|
|
637
|
-
*/
|
|
638
|
-
export const selectEnableAutomationFilterContext = createSelector(selectConfig, (state) => {
|
|
639
|
-
return Boolean(state.settings?.enableAutomationFilterContext);
|
|
640
|
-
});
|
|
641
633
|
/**
|
|
642
634
|
* Selector for the date filter local identifiers feature flag
|
|
643
635
|
*
|
|
@@ -758,14 +750,6 @@ export const selectEnableSnapshotExport = createSelector(selectConfig, (state) =
|
|
|
758
750
|
export const selectEnableAccessibilityMode = createSelector(selectConfig, (state) => {
|
|
759
751
|
return Boolean(state.settings?.enableAccessibilityMode);
|
|
760
752
|
});
|
|
761
|
-
/**
|
|
762
|
-
* Returns whether implicit drill to url feature is enabled.
|
|
763
|
-
*
|
|
764
|
-
* @alpha
|
|
765
|
-
*/
|
|
766
|
-
export const selectEnableImplicitDrillToUrl = createSelector(selectConfig, (state) => {
|
|
767
|
-
return state.settings?.enableImplicitDrillToUrl ?? true;
|
|
768
|
-
});
|
|
769
753
|
/**
|
|
770
754
|
* Returns the timeout to use when polling for export results (in milliseconds).
|
|
771
755
|
*
|
|
@@ -784,8 +768,8 @@ export const selectExportResultPollingTimeout = createSelector(selectConfig, (st
|
|
|
784
768
|
*
|
|
785
769
|
* @alpha
|
|
786
770
|
*/
|
|
787
|
-
export const selectEnableDrillToUrlByDefault = createSelector(selectConfig,
|
|
788
|
-
return
|
|
771
|
+
export const selectEnableDrillToUrlByDefault = createSelector(selectConfig, (state) => {
|
|
772
|
+
return state.settings?.enableDrillToUrlByDefault ?? false;
|
|
789
773
|
});
|
|
790
774
|
/**
|
|
791
775
|
* Returns whether fiscal calendars feature flag is enabled.
|
|
@@ -575,6 +575,10 @@ export declare const tabsActions: import("@reduxjs/toolkit").CaseReducerActions<
|
|
|
575
575
|
payload: import("./parameters/parametersReducers.js").ISetParameterRuntimeValuePayload;
|
|
576
576
|
type: string;
|
|
577
577
|
}) => void | import("./tabsState.js").ITabsState | import("immer").WritableDraft<import("./tabsState.js").ITabsState>;
|
|
578
|
+
readonly setParameterRuntimeValues: (state: import("immer").WritableDraft<import("./tabsState.js").ITabsState>, action: {
|
|
579
|
+
payload: import("./parameters/parametersReducers.js").ISetParameterRuntimeValuesPayload;
|
|
580
|
+
type: string;
|
|
581
|
+
}) => void | import("./tabsState.js").ITabsState | import("immer").WritableDraft<import("./tabsState.js").ITabsState>;
|
|
578
582
|
readonly removeParameter: (state: import("immer").WritableDraft<import("./tabsState.js").ITabsState>, action: {
|
|
579
583
|
payload: import("./parameters/parametersReducers.js").IRemoveParameterPayload;
|
|
580
584
|
type: string;
|
|
@@ -17,7 +17,13 @@ export interface IAddParameterPayload {
|
|
|
17
17
|
*/
|
|
18
18
|
export interface ISetParameterRuntimeValuePayload {
|
|
19
19
|
ref: ObjRef;
|
|
20
|
-
value: number;
|
|
20
|
+
value: number | undefined;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* @alpha
|
|
24
|
+
*/
|
|
25
|
+
export interface ISetParameterRuntimeValuesPayload {
|
|
26
|
+
values: ISetParameterRuntimeValuePayload[];
|
|
21
27
|
}
|
|
22
28
|
/**
|
|
23
29
|
* @alpha
|
|
@@ -34,6 +40,10 @@ export declare const parametersReducers: {
|
|
|
34
40
|
payload: ISetParameterRuntimeValuePayload;
|
|
35
41
|
type: string;
|
|
36
42
|
}>;
|
|
43
|
+
setParameterRuntimeValues: ParametersReducer<{
|
|
44
|
+
payload: ISetParameterRuntimeValuesPayload;
|
|
45
|
+
type: string;
|
|
46
|
+
}>;
|
|
37
47
|
removeParameter: ParametersReducer<{
|
|
38
48
|
payload: IRemoveParameterPayload;
|
|
39
49
|
type: string;
|
|
@@ -20,14 +20,11 @@ const addParameter = (state, action) => {
|
|
|
20
20
|
};
|
|
21
21
|
};
|
|
22
22
|
const setParameterRuntimeValue = (state, action) => {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const entry = activeTab.parameters.parameters.find((item) => areObjRefsEqual(item.parameter.ref, ref));
|
|
29
|
-
if (entry) {
|
|
30
|
-
entry.runtimeOverride = value;
|
|
23
|
+
setRuntimeOverride(state, action.payload);
|
|
24
|
+
};
|
|
25
|
+
const setParameterRuntimeValues = (state, action) => {
|
|
26
|
+
for (const entry of action.payload.values) {
|
|
27
|
+
setRuntimeOverride(state, entry);
|
|
31
28
|
}
|
|
32
29
|
};
|
|
33
30
|
const removeParameter = (state, action) => {
|
|
@@ -39,8 +36,19 @@ const removeParameter = (state, action) => {
|
|
|
39
36
|
parameters: activeTab.parameters.parameters.filter((entry) => !areObjRefsEqual(entry.parameter.ref, action.payload.ref)),
|
|
40
37
|
};
|
|
41
38
|
};
|
|
39
|
+
function setRuntimeOverride(state, { ref, value }) {
|
|
40
|
+
const activeTab = getActiveTab(state);
|
|
41
|
+
if (!activeTab?.parameters) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const entry = activeTab.parameters.parameters.find((item) => areObjRefsEqual(item.parameter.ref, ref));
|
|
45
|
+
if (entry && entry.runtimeOverride !== value) {
|
|
46
|
+
entry.runtimeOverride = value;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
42
49
|
export const parametersReducers = {
|
|
43
50
|
addParameter,
|
|
44
51
|
setParameterRuntimeValue,
|
|
52
|
+
setParameterRuntimeValues,
|
|
45
53
|
removeParameter,
|
|
46
54
|
};
|
|
@@ -20,6 +20,13 @@ export declare const selectActiveParameterRefKeys: DashboardSelector<ReadonlySet
|
|
|
20
20
|
* @internal
|
|
21
21
|
*/
|
|
22
22
|
export declare const selectDashboardParameterEntries: DashboardSelector<IDashboardParameterEntry[]>;
|
|
23
|
+
/**
|
|
24
|
+
* Returns the active tab's parameters in the shape persisted by a filter view.
|
|
25
|
+
* Runtime overrides become persisted `value`; existing parameter values are kept when no runtime value exists.
|
|
26
|
+
*
|
|
27
|
+
* @internal
|
|
28
|
+
*/
|
|
29
|
+
export declare const selectFilterViewParameters: DashboardSelector<IDashboardParameter[] | undefined>;
|
|
23
30
|
/**
|
|
24
31
|
* Returns a selector that yields the entry held by the active tab for a given parameter ref,
|
|
25
32
|
* or `undefined` if no such entry exists.
|
|
@@ -35,6 +35,23 @@ export const selectActiveParameterRefKeys = createSelector(selectDashboardParame
|
|
|
35
35
|
* @internal
|
|
36
36
|
*/
|
|
37
37
|
export const selectDashboardParameterEntries = createSelector(selectParametersState, (state) => state.parameters);
|
|
38
|
+
/**
|
|
39
|
+
* Returns the active tab's parameters in the shape persisted by a filter view.
|
|
40
|
+
* Runtime overrides become persisted `value`; existing parameter values are kept when no runtime value exists.
|
|
41
|
+
*
|
|
42
|
+
* @internal
|
|
43
|
+
*/
|
|
44
|
+
export const selectFilterViewParameters = createSelector(selectDashboardParameterEntries, (entries) => {
|
|
45
|
+
if (entries.length === 0) {
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
return entries.map((entry) => {
|
|
49
|
+
if (entry.runtimeOverride === undefined) {
|
|
50
|
+
return entry.parameter;
|
|
51
|
+
}
|
|
52
|
+
return { ...entry.parameter, value: entry.runtimeOverride };
|
|
53
|
+
});
|
|
54
|
+
});
|
|
38
55
|
/**
|
|
39
56
|
* Returns a selector that yields the entry held by the active tab for a given parameter ref,
|
|
40
57
|
* or `undefined` if no such entry exists.
|
|
@@ -10,7 +10,7 @@ import { createMemoizedSelector } from "../_infra/selectors.js";
|
|
|
10
10
|
import { selectAccessibleDashboardsLoaded, selectAccessibleDashboardsMap, } from "../accessibleDashboards/accessibleDashboardsSelectors.js";
|
|
11
11
|
import { selectBackendCapabilities, selectSupportsAttributeHierarchies, selectSupportsCrossFiltering, } from "../backendCapabilities/backendCapabilitiesSelectors.js";
|
|
12
12
|
import { selectAllCatalogAttributeHierarchies, selectAllCatalogAttributesMap, selectAllCatalogDisplayFormsMap, selectAttributesWithDisplayFormLink, selectAttributesWithHierarchyDescendants, selectCatalogDateAttributes, selectCatalogIsLoaded, } from "../catalog/catalogSelectors.js";
|
|
13
|
-
import { selectDisableDefaultDrills, selectEnableDrillToUrlByDefault,
|
|
13
|
+
import { selectDisableDefaultDrills, selectEnableDrillToUrlByDefault, selectEnableKDCrossFiltering, selectEnableKda, selectIsDisabledCrossFiltering, selectIsDisabledKda, selectIsEmbedded, } from "../config/configSelectors.js";
|
|
14
14
|
import { selectDrillableItems } from "../drill/drillSelectors.js";
|
|
15
15
|
import { selectDrillTargetsByWidgetRef } from "../drillTargets/drillTargetsSelectors.js";
|
|
16
16
|
import { selectInsightByWidgetRef, selectInsightsMap } from "../insights/insightsSelectors.js";
|
|
@@ -126,14 +126,11 @@ function getDrillDownDefinitionsWithPredicates(availableDrillAttributes, attribu
|
|
|
126
126
|
});
|
|
127
127
|
});
|
|
128
128
|
}
|
|
129
|
-
function getDrillToUrlDefinitionsWithPredicates(availableDrillAttributes, attributesWithDisplayFormLink, ignoredDrillToUrlAttributes
|
|
129
|
+
function getDrillToUrlDefinitionsWithPredicates(availableDrillAttributes, attributesWithDisplayFormLink, ignoredDrillToUrlAttributes) {
|
|
130
130
|
const matchingAvailableDrillAttributes = availableDrillAttributes.filter((candidate) => {
|
|
131
131
|
return attributesWithDisplayFormLink.some((attr) => areObjRefsEqual(attr.attribute.ref, candidate.attribute.attributeHeader.formOf.ref));
|
|
132
132
|
});
|
|
133
133
|
const filterIgnoredDrillToUrlAttributes = (targetAttribute) => {
|
|
134
|
-
if (!enableImplicitDrillToUrl) {
|
|
135
|
-
return true;
|
|
136
|
-
}
|
|
137
134
|
return !ignoredDrillToUrlAttributes?.some((ignoredAttributeRef) => areObjRefsEqual(targetAttribute.attribute.attributeHeader.ref, ignoredAttributeRef));
|
|
138
135
|
};
|
|
139
136
|
const mapDrillTargetToDefinition = (targetAttribute) => {
|
|
@@ -304,10 +301,7 @@ export const selectGlobalDrillsDownAttributeHierarchyByWidgetRef = createMemoize
|
|
|
304
301
|
/**
|
|
305
302
|
* @internal
|
|
306
303
|
*/
|
|
307
|
-
export const selectDrillsToUrlAttributeByWidgetRef = createMemoizedSelector((ref) => createSelector(selectDrillTargetsByWidgetRef(ref), selectIgnoredDrillToUrlAttributesByWidgetRef(ref), selectInsightByWidgetRef(ref), selectAllCatalogDisplayFormsMap, selectAllCatalogAttributesMap, selectEnableDrillToUrlByDefault,
|
|
308
|
-
if (!enableImplicitDrillToUrl) {
|
|
309
|
-
return [];
|
|
310
|
-
}
|
|
304
|
+
export const selectDrillsToUrlAttributeByWidgetRef = createMemoizedSelector((ref) => createSelector(selectDrillTargetsByWidgetRef(ref), selectIgnoredDrillToUrlAttributesByWidgetRef(ref), selectInsightByWidgetRef(ref), selectAllCatalogDisplayFormsMap, selectAllCatalogAttributesMap, selectEnableDrillToUrlByDefault, (availableDrillTargets, ignoredDrillToUrlAttributes, widgetInsight, allCatalogDisplayFormsMap, allCatalogAttributesMap, enableDrillToUrlByDefault) => {
|
|
311
305
|
const disableDrillIntoURL = widgetInsight?.insight?.properties?.["controls"]?.disableDrillIntoURL ??
|
|
312
306
|
!enableDrillToUrlByDefault;
|
|
313
307
|
if (disableDrillIntoURL) {
|
|
@@ -341,9 +335,9 @@ export const selectDrillsToUrlAttributeByWidgetRef = createMemoizedSelector((ref
|
|
|
341
335
|
/**
|
|
342
336
|
* @internal
|
|
343
337
|
*/
|
|
344
|
-
export const selectImplicitDrillsToUrlByWidgetRef = createMemoizedSelector((ref) => createSelector(selectDrillTargetsByWidgetRef(ref), selectAttributesWithDisplayFormLink, selectIgnoredDrillToUrlAttributesByWidgetRef(ref),
|
|
338
|
+
export const selectImplicitDrillsToUrlByWidgetRef = createMemoizedSelector((ref) => createSelector(selectDrillTargetsByWidgetRef(ref), selectAttributesWithDisplayFormLink, selectIgnoredDrillToUrlAttributesByWidgetRef(ref), (availableDrillTargets, attributesWithLink, ignoredDrillToUrlAttributes) => {
|
|
345
339
|
const availableDrillAttributes = availableDrillTargets?.availableDrillTargets?.attributes ?? [];
|
|
346
|
-
return getDrillToUrlDefinitionsWithPredicates(availableDrillAttributes, attributesWithLink, ignoredDrillToUrlAttributes
|
|
340
|
+
return getDrillToUrlDefinitionsWithPredicates(availableDrillAttributes, attributesWithLink, ignoredDrillToUrlAttributes);
|
|
347
341
|
}));
|
|
348
342
|
/**
|
|
349
343
|
* @internal
|
|
@@ -433,9 +427,9 @@ const selectKeyDriverAnalysisPredicates = createMemoizedSelector((ref) => create
|
|
|
433
427
|
/**
|
|
434
428
|
* @internal
|
|
435
429
|
*/
|
|
436
|
-
export const selectConfiguredAndImplicitDrillsByWidgetRef = createMemoizedSelector((ref) => createSelector(selectCatalogIsLoaded, selectAccessibleDashboardsLoaded, selectValidConfiguredDrillsByWidgetRef(ref), selectImplicitDrillsDownByWidgetRef(ref), selectImplicitDrillsToUrlByWidgetRef(ref), selectCrossFilteringByWidgetRef(ref), selectKdaByWidgetRef(ref), selectInsightByWidgetRef(ref), selectEnableDrillToUrlByDefault,
|
|
430
|
+
export const selectConfiguredAndImplicitDrillsByWidgetRef = createMemoizedSelector((ref) => createSelector(selectCatalogIsLoaded, selectAccessibleDashboardsLoaded, selectValidConfiguredDrillsByWidgetRef(ref), selectImplicitDrillsDownByWidgetRef(ref), selectImplicitDrillsToUrlByWidgetRef(ref), selectCrossFilteringByWidgetRef(ref), selectKdaByWidgetRef(ref), selectInsightByWidgetRef(ref), selectEnableDrillToUrlByDefault, (catalogIsLoaded, accessibleDashboardsLoaded, configuredDrills, implicitDrillDownDrills, implicitDrillToUrlDrills, crossFiltering, keyDriverAnalysis, insight, enableDrillToUrlByDefault) => {
|
|
437
431
|
const disableDrillIntoURL = insight?.insight.properties["controls"]?.disableDrillIntoURL ?? !enableDrillToUrlByDefault;
|
|
438
|
-
const isDrillToUrlDisabled =
|
|
432
|
+
const isDrillToUrlDisabled = disableDrillIntoURL;
|
|
439
433
|
// disable drilling until all necessary items are loaded (catalog, dash list, ...)
|
|
440
434
|
const drillActive = catalogIsLoaded && accessibleDashboardsLoaded;
|
|
441
435
|
return drillActive
|
|
@@ -464,16 +458,14 @@ export const selectDrillableItemsByWidgetRef = createMemoizedSelector((ref) => c
|
|
|
464
458
|
/**
|
|
465
459
|
* @internal
|
|
466
460
|
*/
|
|
467
|
-
export const selectImplicitDrillsByAvailableDrillTargets = createMemoizedSelector((availableDrillTargets, ignoredDrillDownHierarchies = [], disableDrillIntoURL) => createSelector(selectAttributesWithDisplayFormLink, selectAttributesWithHierarchyDescendants, selectAllCatalogAttributesMap, selectSupportsAttributeHierarchies, selectAllCatalogAttributeHierarchies, selectBackendCapabilities, selectEnableDrillToUrlByDefault,
|
|
461
|
+
export const selectImplicitDrillsByAvailableDrillTargets = createMemoizedSelector((availableDrillTargets, ignoredDrillDownHierarchies = [], disableDrillIntoURL) => createSelector(selectAttributesWithDisplayFormLink, selectAttributesWithHierarchyDescendants, selectAllCatalogAttributesMap, selectSupportsAttributeHierarchies, selectAllCatalogAttributeHierarchies, selectBackendCapabilities, selectEnableDrillToUrlByDefault, (attributesWithLink, attributesWithHierarchyDescendants, allCatalogAttributesMap, isDrillDownEnabled, allCatalogHierarchies, backendCapabilities, enableDrillToUrlByDefault) => {
|
|
468
462
|
const isDrillToUrlDisabled = disableDrillIntoURL ?? !enableDrillToUrlByDefault;
|
|
469
463
|
const availableDrillAttributes = availableDrillTargets?.attributes ?? [];
|
|
470
464
|
const drillDownDrills = isDrillDownEnabled
|
|
471
465
|
? getDrillDownDefinitionsWithPredicates(availableDrillAttributes, attributesWithHierarchyDescendants, allCatalogAttributesMap, allCatalogHierarchies, ignoredDrillDownHierarchies, backendCapabilities.supportsAttributeHierarchies)
|
|
472
466
|
: [];
|
|
473
|
-
const drillToUrlDrills = getDrillToUrlDefinitionsWithPredicates(availableDrillAttributes, attributesWithLink, []
|
|
474
|
-
return
|
|
475
|
-
? drillDownDrills
|
|
476
|
-
: [...drillDownDrills, ...drillToUrlDrills];
|
|
467
|
+
const drillToUrlDrills = getDrillToUrlDefinitionsWithPredicates(availableDrillAttributes, attributesWithLink, []);
|
|
468
|
+
return isDrillToUrlDisabled ? drillDownDrills : [...drillDownDrills, ...drillToUrlDrills];
|
|
477
469
|
}));
|
|
478
470
|
/**
|
|
479
471
|
* @internal
|