@gooddata/sdk-ui-dashboard 11.57.0-alpha.2 → 11.57.0-alpha.4
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 +4 -4
- package/esm/__version.d.ts +1 -1
- package/esm/__version.js +1 -1
- package/esm/kdaDialog/dialog/hooks/useChangeAnalysis.js +1 -1
- package/esm/model/commandHandlers/common/validateDrillToCustomUrlParams.d.ts.map +1 -1
- package/esm/model/commandHandlers/common/validateDrillToCustomUrlParams.js +6 -5
- package/esm/model/commandHandlers/dashboard/saveDashboardHandler.d.ts +1 -1
- package/esm/model/commandHandlers/dashboard/saveDashboardHandler.d.ts.map +1 -1
- package/esm/model/commandHandlers/dashboard/saveDashboardHandler.js +63 -3
- package/esm/model/commandHandlers/drill/resolveDrillToCustomUrl.d.ts +2 -3
- package/esm/model/commandHandlers/drill/resolveDrillToCustomUrl.d.ts.map +1 -1
- package/esm/model/commandHandlers/drill/resolveDrillToCustomUrl.js +23 -17
- package/esm/model/commandHandlers/widgets/validation/insightDrillDefinitionUtils.d.ts.map +1 -1
- package/esm/model/commandHandlers/widgets/validation/insightDrillDefinitionUtils.js +5 -9
- package/esm/model/react/useDashboardAsyncRender.js +2 -2
- package/esm/model/react/useDashboardCommand.js +1 -1
- package/esm/model/react/useDashboardQueryProcessing.js +1 -1
- package/esm/model/react/useDispatchDashboardCommand.js +1 -1
- package/esm/model/react/useInitializeDashboardStore.js +1 -1
- package/esm/model/react/useWidgetFilters.js +7 -7
- package/esm/model/store/insights/insightsSelectors.d.ts +18 -0
- package/esm/model/store/insights/insightsSelectors.d.ts.map +1 -1
- package/esm/model/store/insights/insightsSelectors.js +51 -2
- package/esm/model/store/tabs/index.d.ts +12 -0
- package/esm/model/store/tabs/index.d.ts.map +1 -1
- package/esm/model/store/tabs/layout/layoutReducers.d.ts +36 -30
- package/esm/model/store/tabs/layout/layoutReducers.d.ts.map +1 -1
- package/esm/model/store/tabs/layout/layoutReducers.js +19 -0
- package/esm/model/store/tabs/layout/layoutSelectors.d.ts +17 -0
- package/esm/model/store/tabs/layout/layoutSelectors.d.ts.map +1 -1
- package/esm/model/store/tabs/layout/layoutSelectors.js +30 -1
- package/esm/model/store/ui/index.d.ts +3 -0
- package/esm/model/store/ui/index.d.ts.map +1 -1
- package/esm/model/store/ui/uiReducers.d.ts +3 -0
- package/esm/model/store/ui/uiReducers.d.ts.map +1 -1
- package/esm/model/store/ui/uiReducers.js +13 -0
- package/esm/model/store/ui/uiSelectors.d.ts +8 -0
- package/esm/model/store/ui/uiSelectors.d.ts.map +1 -1
- package/esm/model/store/ui/uiSelectors.js +8 -0
- package/esm/model/store/ui/uiState.d.ts +4 -0
- package/esm/model/store/ui/uiState.d.ts.map +1 -1
- package/esm/model/store/ui/uiState.js +4 -0
- package/esm/presentation/automations/alerting/DefaultAlertingDialog/DefaultAlertingDialogAttribute.js +1 -1
- package/esm/presentation/automations/alerting/blocks/AlertingDialogFieldLabelWithTooltip.d.ts.map +1 -1
- package/esm/presentation/automations/alerting/blocks/AlertingDialogFieldLabelWithTooltip.js +1 -1
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useElementHeightSnapshot.js +1 -1
- package/esm/presentation/automations/shared/automationFilters/components/AutomationFiltersSelect.d.ts.map +1 -1
- package/esm/presentation/automations/shared/automationFilters/components/AutomationFiltersSelect.js +1 -1
- package/esm/presentation/automations/shared/automationFilters/useAutomationFilters.js +3 -3
- package/esm/presentation/dashboard/DashboardHeader/DashboardHeader.d.ts.map +1 -1
- package/esm/presentation/dashboard/DashboardHeader/DashboardHeader.js +5 -1
- package/esm/presentation/dashboardSettingsDialog/DefaultDashboardSettingsDialog.d.ts.map +1 -1
- package/esm/presentation/dashboardSettingsDialog/DefaultDashboardSettingsDialog.js +4 -3
- package/esm/presentation/dragAndDrop/useDashboardDragScroll.js +2 -2
- package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditor.d.ts.map +1 -1
- package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditor.js +16 -23
- package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParametersSections/DashboardParametersSection.d.ts.map +1 -1
- package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParametersSections/DashboardParametersSection.js +3 -2
- package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParametersSections/DisplayFormParam.d.ts.map +1 -1
- package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParametersSections/DisplayFormParam.js +2 -1
- package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParametersSections/InsightParametersSection.d.ts.map +1 -1
- package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParametersSections/InsightParametersSection.js +2 -1
- package/esm/presentation/drill/utils/drillToCustomUrlUtils.d.ts.map +1 -1
- package/esm/presentation/drill/utils/drillToCustomUrlUtils.js +5 -3
- package/esm/presentation/filterBar/attributeFilter/DefaultDashboardAttributeFilter.js +1 -1
- package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/AttributesDropdown.js +1 -1
- package/esm/presentation/filterBar/attributeFilter/dashboardDropdownBody/configuration/hooks/useTitleConfiguration.js +1 -1
- package/esm/presentation/filterBar/attributeFilter/dashboardDropdownBody/configuration/limitValues/dialog/DateFiltersPage.js +1 -1
- package/esm/presentation/filterBar/filterBar/hooks/useResetFiltersButton.js +1 -1
- package/esm/presentation/filterBar/filterBar/useFiltersWithAddedPlaceholder.js +1 -1
- package/esm/presentation/flexibleLayout/DefaultDashboardLayoutRenderer/DashboardLayoutWidgetRenderer.js +1 -1
- package/esm/presentation/flexibleLayout/dragAndDrop/DragLayer.js +1 -1
- package/esm/presentation/flexibleLayout/dragAndDrop/Resize/HeightResizerHotspot.js +1 -1
- package/esm/presentation/insightList/InsightList.js +1 -1
- package/esm/presentation/insightNotSavedDialog/InsightNotSavedDialog.d.ts +5 -0
- package/esm/presentation/insightNotSavedDialog/InsightNotSavedDialog.d.ts.map +1 -0
- package/esm/presentation/insightNotSavedDialog/InsightNotSavedDialog.js +29 -0
- package/esm/presentation/localization/bundles/de-DE.localization-bundle.d.ts +1 -0
- package/esm/presentation/localization/bundles/de-DE.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/de-DE.localization-bundle.js +1 -0
- package/esm/presentation/localization/bundles/en-AU.localization-bundle.d.ts +1 -0
- package/esm/presentation/localization/bundles/en-AU.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/en-AU.localization-bundle.js +1 -0
- package/esm/presentation/localization/bundles/en-GB.localization-bundle.d.ts +1 -0
- package/esm/presentation/localization/bundles/en-GB.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/en-GB.localization-bundle.js +1 -0
- package/esm/presentation/localization/bundles/en-US.localization-bundle.d.ts +20 -0
- package/esm/presentation/localization/bundles/en-US.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/en-US.localization-bundle.js +22 -2
- package/esm/presentation/localization/bundles/es-419.localization-bundle.d.ts +1 -0
- package/esm/presentation/localization/bundles/es-419.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/es-419.localization-bundle.js +1 -0
- package/esm/presentation/localization/bundles/es-ES.localization-bundle.d.ts +1 -0
- package/esm/presentation/localization/bundles/es-ES.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/es-ES.localization-bundle.js +1 -0
- package/esm/presentation/localization/bundles/fi-FI.localization-bundle.d.ts +1 -0
- package/esm/presentation/localization/bundles/fi-FI.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/fi-FI.localization-bundle.js +1 -0
- package/esm/presentation/localization/bundles/fr-CA.localization-bundle.d.ts +1 -0
- package/esm/presentation/localization/bundles/fr-CA.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/fr-CA.localization-bundle.js +1 -0
- package/esm/presentation/localization/bundles/fr-FR.localization-bundle.d.ts +1 -0
- package/esm/presentation/localization/bundles/fr-FR.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/fr-FR.localization-bundle.js +1 -0
- package/esm/presentation/localization/bundles/id-ID.localization-bundle.d.ts +1 -0
- package/esm/presentation/localization/bundles/id-ID.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/id-ID.localization-bundle.js +1 -0
- package/esm/presentation/localization/bundles/it-IT.localization-bundle.d.ts +1 -0
- package/esm/presentation/localization/bundles/it-IT.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/it-IT.localization-bundle.js +1 -0
- package/esm/presentation/localization/bundles/ja-JP.localization-bundle.d.ts +1 -0
- package/esm/presentation/localization/bundles/ja-JP.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/ja-JP.localization-bundle.js +1 -0
- package/esm/presentation/localization/bundles/ko-KR.localization-bundle.d.ts +1 -0
- package/esm/presentation/localization/bundles/ko-KR.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/ko-KR.localization-bundle.js +1 -0
- package/esm/presentation/localization/bundles/nl-NL.localization-bundle.d.ts +1 -0
- package/esm/presentation/localization/bundles/nl-NL.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/nl-NL.localization-bundle.js +1 -0
- package/esm/presentation/localization/bundles/pl-PL.localization-bundle.d.ts +1 -0
- package/esm/presentation/localization/bundles/pl-PL.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/pl-PL.localization-bundle.js +1 -0
- package/esm/presentation/localization/bundles/pt-BR.localization-bundle.d.ts +1 -0
- package/esm/presentation/localization/bundles/pt-BR.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/pt-BR.localization-bundle.js +1 -0
- package/esm/presentation/localization/bundles/pt-PT.localization-bundle.d.ts +1 -0
- package/esm/presentation/localization/bundles/pt-PT.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/pt-PT.localization-bundle.js +1 -0
- package/esm/presentation/localization/bundles/ru-RU.localization-bundle.d.ts +1 -0
- package/esm/presentation/localization/bundles/ru-RU.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/ru-RU.localization-bundle.js +2 -1
- package/esm/presentation/localization/bundles/sl-SI.localization-bundle.d.ts +1 -0
- package/esm/presentation/localization/bundles/sl-SI.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/sl-SI.localization-bundle.js +1 -0
- package/esm/presentation/localization/bundles/th-TH.localization-bundle.d.ts +1 -0
- package/esm/presentation/localization/bundles/th-TH.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/th-TH.localization-bundle.js +1 -0
- package/esm/presentation/localization/bundles/tr-TR.localization-bundle.d.ts +1 -0
- package/esm/presentation/localization/bundles/tr-TR.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/tr-TR.localization-bundle.js +1 -0
- package/esm/presentation/localization/bundles/uk-UA.localization-bundle.d.ts +1 -0
- package/esm/presentation/localization/bundles/uk-UA.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/uk-UA.localization-bundle.js +1 -0
- package/esm/presentation/localization/bundles/vi-VN.localization-bundle.d.ts +1 -0
- package/esm/presentation/localization/bundles/vi-VN.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/vi-VN.localization-bundle.js +1 -0
- package/esm/presentation/localization/bundles/zh-HK.localization-bundle.d.ts +1 -0
- package/esm/presentation/localization/bundles/zh-HK.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/zh-HK.localization-bundle.js +1 -0
- package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.d.ts +1 -0
- package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.js +1 -0
- package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.d.ts +1 -0
- package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.js +1 -0
- package/esm/presentation/saveAs/DefaultSaveAsDialog/useSaveAs.js +1 -1
- package/esm/presentation/topBar/buttonBar/button/settingButton/DefaultSettingButton.d.ts.map +1 -1
- package/esm/presentation/topBar/buttonBar/button/settingButton/DefaultSettingButton.js +1 -1
- package/esm/presentation/topBar/menuButton/useDefaultMenuItems.js +4 -4
- package/esm/presentation/widget/common/configuration/useAttributeFilterConfigurationHandling.js +5 -5
- package/esm/presentation/widget/common/configuration/useDateFilterConfigurationHandling.js +5 -5
- package/esm/presentation/widget/common/configuration/useIsSelectedDatasetHidden.js +1 -1
- package/esm/presentation/widget/common/configuration/useMeasureValueFilterConfigurationHandling.js +5 -5
- package/esm/presentation/widget/common/useCustomWidgetInsightDataView.js +3 -3
- package/esm/presentation/widget/common/useExportHandler.js +1 -1
- package/esm/presentation/widget/common/useImageExportHandler.d.ts.map +1 -1
- package/esm/presentation/widget/common/useImageExportHandler.js +2 -2
- package/esm/presentation/widget/common/useInsightExport.js +11 -11
- package/esm/presentation/widget/common/useInsightWidgetDataView.js +2 -2
- package/esm/presentation/widget/common/useRawExportHandler.js +1 -1
- package/esm/presentation/widget/common/useSlidesExportHandler.js +1 -1
- package/esm/presentation/widget/common/useWidgetHighlighting.js +1 -1
- package/esm/presentation/widget/insight/ViewModeDashboardInsight/Insight/DashboardInsight.js +6 -6
- package/esm/presentation/widget/insight/ViewModeDashboardInsight/InsightDrillDialog/DrillDialogInsight.js +1 -1
- package/esm/presentation/widget/insight/ViewModeDashboardInsight/useResolveDashboardInsightProperties.js +1 -1
- package/esm/presentation/widget/insight/configuration/DrillTargets/useInvalidAttributeDisplayFormIdentifier.d.ts.map +1 -1
- package/esm/presentation/widget/insight/configuration/DrillTargets/useInvalidAttributeDisplayFormIdentifier.js +7 -6
- package/esm/presentation/widget/insight/configuration/DrillTargets/useInvalidFilteringParametersIdentifiers.d.ts.map +1 -1
- package/esm/presentation/widget/insight/configuration/DrillTargets/useInvalidFilteringParametersIdentifiers.js +16 -12
- package/esm/presentation/widget/insight/configuration/InsightDrillConfigPanel/useInsightDrillConfigPanel.js +2 -2
- package/esm/presentation/widget/visualizationSwitcher/configuration/Toolbar.js +2 -2
- package/esm/presentation/widget/visualizationSwitcher/configuration/VisualizationsList/VisualizationListMenu.js +2 -2
- package/esm/presentation/widget/widget/DashboardWidget.js +1 -1
- package/esm/presentation/widget/widget/DefaultDashboardWidget.js +1 -1
- package/esm/presentation/widget/widget/InsightWidget/useInsightMenu.js +1 -1
- package/esm/sdk-ui-dashboard.d.ts +19 -0
- package/package.json +23 -24
- package/styles/css/insightsNotSavedDialog.css +26 -0
- package/styles/css/insightsNotSavedDialog.css.map +1 -0
- package/styles/css/main.css +27 -2
- package/styles/css/main.css.map +1 -1
- package/styles/scss/insightsNotSavedDialog.scss +26 -0
- package/styles/scss/main.scss +1 -0
package/NOTICE
CHANGED
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
|
|
8
8
|
The following 3rd-party software packages may be used by or distributed with gooddata-ui-sdk. Any information relevant to third-party vendors listed below are collected using common, reasonable means.
|
|
9
9
|
|
|
10
|
-
Date generated: 2026-9-
|
|
10
|
+
Date generated: 2026-9-14
|
|
11
11
|
|
|
12
|
-
Revision ID:
|
|
12
|
+
Revision ID: b22f44aea3e618f71ec62f6853d9310a210cb741
|
|
13
13
|
|
|
14
14
|
================================================================================
|
|
15
15
|
================================================================================
|
|
@@ -22305,7 +22305,7 @@ MIT
|
|
|
22305
22305
|
|
|
22306
22306
|
Authors: ljharb@gmail.com
|
|
22307
22307
|
Package Manager: NPM
|
|
22308
|
-
Project URL: https://
|
|
22308
|
+
Project URL: https://github.com/ljharb/call-bind#readme
|
|
22309
22309
|
Package Download URL: https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz
|
|
22310
22310
|
Dependency Path: @formatjs/cli-lib > @formatjs/ts-transformer > @types/json-stable-stringify > json-stable-stringify > call-bind > @formatjs/cli-lib > @formatjs/ts-transformer > json-stable-stringify > call-bind > @formatjs/cli-lib > @types/json-stable-stringify > json-stable-stringify > call-bind > @formatjs/cli-lib > json-stable-stringify > call-bind > json-stable-stringify > call-bind
|
|
22311
22311
|
File Path(s): common/config/subspaces/sdk/pnpm-lock.yaml
|
|
@@ -64353,4 +64353,4 @@ File Path(s): common/config/subspaces/sdk/pnpm-lock.yaml
|
|
|
64353
64353
|
--------------------------------------------------------------------------------
|
|
64354
64354
|
--------------------------------------------------------------------------------
|
|
64355
64355
|
|
|
64356
|
-
Report Generated by FOSSA on 2026-9-
|
|
64356
|
+
Report Generated by FOSSA on 2026-9-14
|
package/esm/__version.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const LIB_VERSION = "11.57.0-alpha.
|
|
1
|
+
export declare const LIB_VERSION = "11.57.0-alpha.4";
|
|
2
2
|
export declare const LIB_DESCRIPTION = "GoodData SDK - Dashboard Component";
|
|
3
3
|
export declare const LIB_NAME = "@gooddata/sdk-ui-dashboard";
|
|
4
4
|
//# sourceMappingURL=__version.d.ts.map
|
package/esm/__version.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// (C) 2021 GoodData Corporation
|
|
2
2
|
// DO NOT CHANGE THIS FILE, IT IS RE-GENERATED ON EVERY BUILD
|
|
3
|
-
export const LIB_VERSION = "11.57.0-alpha.
|
|
3
|
+
export const LIB_VERSION = "11.57.0-alpha.4";
|
|
4
4
|
export const LIB_DESCRIPTION = "GoodData SDK - Dashboard Component";
|
|
5
5
|
export const LIB_NAME = "@gooddata/sdk-ui-dashboard";
|
|
@@ -15,7 +15,7 @@ export function useChangeAnalysis() {
|
|
|
15
15
|
const definition = state.definition;
|
|
16
16
|
const attributes = useMemo(() => {
|
|
17
17
|
return state.selectedAttributes;
|
|
18
|
-
//
|
|
18
|
+
// oxlint-disable-next-line react-hooks/exhaustive-deps
|
|
19
19
|
}, [state.selectedUpdated]);
|
|
20
20
|
const filters = useRelevantFilters();
|
|
21
21
|
const measureValueFilters = state.measureValueFilters;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validateDrillToCustomUrlParams.d.ts","sourceRoot":"","sources":["../../../../src/model/commandHandlers/common/validateDrillToCustomUrlParams.ts"],"names":[],"mappings":"AAKA,OAAO,EAGH,KAAK,iBAAiB,EAEtB,KAAK,cAAc,
|
|
1
|
+
{"version":3,"file":"validateDrillToCustomUrlParams.d.ts","sourceRoot":"","sources":["../../../../src/model/commandHandlers/common/validateDrillToCustomUrlParams.ts"],"names":[],"mappings":"AAKA,OAAO,EAGH,KAAK,iBAAiB,EAEtB,KAAK,cAAc,EAUtB,MAAM,qBAAqB,CAAC;AAmB7B,UAAU,kBAAkB;IACxB,MAAM,EAAE,cAAc,CAAC;IACvB,aAAa,EAAE,iBAAiB,EAAE,CAAC;CACtC;AAGD,wBAAiB,8BAA8B,CAAC,OAAO,EAAE,cAAc,EAAE;;;;;;;;;gCAYxE"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// (C) 2022-2026 GoodData Corporation
|
|
2
2
|
import { all, call, put, select } from "redux-saga/effects";
|
|
3
|
-
import { areObjRefsEqual, dashboardAttributeFilterItemToAttributeFilter, filterObjRef,
|
|
3
|
+
import { areObjRefsEqual, dashboardAttributeFilterItemToAttributeFilter, filterObjRef, isArbitraryAttributeFilter, isAttributeFilter, isDrillToCustomUrl, isMatchAttributeFilter, isNegativeAttributeFilter, widgetRef, } from "@gooddata/sdk-model";
|
|
4
|
+
import { displayFormPlaceholderRef } from "@gooddata/sdk-model/internal";
|
|
4
5
|
import { queryWidgetFilters } from "../../queries/widgets.js";
|
|
5
6
|
import { query } from "../../store/_infra/queryCall.js";
|
|
6
7
|
import { selectAllCatalogDisplayFormsMap } from "../../store/catalog/catalogSelectors.js";
|
|
@@ -84,7 +85,7 @@ function sanitizeAttributeFilter(filter, displayFormMap) {
|
|
|
84
85
|
...filter,
|
|
85
86
|
negativeAttributeFilter: {
|
|
86
87
|
...filter.negativeAttributeFilter,
|
|
87
|
-
displayForm:
|
|
88
|
+
displayForm: displayFormPlaceholderRef(displayForm),
|
|
88
89
|
},
|
|
89
90
|
};
|
|
90
91
|
}
|
|
@@ -93,7 +94,7 @@ function sanitizeAttributeFilter(filter, displayFormMap) {
|
|
|
93
94
|
...filter,
|
|
94
95
|
arbitraryAttributeFilter: {
|
|
95
96
|
...filter.arbitraryAttributeFilter,
|
|
96
|
-
displayForm:
|
|
97
|
+
displayForm: displayFormPlaceholderRef(displayForm),
|
|
97
98
|
},
|
|
98
99
|
};
|
|
99
100
|
}
|
|
@@ -102,7 +103,7 @@ function sanitizeAttributeFilter(filter, displayFormMap) {
|
|
|
102
103
|
...filter,
|
|
103
104
|
matchAttributeFilter: {
|
|
104
105
|
...filter.matchAttributeFilter,
|
|
105
|
-
displayForm:
|
|
106
|
+
displayForm: displayFormPlaceholderRef(displayForm),
|
|
106
107
|
},
|
|
107
108
|
};
|
|
108
109
|
}
|
|
@@ -111,7 +112,7 @@ function sanitizeAttributeFilter(filter, displayFormMap) {
|
|
|
111
112
|
...filter,
|
|
112
113
|
positiveAttributeFilter: {
|
|
113
114
|
...filter.positiveAttributeFilter,
|
|
114
|
-
displayForm:
|
|
115
|
+
displayForm: displayFormPlaceholderRef(displayForm),
|
|
115
116
|
},
|
|
116
117
|
};
|
|
117
118
|
}
|
|
@@ -6,5 +6,5 @@ import { type DashboardContext } from "../../types/commonTypes.js";
|
|
|
6
6
|
import { type ExtendedDashboardWidget } from "../../types/layoutTypes.js";
|
|
7
7
|
export declare function getDashboardWithSharing(dashboard: IDashboardDefinition, sharingSupported: boolean | undefined, isNewDashboard: boolean): IDashboardDefinition;
|
|
8
8
|
export declare function processLayout(layout: IDashboardLayout<ExtendedDashboardWidget>): IDashboardLayout;
|
|
9
|
-
export declare function saveDashboardHandler(ctx: DashboardContext, cmd: ISaveDashboard): SagaIterator<DashboardSaved>;
|
|
9
|
+
export declare function saveDashboardHandler(ctx: DashboardContext, cmd: ISaveDashboard): SagaIterator<DashboardSaved | undefined>;
|
|
10
10
|
//# sourceMappingURL=saveDashboardHandler.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"saveDashboardHandler.d.ts","sourceRoot":"","sources":["../../../../src/model/commandHandlers/dashboard/saveDashboardHandler.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAK/C,OAAO,EAGH,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,
|
|
1
|
+
{"version":3,"file":"saveDashboardHandler.d.ts","sourceRoot":"","sources":["../../../../src/model/commandHandlers/dashboard/saveDashboardHandler.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAK/C,OAAO,EAGH,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EAWxB,MAAM,qBAAqB,CAAC;AAS7B,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAGlE,OAAO,EAAE,KAAK,cAAc,EAAkB,MAAM,2BAA2B,CAAC;AAkChF,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,KAAK,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AA2J1E,wBAAgB,uBAAuB,CACnC,SAAS,EAAE,oBAAoB,EAC/B,gBAAgB,EAAE,OAAO,YAAO,EAChC,cAAc,EAAE,OAAO,GACxB,oBAAoB,CAkBtB;AAyED,wBAAgB,aAAa,CAAC,MAAM,EAAE,gBAAgB,CAAC,uBAAuB,CAAC,GAAG,gBAAgB,CAEjG;AAoUD,wBAAiB,oBAAoB,CACjC,GAAG,EAAE,gBAAgB,EACrB,GAAG,EAAE,cAAc,GACpB,YAAY,CAAC,cAAc,GAAG,SAAS,CAAC,CA+F1C"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// (C) 2021-2026 GoodData Corporation
|
|
2
2
|
import { batchActions } from "redux-batched-actions";
|
|
3
|
-
import { call, put, select } from "redux-saga/effects";
|
|
3
|
+
import { call, put, select, take } from "redux-saga/effects";
|
|
4
4
|
import { invariant } from "ts-invariant";
|
|
5
5
|
import { isUnexpectedResponseError } from "@gooddata/sdk-backend-spi";
|
|
6
|
-
import { isTempFilterContext, } from "@gooddata/sdk-model";
|
|
6
|
+
import { areObjRefsEqual, insightRef, isTempFilterContext, } from "@gooddata/sdk-model";
|
|
7
7
|
import { dashboardFilterContextIdentity } from "../../../_staging/dashboard/dashboardFilterContext.js";
|
|
8
8
|
import { dashboardLayoutRemoveIdentity, dashboardLayoutWidgetIdentityMap, } from "../../../_staging/dashboard/dashboardLayout.js";
|
|
9
9
|
import { createListedDashboard } from "../../../_staging/listedDashboard/listedDashboardUtils.js";
|
|
@@ -15,6 +15,8 @@ import { dispatchDashboardEvent } from "../../store/_infra/eventDispatcher.js";
|
|
|
15
15
|
import { accessibleDashboardsActions } from "../../store/accessibleDashboards/index.js";
|
|
16
16
|
import { selectBackendCapabilities } from "../../store/backendCapabilities/backendCapabilitiesSelectors.js";
|
|
17
17
|
import { selectLocale } from "../../store/config/configSelectors.js";
|
|
18
|
+
import { insightsActions } from "../../store/insights/index.js";
|
|
19
|
+
import { selectDraftInsightsUsedOnDashboard, selectInsights, } from "../../store/insights/insightsSelectors.js";
|
|
18
20
|
import { listedDashboardsActions } from "../../store/listedDashboards/index.js";
|
|
19
21
|
import { metaActions } from "../../store/meta/index.js";
|
|
20
22
|
import { selectDashboardDescriptor, selectPersistedDashboard } from "../../store/meta/metaSelectors.js";
|
|
@@ -25,15 +27,52 @@ import { selectDateFilterConfigOverridesByTab } from "../../store/tabs/dateFilte
|
|
|
25
27
|
import { selectDateFilterConfigsOverridesByTab } from "../../store/tabs/dateFilterConfigs/dateFilterConfigsSelectors.js";
|
|
26
28
|
import { selectFilterContextStatesByTab } from "../../store/tabs/filterContext/filterContextSelectors.js";
|
|
27
29
|
import { tabsActions } from "../../store/tabs/index.js";
|
|
28
|
-
import { filterOutCustomWidgets, selectBasicLayoutByTab } from "../../store/tabs/layout/layoutSelectors.js";
|
|
30
|
+
import { filterOutCustomWidgets, selectAllInsightWidgetRefsByTab, selectBasicLayoutByTab, } from "../../store/tabs/layout/layoutSelectors.js";
|
|
29
31
|
import { selectMeasureValueFilterConfigsOverridesByTab } from "../../store/tabs/measureValueFilterConfigs/measureValueFilterConfigsSelectors.js";
|
|
30
32
|
import { selectSmartPersistedTabsParameters } from "../../store/tabs/parameters/parametersSelectors.js";
|
|
31
33
|
import { selectTabs } from "../../store/tabs/tabsSelectors.js";
|
|
32
34
|
import { DEFAULT_TAB_ID } from "../../store/tabs/tabsState.js";
|
|
35
|
+
import { uiActions } from "../../store/ui/index.js";
|
|
36
|
+
import { selectIsInsightNotSavedDialogOpen, selectIsInsightNotSavedDialogSaveConfirmed, } from "../../store/ui/uiSelectors.js";
|
|
33
37
|
import { isTemporaryIdentity } from "../../utils/dashboardItemUtils.js";
|
|
34
38
|
import { generateTabLocalIdentifier } from "../../utils/tabLocalIdentifier.js";
|
|
35
39
|
import { changeRenderModeHandler } from "../renderMode/changeRenderModeHandler.js";
|
|
36
40
|
import { switchDashboardTabHandler } from "../tabs/switchDashboardTabHandler.js";
|
|
41
|
+
function* persistDraftInsights(ctx, cmd, insights) {
|
|
42
|
+
for (const draftInsight of insights) {
|
|
43
|
+
const persistedInsight = yield call(async () => {
|
|
44
|
+
return ctx.backend.workspace(ctx.workspace).insights().createInsight(draftInsight, false);
|
|
45
|
+
});
|
|
46
|
+
const persistedInsightWithDraftState = {
|
|
47
|
+
...persistedInsight,
|
|
48
|
+
insight: {
|
|
49
|
+
...persistedInsight.insight,
|
|
50
|
+
isDraft: false,
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
const currentInsights = yield select(selectInsights);
|
|
54
|
+
const updatedInsights = currentInsights.map((insight) => {
|
|
55
|
+
if (areObjRefsEqual(insightRef(insight), insightRef(draftInsight))) {
|
|
56
|
+
return persistedInsightWithDraftState;
|
|
57
|
+
}
|
|
58
|
+
return insight;
|
|
59
|
+
});
|
|
60
|
+
const widgetRefsWithDraftInsightByTab = yield select(selectAllInsightWidgetRefsByTab(insightRef(draftInsight)));
|
|
61
|
+
for (const { tabId, widgetRef } of widgetRefsWithDraftInsightByTab) {
|
|
62
|
+
yield put(tabsActions.replaceInsightWidgetInsightForTab({
|
|
63
|
+
tabId,
|
|
64
|
+
ref: widgetRef,
|
|
65
|
+
insightRef: insightRef(persistedInsightWithDraftState),
|
|
66
|
+
properties: undefined,
|
|
67
|
+
header: undefined,
|
|
68
|
+
undo: {
|
|
69
|
+
cmd,
|
|
70
|
+
},
|
|
71
|
+
}));
|
|
72
|
+
}
|
|
73
|
+
yield put(insightsActions.setInsights(updatedInsights));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
37
76
|
function createDashboard(ctx, saveCtx) {
|
|
38
77
|
return ctx.backend
|
|
39
78
|
.workspace(ctx.workspace)
|
|
@@ -349,7 +388,28 @@ function* save(ctx, saveCtx, saveFn, saveActionName) {
|
|
|
349
388
|
}
|
|
350
389
|
export function* saveDashboardHandler(ctx, cmd) {
|
|
351
390
|
try {
|
|
391
|
+
const isInsightNotSavedDialogSaveConfirmed = yield select(selectIsInsightNotSavedDialogSaveConfirmed);
|
|
392
|
+
const draftInsightsOnDashboard = yield select(selectDraftInsightsUsedOnDashboard);
|
|
393
|
+
let shouldPersistDraftInsights = isInsightNotSavedDialogSaveConfirmed;
|
|
394
|
+
if (draftInsightsOnDashboard.length > 0 && !shouldPersistDraftInsights) {
|
|
395
|
+
yield put(uiActions.openInsightNotSavedDialog());
|
|
396
|
+
const draftInsightDialogAction = yield take([
|
|
397
|
+
uiActions.confirmInsightNotSavedDialogSubmit.type,
|
|
398
|
+
uiActions.closeInsightNotSavedDialog.type,
|
|
399
|
+
]);
|
|
400
|
+
if (draftInsightDialogAction.type === uiActions.closeInsightNotSavedDialog.type) {
|
|
401
|
+
return undefined;
|
|
402
|
+
}
|
|
403
|
+
shouldPersistDraftInsights = true;
|
|
404
|
+
}
|
|
352
405
|
yield put(savingActions.setSavingStart());
|
|
406
|
+
const isInsightNotSavedDialogOpen = yield select(selectIsInsightNotSavedDialogOpen);
|
|
407
|
+
if (isInsightNotSavedDialogOpen) {
|
|
408
|
+
yield put(uiActions.closeInsightNotSavedDialog());
|
|
409
|
+
}
|
|
410
|
+
if (shouldPersistDraftInsights && draftInsightsOnDashboard.length > 0) {
|
|
411
|
+
yield call(persistDraftInsights, ctx, cmd, draftInsightsOnDashboard);
|
|
412
|
+
}
|
|
353
413
|
const persistedDashboard = yield select(selectPersistedDashboard);
|
|
354
414
|
const isNewDashboard = persistedDashboard === undefined;
|
|
355
415
|
const isAiBuilder = ctx.config?.isAiMode;
|
|
@@ -9,10 +9,10 @@ interface IDrillToUrlPlaceholderReplacement {
|
|
|
9
9
|
replaceGlobally?: boolean;
|
|
10
10
|
}
|
|
11
11
|
interface IDrillToUrlElement {
|
|
12
|
-
|
|
12
|
+
ref: ObjRef;
|
|
13
13
|
elementTitle: string | null;
|
|
14
14
|
}
|
|
15
|
-
export declare function loadElementTitle(dfRef: ObjRef,
|
|
15
|
+
export declare function loadElementTitle(dfRef: ObjRef, placeholderRef: ObjRef, attrElementUri: string, ctx: DashboardContext): SagaIterator<IDrillToUrlElement>;
|
|
16
16
|
export declare function loadSecondaryElementTitles(dfRef: ObjRef, attrElementValues: (string | null)[], ctx: DashboardContext): SagaIterator<Array<string | null>>;
|
|
17
17
|
/**
|
|
18
18
|
* @internal
|
|
@@ -23,7 +23,6 @@ export declare function splitDFToLoadingAndMapping(attributesDisplayForms: IAttr
|
|
|
23
23
|
displayFormForValueLoad: IAttributeDisplayFormMetadataObject[];
|
|
24
24
|
}>;
|
|
25
25
|
export declare function loadAttributeElementsForDrillIntersection(drillIntersectionElements: IDrillEventIntersectionElement[], attributesDisplayForms: IAttributeDisplayFormMetadataObject[], ctx: DashboardContext): SagaIterator<IDrillToUrlElement[]>;
|
|
26
|
-
export declare function getAttributeDisplayForms(projectId: string, objRefs: ObjRef[], ctx: DashboardContext): Promise<IAttributeDisplayFormMetadataObject[]>;
|
|
27
26
|
export declare function getAttributeIdentifiersReplacements(url: string, drillIntersectionElements: IDrillEventIntersectionElement[], ctx: DashboardContext): SagaIterator<IDrillToUrlPlaceholderReplacement[]>;
|
|
28
27
|
export declare function getDashboardAttributeFilterReplacements(url: string, ctx: DashboardContext): SagaIterator<IDrillToUrlPlaceholderReplacement[]>;
|
|
29
28
|
export declare function getDashboardMeasureValueFilterReplacements(url: string): SagaIterator<IDrillToUrlPlaceholderReplacement[]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolveDrillToCustomUrl.d.ts","sourceRoot":"","sources":["../../../../src/model/commandHandlers/drill/resolveDrillToCustomUrl.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAG/C,OAAO,EAEH,KAAK,4BAA4B,EACjC,KAAK,mCAAmC,EAExC,KAAK,iBAAiB,IAAI,sBAAsB,EAIhD,KAAK,2BAA2B,EAChC,KAAK,MAAM,EACX,KAAK,mBAAmB,
|
|
1
|
+
{"version":3,"file":"resolveDrillToCustomUrl.d.ts","sourceRoot":"","sources":["../../../../src/model/commandHandlers/drill/resolveDrillToCustomUrl.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAG/C,OAAO,EAEH,KAAK,4BAA4B,EACjC,KAAK,mCAAmC,EAExC,KAAK,iBAAiB,IAAI,sBAAsB,EAIhD,KAAK,2BAA2B,EAChC,KAAK,MAAM,EACX,KAAK,mBAAmB,EAwB3B,MAAM,qBAAqB,CAAC;AAU7B,OAAO,EACH,KAAK,WAAW,EAChB,KAAK,8BAA8B,EAEtC,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAgBjE,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAWnE,UAAU,iCAAiC;IACvC,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,eAAe,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,UAAU,kBAAkB;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,wBAAiB,gBAAgB,CAC7B,KAAK,EAAE,MAAM,EACb,cAAc,EAAE,MAAM,EACtB,cAAc,EAAE,MAAM,EACtB,GAAG,EAAE,gBAAgB,GACtB,YAAY,CAAC,kBAAkB,CAAC,CAYlC;AAED,wBAAiB,0BAA0B,CACvC,KAAK,EAAE,MAAM,EACb,iBAAiB,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,EACpC,GAAG,EAAE,gBAAgB,GACtB,YAAY,CAAC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CASpC;AA4BD;;GAEG;AACH,wBAAgB,wCAAwC,CACpD,yBAAyB,EAAE,8BAA8B,EAAE,EAC3D,WAAW,EAAE,mCAAmC,wEA+DnD;AAED,wBAAiB,0BAA0B,CACvC,sBAAsB,EAAE,mCAAmC,EAAE,EAC7D,GAAG,EAAE,gBAAgB,GACtB,YAAY,CAAC;IACZ,2BAA2B,EAAE,mCAAmC,EAAE,CAAC;IACnE,uBAAuB,EAAE,mCAAmC,EAAE,CAAC;CAClE,CAAC,CAuBD;AAED,wBAAiB,yCAAyC,CACtD,yBAAyB,EAAE,8BAA8B,EAAE,EAC3D,sBAAsB,EAAE,mCAAmC,EAAE,EAC7D,GAAG,EAAE,gBAAgB,GACtB,YAAY,CAAC,kBAAkB,EAAE,CAAC,CAiDpC;AAKD,wBAAiB,mCAAmC,CAChD,GAAG,EAAE,MAAM,EACX,yBAAyB,EAAE,8BAA8B,EAAE,EAC3D,GAAG,EAAE,gBAAgB,GACtB,YAAY,CAAC,iCAAiC,EAAE,CAAC,CA8CnD;AAuED,wBAAiB,uCAAuC,CACpD,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,gBAAgB,GACtB,YAAY,CAAC,iCAAiC,EAAE,CAAC,CA8BnD;AAwBD,wBAAiB,0CAA0C,CACvD,GAAG,EAAE,MAAM,GACZ,YAAY,CAAC,iCAAiC,EAAE,CAAC,CAgBnD;AAsBD,wBAAiB,wCAAwC,CACrD,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,GAClB,YAAY,CAAC,iCAAiC,EAAE,CAAC,CAgBnD;AAED,wBAAiB,qCAAqC,CAClD,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,GAClB,YAAY,CAAC,iCAAiC,EAAE,CAAC,CAkDnD;AAOD,wBAAiB,iCAAiC,CAC9C,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,gBAAgB,GACtB,YAAY,CAAC,iCAAiC,EAAE,CAAC,CAwCnD;AAYD,wBAAiB,uBAAuB,CACpC,WAAW,EAAE,sBAAsB,EACnC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,WAAW,EAClB,GAAG,EAAE,gBAAgB,EACrB,GAAG,EAAE,iBAAiB,GACvB,YAAY,CAAC,MAAM,CAAC,CA8EtB;AAMD;;GAEG;AACH,wBAAgB,4BAA4B,CACxC,MAAM,EAAE,4BAA4B,GAAG,mBAAmB,GAC3D,MAAM,CAOR;AAcD;;GAEG;AACH,wBAAgB,oCAAoC,CAChD,UAAU,EAAE,2BAA2B,EAAE,GAAG,SAAS,GACtD,MAAM,CAgBR"}
|
|
@@ -2,8 +2,8 @@
|
|
|
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, dashboardFilterObjRef, filterAttributeElements, filterObjRef,
|
|
6
|
-
import { getAttributeIdentifiersPlaceholdersFromUrl, getDashboardAttributeFilterPlaceholdersFromUrl, getDashboardMeasureValueFilterPlaceholdersFromUrl, getInsightAttributeFilterPlaceholdersFromUrl, getInsightMeasureValueFilterPlaceholdersFromUrl, } from "@gooddata/sdk-model/internal";
|
|
5
|
+
import { areObjRefsEqual, dashboardAttributeFilterItemDisplayForm, dashboardFilterObjRef, filterAttributeElements, filterObjRef, insightFilters as insightDefinitionFilters, insightId, isArbitraryAttributeFilter, isAttributeDescriptor, isAttributeElementsByValue, isAttributeFilter, isComparisonCondition, isDashboardArbitraryAttributeFilter, isDashboardAttributeFilter, isDashboardTextAttributeFilter, isIdentifierRef, isMeasureValueFilter, isNegativeAttributeFilter, isRangeCondition, isTextAttributeFilter, isUriRef, measureValueFilterConditions, measureValueFilterMeasure, } from "@gooddata/sdk-model";
|
|
6
|
+
import { displayFormPlaceholderRef, 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 { selectAllCatalogDisplayFormsMap, selectAllCatalogMeasuresMap, selectCatalogDateAttributes, } from "../../store/catalog/catalogSelectors.js";
|
|
@@ -14,12 +14,13 @@ import { selectAttributeFilterConfigsOverrides } from "../../store/tabs/attribut
|
|
|
14
14
|
import { selectFilterContextAttributeFilterItems, selectFilterContextMeasureValueFilters, } from "../../store/tabs/filterContext/filterContextSelectors.js";
|
|
15
15
|
import { selectAnalyticalWidgetByRef } from "../../store/tabs/layout/layoutSelectors.js";
|
|
16
16
|
import { DRILL_TO_URL_PLACEHOLDER } from "../../types/drillTypes.js";
|
|
17
|
+
import { resolveDisplayFormMetadata } from "../../utils/displayFormResolver.js";
|
|
17
18
|
import { dashboardMeasureValueFilterMatchesIdentifier, insightMeasureValueFilterMatchesIdentifier, } from "../../utils/measureValueFilterUtils.js";
|
|
18
19
|
import { getElementTitle, getElementsSecondaryTitles } from "./getElementTitle.js";
|
|
19
|
-
export function* loadElementTitle(dfRef,
|
|
20
|
+
export function* loadElementTitle(dfRef, placeholderRef, attrElementUri, ctx) {
|
|
20
21
|
const elementTitle = yield call(getElementTitle, ctx.workspace, dfRef, attrElementUri, ctx);
|
|
21
22
|
return {
|
|
22
|
-
|
|
23
|
+
ref: placeholderRef,
|
|
23
24
|
elementTitle,
|
|
24
25
|
};
|
|
25
26
|
}
|
|
@@ -126,35 +127,40 @@ export function* loadAttributeElementsForDrillIntersection(drillIntersectionElem
|
|
|
126
127
|
return acc;
|
|
127
128
|
}
|
|
128
129
|
acc.push({
|
|
129
|
-
|
|
130
|
+
ref: displayFormPlaceholderRef(displayForm),
|
|
130
131
|
elementTitle: attributeHeaderItem.uri,
|
|
131
132
|
});
|
|
132
133
|
return acc;
|
|
133
134
|
}, []);
|
|
134
135
|
const loadedElement = yield all(displayFormForValueLoad.reduce((acc, displayForm) => {
|
|
135
|
-
const { id: dfIdentifier, ref: dfRef } = displayForm;
|
|
136
136
|
const attributeHeaderItem = findDrillIntersectionAttributeHeaderItem(drillIntersectionElements, displayForm);
|
|
137
137
|
if (!attributeHeaderItem) {
|
|
138
138
|
return acc;
|
|
139
139
|
}
|
|
140
|
-
acc.push(call(loadElementTitle,
|
|
140
|
+
acc.push(call(loadElementTitle, displayForm.ref, displayFormPlaceholderRef(displayForm), attributeHeaderItem.uri, ctx));
|
|
141
141
|
return acc;
|
|
142
142
|
}, []));
|
|
143
143
|
return [...mappedElements, ...loadedElement];
|
|
144
144
|
}
|
|
145
145
|
const encodeParameterIfSet = (parameter) => parameter === null || parameter === undefined ? parameter : encodeURIComponent(parameter);
|
|
146
|
-
export function getAttributeDisplayForms(projectId, objRefs, ctx) {
|
|
147
|
-
return ctx.backend.workspace(projectId).attributes().getAttributeDisplayForms(objRefs);
|
|
148
|
-
}
|
|
149
146
|
export function* getAttributeIdentifiersReplacements(url, drillIntersectionElements, ctx) {
|
|
150
147
|
const attributeIdentifiersPlaceholders = getAttributeIdentifiersPlaceholdersFromUrl(url);
|
|
151
148
|
if (attributeIdentifiersPlaceholders.length === 0) {
|
|
152
149
|
return [];
|
|
153
150
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
151
|
+
// The placeholder refs carry their own type, so this resolves a label through the labels API and a
|
|
152
|
+
// computed attribute through the computedAttributes service - the labels API cannot describe one.
|
|
153
|
+
// It reads the catalog first but falls back to loading, so a computed attribute that the catalog
|
|
154
|
+
// does not carry (excluded by tags, or created after the dashboard was initialised) still resolves.
|
|
155
|
+
const { resolved, missing } = yield call(resolveDisplayFormMetadata, ctx, attributeIdentifiersPlaceholders.map(({ ref }) => ref));
|
|
156
|
+
if (missing.length > 0) {
|
|
157
|
+
console.warn("Drill to custom URL: no metadata found for attributes referenced by attribute_title placeholders; those placeholders cannot be resolved.", { missing });
|
|
158
|
+
}
|
|
159
|
+
const elements = yield call(loadAttributeElementsForDrillIntersection, drillIntersectionElements, [...resolved.values()], ctx);
|
|
160
|
+
return attributeIdentifiersPlaceholders.map(({ placeholder: toBeReplaced, ref, toBeEncoded }) => {
|
|
161
|
+
// Matched by reference, not by identifier alone: a computed attribute and a label can
|
|
162
|
+
// share an identifier, and they must not resolve to each other's element titles.
|
|
163
|
+
const elementTitle = elements.find((element) => areObjRefsEqual(element.ref, ref))?.elementTitle;
|
|
158
164
|
const replacement = toBeEncoded ? encodeParameterIfSet(elementTitle) : elementTitle;
|
|
159
165
|
return {
|
|
160
166
|
toBeReplaced,
|
|
@@ -169,7 +175,7 @@ function* resolveDashboardAttributeFilterReplacement({ placeholder: toBeReplaced
|
|
|
169
175
|
return false;
|
|
170
176
|
}
|
|
171
177
|
const df = catalogDisplayForms.get(dashboardAttributeFilterItemDisplayForm(filter));
|
|
172
|
-
return df && areObjRefsEqual(
|
|
178
|
+
return df && areObjRefsEqual(displayFormPlaceholderRef(df), ref);
|
|
173
179
|
});
|
|
174
180
|
if (textFilter && isDashboardTextAttributeFilter(textFilter)) {
|
|
175
181
|
const parsedFilter = stringifyTextFilterSelection(textFilter);
|
|
@@ -183,7 +189,7 @@ function* resolveDashboardAttributeFilterReplacement({ placeholder: toBeReplaced
|
|
|
183
189
|
const standardFilters = attributeFilters.filter(isDashboardAttributeFilter);
|
|
184
190
|
let usedFilter = standardFilters.find((filter) => {
|
|
185
191
|
const df = catalogDisplayForms.get(filter.attributeFilter.displayForm);
|
|
186
|
-
return df && areObjRefsEqual(
|
|
192
|
+
return df && areObjRefsEqual(displayFormPlaceholderRef(df), ref);
|
|
187
193
|
});
|
|
188
194
|
let attributeElementsValues = [];
|
|
189
195
|
if (usedFilter) {
|
|
@@ -288,7 +294,7 @@ export function* getInsightAttributeFilterReplacements(url, widgetRef) {
|
|
|
288
294
|
const usedFilter = insightAttributeFilters.find((filter) => {
|
|
289
295
|
const filterRef = filterObjRef(filter);
|
|
290
296
|
const df = filterRef && catalogDisplayForms.get(filterRef);
|
|
291
|
-
return df && areObjRefsEqual(
|
|
297
|
+
return df && areObjRefsEqual(displayFormPlaceholderRef(df), ref);
|
|
292
298
|
});
|
|
293
299
|
let parsedFilter;
|
|
294
300
|
if (usedFilter && isTextAttributeFilter(usedFilter)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"insightDrillDefinitionUtils.d.ts","sourceRoot":"","sources":["../../../../../src/model/commandHandlers/widgets/validation/insightDrillDefinitionUtils.ts"],"names":[],"mappings":"AAIA,OAAO,EACH,KAAK,iBAAiB,EACtB,KAAK,UAAU,EACf,KAAK,mCAAmC,EACxC,KAAK,aAAa,EAClB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EAGtB,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,KAAK,gBAAgB,EACrB,KAAK,QAAQ,EACb,KAAK,sBAAsB,EAC3B,KAAK,UAAU,EACf,KAAK,MAAM,EAYd,MAAM,qBAAqB,CAAC;AAM7B,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAQ/D,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,4CAA4C,CAAC;AAC5E,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,8CAA8C,CAAC;AAG3F,wBAAgB,6BAA6B,CACzC,eAAe,EAAE,sBAAsB,EACvC,YAAY,EAAE,sBAAsB,GACrC,sBAAsB,CA8BxB;AAED,wBAAgB,4BAA4B,CACxC,eAAe,EAAE,sBAAsB,EACvC,oBAAoB,GAAE,sBAAsB,EAAO,GACpD,OAAO,CAIT;AAED,wBAAgB,2BAA2B,CACvC,eAAe,EAAE,sBAAsB,EACvC,oBAAoB,GAAE,sBAAsB,EAAO,GACpD,sBAAsB,GAAG,SAAS,CAIpC;AAED,wBAAgB,wCAAwC,CACpD,GAAG,EAAE,UAAU,EACf,oBAAoB,GAAE,sBAAsB,EAAO,GACpD,sBAAsB,CAUxB;AAED,wBAAgB,oCAAoC,CAChD,uBAAuB,EAAE,sBAAsB,EAC/C,wBAAwB,EAAE,sBAAsB,GACjD,OAAO,CA+BT;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,aAAa,CAAC,sBAAsB,CAAC,GAAG,MAAM,EAAE,CAEzF;AAED,wBAAgB,6BAA6B,CAAC,gBAAgB,EAAE,sBAAsB,EAAE,GAAG,MAAM,EAAE,CAalG;AAED,wBAAgB,4CAA4C,CACxD,gBAAgB,EAAE,sBAAsB,EAAE,GAC3C,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"insightDrillDefinitionUtils.d.ts","sourceRoot":"","sources":["../../../../../src/model/commandHandlers/widgets/validation/insightDrillDefinitionUtils.ts"],"names":[],"mappings":"AAIA,OAAO,EACH,KAAK,iBAAiB,EACtB,KAAK,UAAU,EACf,KAAK,mCAAmC,EACxC,KAAK,aAAa,EAClB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EAGtB,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,KAAK,gBAAgB,EACrB,KAAK,QAAQ,EACb,KAAK,sBAAsB,EAC3B,KAAK,UAAU,EACf,KAAK,MAAM,EAYd,MAAM,qBAAqB,CAAC;AAM7B,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAQ/D,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,4CAA4C,CAAC;AAC5E,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,8CAA8C,CAAC;AAG3F,wBAAgB,6BAA6B,CACzC,eAAe,EAAE,sBAAsB,EACvC,YAAY,EAAE,sBAAsB,GACrC,sBAAsB,CA8BxB;AAED,wBAAgB,4BAA4B,CACxC,eAAe,EAAE,sBAAsB,EACvC,oBAAoB,GAAE,sBAAsB,EAAO,GACpD,OAAO,CAIT;AAED,wBAAgB,2BAA2B,CACvC,eAAe,EAAE,sBAAsB,EACvC,oBAAoB,GAAE,sBAAsB,EAAO,GACpD,sBAAsB,GAAG,SAAS,CAIpC;AAED,wBAAgB,wCAAwC,CACpD,GAAG,EAAE,UAAU,EACf,oBAAoB,GAAE,sBAAsB,EAAO,GACpD,sBAAsB,CAUxB;AAED,wBAAgB,oCAAoC,CAChD,uBAAuB,EAAE,sBAAsB,EAC/C,wBAAwB,EAAE,sBAAsB,GACjD,OAAO,CA+BT;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,aAAa,CAAC,sBAAsB,CAAC,GAAG,MAAM,EAAE,CAEzF;AAED,wBAAgB,6BAA6B,CAAC,gBAAgB,EAAE,sBAAsB,EAAE,GAAG,MAAM,EAAE,CAalG;AAED,wBAAgB,4CAA4C,CACxD,gBAAgB,EAAE,sBAAsB,EAAE,GAC3C,MAAM,EAAE,CAOV;AAED,wBAAgB,0CAA0C,CACtD,gBAAgB,EAAE,sBAAsB,EAAE,GAC3C,MAAM,EAAE,CAOV;AAED,MAAM,WAAW,qCAAqC;IAClD,uBAAuB,EAAE,UAAU,EAAE,CAAC;IACtC,oBAAoB,EAAE,OAAO,EAAE,CAAC;IAChC,qBAAqB,EAAE,QAAQ,EAAE,CAAC;IAClC,gBAAgB,EAAE,iBAAiB,EAAE,CAAC;IACtC,aAAa,EAAE,SAAS,CAAC,gBAAgB,CAAC,CAAC;IAC3C,WAAW,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC;IACjC,eAAe,EAAE,SAAS,CAAC,mCAAmC,CAAC,CAAC;IAChE,qBAAqB,EAAE,sBAAsB,CAAC;IAC9C,yBAAyB,EAAE,SAAS,CAAC,sBAAsB,CAAC,CAAC;IAC7D,mBAAmB,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,oBAAoB,EAAE,aAAa,EAAE,GAAG,SAAS,CAAC;CACrD;AAED,wBAAgB,8BAA8B,CAC1C,eAAe,EAAE,sBAAsB,EACvC,iBAAiB,EAAE,qCAAqC,GACzD,sBAAsB,CAkBxB;AAyMD,wBAAgB,kCAAkC,CAC9C,eAAe,EAAE,iBAAiB,EAClC,iBAAiB,EAAE,qCAAqC,GACzD,iBAAiB,CAenB;AAED,wBAAgB,qCAAqC,CACjD,eAAe,EAAE,oBAAoB,EACrC,iBAAiB,EAAE,qCAAqC,GACzD,oBAAoB,CAwCtB"}
|
|
@@ -65,9 +65,9 @@ export function extractDisplayFormIdentifiers(drillDefinitions) {
|
|
|
65
65
|
.flatMap((drillItem) => {
|
|
66
66
|
if (isDrillToCustomUrl(drillItem)) {
|
|
67
67
|
const params = getAttributeIdentifiersPlaceholdersFromUrl(drillItem.target.url);
|
|
68
|
-
//
|
|
69
|
-
//
|
|
70
|
-
return params.map((param) =>
|
|
68
|
+
// the placeholder's own ref already names the object by identifier and carries its
|
|
69
|
+
// type, which a computed attribute needs to resolve as anything other than a label
|
|
70
|
+
return params.map((param) => param.ref);
|
|
71
71
|
}
|
|
72
72
|
else {
|
|
73
73
|
return [drillItem.target.displayForm, drillItem.target.hyperlinkDisplayForm];
|
|
@@ -77,17 +77,13 @@ export function extractDisplayFormIdentifiers(drillDefinitions) {
|
|
|
77
77
|
export function extractDashboardFilterDisplayFormIdentifiers(drillDefinitions) {
|
|
78
78
|
return drillDefinitions.filter(isDrillToCustomUrl).flatMap((drillItem) => {
|
|
79
79
|
const dashboardAttributeFilterPlaceholdersFromUrl = getDashboardAttributeFilterPlaceholdersFromUrl(drillItem.target.url);
|
|
80
|
-
|
|
81
|
-
// md object has to be identifier
|
|
82
|
-
return dashboardAttributeFilterPlaceholdersFromUrl.map((param) => idRef(param.identifier, "displayForm"));
|
|
80
|
+
return dashboardAttributeFilterPlaceholdersFromUrl.map((param) => param.ref);
|
|
83
81
|
});
|
|
84
82
|
}
|
|
85
83
|
export function extractInsightFilterDisplayFormIdentifiers(drillDefinitions) {
|
|
86
84
|
return drillDefinitions.filter(isDrillToCustomUrl).flatMap((drillItem) => {
|
|
87
85
|
const insightAttributeFilterPlaceholders = getInsightAttributeFilterPlaceholdersFromUrl(drillItem.target.url);
|
|
88
|
-
|
|
89
|
-
// md object has to be identifier
|
|
90
|
-
return insightAttributeFilterPlaceholders.map((param) => idRef(param.identifier, "displayForm"));
|
|
86
|
+
return insightAttributeFilterPlaceholders.map((param) => param.ref);
|
|
91
87
|
});
|
|
92
88
|
}
|
|
93
89
|
export function validateInsightDrillDefinition(drillDefinition, validationContext) {
|
|
@@ -29,11 +29,11 @@ export const useDashboardAsyncRender = (id) => {
|
|
|
29
29
|
const resolveDashboardAsyncRender = useDispatchDashboardCommand(resolveAsyncRender);
|
|
30
30
|
const onRequestAsyncRender = useCallback(() => {
|
|
31
31
|
requestDashboardAsyncRender(id);
|
|
32
|
-
//
|
|
32
|
+
// oxlint-disable-next-line react-hooks/exhaustive-deps
|
|
33
33
|
}, [id]);
|
|
34
34
|
const onResolveAsyncRender = useCallback(() => {
|
|
35
35
|
resolveDashboardAsyncRender(id);
|
|
36
|
-
//
|
|
36
|
+
// oxlint-disable-next-line react-hooks/exhaustive-deps
|
|
37
37
|
}, [id]);
|
|
38
38
|
return {
|
|
39
39
|
onRequestAsyncRender,
|
|
@@ -54,6 +54,6 @@ export const useDashboardCommand = (commandCreator, eventHandlers, onBeforeRun)
|
|
|
54
54
|
}
|
|
55
55
|
onBeforeRun?.(command);
|
|
56
56
|
dispatch(command);
|
|
57
|
-
//
|
|
57
|
+
// oxlint-disable-next-line react-hooks/exhaustive-deps
|
|
58
58
|
}, []);
|
|
59
59
|
};
|
|
@@ -67,7 +67,7 @@ export const useDashboardQueryProcessing = ({ queryCreator, onSuccess, onError,
|
|
|
67
67
|
}
|
|
68
68
|
});
|
|
69
69
|
},
|
|
70
|
-
//
|
|
70
|
+
// oxlint-disable-next-line react-hooks/exhaustive-deps
|
|
71
71
|
[queryCreator, onSuccess, onError, onRejected, onBeforeRun]);
|
|
72
72
|
// cancel any "in-flight" queries once the parent component is unmounting to prevent react warnings
|
|
73
73
|
// about updating unmounted components
|
|
@@ -28,6 +28,6 @@ export const useDispatchDashboardCommand = (commandCreator) => {
|
|
|
28
28
|
const command = commandCreator(...args);
|
|
29
29
|
dispatch(command);
|
|
30
30
|
},
|
|
31
|
-
//
|
|
31
|
+
// oxlint-disable-next-line react-hooks/exhaustive-deps
|
|
32
32
|
[commandCreator]);
|
|
33
33
|
};
|
|
@@ -80,7 +80,7 @@ export const useInitializeDashboardStore = (props) => {
|
|
|
80
80
|
dashboardStore.store.dispatch(configActions.setIsAiMode(!!props.config?.isAiMode));
|
|
81
81
|
}
|
|
82
82
|
}, [dashboardStore, props.config?.isAiMode]);
|
|
83
|
-
//
|
|
83
|
+
// oxlint-disable-next-line react-hooks/exhaustive-deps
|
|
84
84
|
useEffect(() => {
|
|
85
85
|
if (!shallowEqualObjects(previousInitProps, currentInitProps) || !dashboardStore) {
|
|
86
86
|
if (dashboardStore) {
|
|
@@ -63,11 +63,11 @@ function useWidgetFiltersImpl(widget, insight) {
|
|
|
63
63
|
runFiltersQuery(widget.ref, insight);
|
|
64
64
|
}
|
|
65
65
|
},
|
|
66
|
-
//
|
|
66
|
+
// oxlint-disable-next-line react-hooks/exhaustive-deps
|
|
67
67
|
[
|
|
68
|
-
//
|
|
68
|
+
// oxlint-disable-next-line react-hooks/exhaustive-deps
|
|
69
69
|
safeSerializeObjRef(widget?.ref),
|
|
70
|
-
//
|
|
70
|
+
// oxlint-disable-next-line react-hooks/exhaustive-deps
|
|
71
71
|
fullFiltersDigest(nonIgnoredFilters),
|
|
72
72
|
insight,
|
|
73
73
|
nonIgnoredFiltersStatus,
|
|
@@ -152,13 +152,13 @@ function useNonIgnoredFilters(widget) {
|
|
|
152
152
|
// force ignore the insight -> this way we get only the dashboard level filters even for InsightWidgets
|
|
153
153
|
run(widget.ref, null);
|
|
154
154
|
}
|
|
155
|
-
//
|
|
155
|
+
// oxlint-disable-next-line react-hooks/exhaustive-deps
|
|
156
156
|
}, [
|
|
157
|
-
//
|
|
157
|
+
// oxlint-disable-next-line react-hooks/exhaustive-deps
|
|
158
158
|
safeSerializeObjRef(widget?.ref),
|
|
159
|
-
//
|
|
159
|
+
// oxlint-disable-next-line react-hooks/exhaustive-deps
|
|
160
160
|
stringify(widget?.ignoreDashboardFilters),
|
|
161
|
-
//
|
|
161
|
+
// oxlint-disable-next-line react-hooks/exhaustive-deps
|
|
162
162
|
filtersDigest(usedFilters, widgetIgnoresDateFilter, isInEditMode),
|
|
163
163
|
]);
|
|
164
164
|
const nonIgnoredFilters = useMemo(() => usedFilters.filter((filter) => {
|
|
@@ -22,12 +22,30 @@ export declare const selectInsights: (state: DashboardState) => IInsight[];
|
|
|
22
22
|
* @alpha
|
|
23
23
|
*/
|
|
24
24
|
export declare const selectInsightRefs: DashboardSelector<ObjRef[]>;
|
|
25
|
+
/**
|
|
26
|
+
* Selects refs of insights referenced by dashboard state (widgets, visualization switcher visualizations, and drills).
|
|
27
|
+
*
|
|
28
|
+
* @internal
|
|
29
|
+
*/
|
|
30
|
+
export declare const selectDashboardInsightRefs: DashboardSelector<ObjRef[]>;
|
|
25
31
|
/**
|
|
26
32
|
* Selects all insights and returns them in a mapping of obj ref to the insight object.
|
|
27
33
|
*
|
|
28
34
|
* @alpha
|
|
29
35
|
*/
|
|
30
36
|
export declare const selectInsightsMap: DashboardSelector<ObjRefMap<IInsight>>;
|
|
37
|
+
/**
|
|
38
|
+
* Selects insights referenced by dashboard state (widgets, visualization switcher visualizations, and drills).
|
|
39
|
+
*
|
|
40
|
+
* @internal
|
|
41
|
+
*/
|
|
42
|
+
export declare const selectInsightsUsedOnDashboard: DashboardSelector<IInsight[]>;
|
|
43
|
+
/**
|
|
44
|
+
* Selects draft insights referenced by dashboard state (widgets, visualization switcher visualizations, and drills).
|
|
45
|
+
*
|
|
46
|
+
* @internal
|
|
47
|
+
*/
|
|
48
|
+
export declare const selectDraftInsightsUsedOnDashboard: DashboardSelector<IInsight[]>;
|
|
31
49
|
/**
|
|
32
50
|
* Selects insight used on a dashboard by its ref.
|
|
33
51
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"insightsSelectors.d.ts","sourceRoot":"","sources":["../../../../src/model/store/insights/insightsSelectors.ts"],"names":[],"mappings":"AAIA,OAAO,EAAiC,KAAK,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AAC1G,OAAO,EAEH,KAAK,QAAQ,EACb,KAAK,kBAAkB,EAEvB,KAAK,MAAM,
|
|
1
|
+
{"version":3,"file":"insightsSelectors.d.ts","sourceRoot":"","sources":["../../../../src/model/store/insights/insightsSelectors.ts"],"names":[],"mappings":"AAIA,OAAO,EAAiC,KAAK,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AAC1G,OAAO,EAEH,KAAK,QAAQ,EACb,KAAK,kBAAkB,EAEvB,KAAK,MAAM,EAad,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,KAAK,SAAS,EAAiB,MAAM,yCAAyC,CAAC;AAWxF,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAM1E;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,cAAc,uCAA4B,CAAC;AAExD;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAAE,iBAAiB,CAAC,MAAM,EAAE,CAExD,CAAC;AAQH;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,EAAE,iBAAiB,CAAC,MAAM,EAAE,CAgBlE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAAE,iBAAiB,CAAC,SAAS,CAAC,QAAQ,CAAC,CAMpE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,6BAA6B,EAAE,iBAAiB,CAAC,QAAQ,EAAE,CAoBvE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,kCAAkC,EAAE,iBAAiB,CAAC,QAAQ,EAAE,CAK5E,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,KAAK,iBAAiB,CAAC,QAAQ,GAAG,SAAS,CAK9F,CAAC;AAEP;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,KAAK,iBAAiB,CAAC,QAAQ,GAAG,SAAS,CAMpG,CAAC;AA6SP;;;;;GAKG;AACH,eAAO,MAAM,uCAAuC,EAAE,CAClD,GAAG,EAAE,MAAM,GAAG,SAAS,KACtB,iBAAiB,CAAC,yBAAyB,GAAG,SAAS,CAa3D,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,kCAAkC,EAAE,CAC7C,OAAO,EAAE,kBAAkB,GAAG,SAAS,KACtC,iBAAiB,CAAC,yBAAyB,GAAG,SAAS,CAa3D,CAAC"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
// (C) 2021-2026 GoodData Corporation
|
|
2
2
|
import { createSelector } from "@reduxjs/toolkit";
|
|
3
|
-
import { areObjRefsEqual, attributeAlias, attributeDisplayFormRef, attributeLocalId, insightAttributes, insightMeasures, insightRef, measureAlias, measureItem, measureLocalId, measureTitle, } from "@gooddata/sdk-model";
|
|
3
|
+
import { areObjRefsEqual, attributeAlias, attributeDisplayFormRef, attributeLocalId, insightAttributes, insightMeasures, insightRef, isDrillToInsight, measureAlias, measureItem, measureLocalId, measureTitle, } from "@gooddata/sdk-model";
|
|
4
4
|
import { newInsightMap } from "../../../_staging/metadata/objRefMap.js";
|
|
5
5
|
import { createMemoizedSelector } from "../_infra/selectors.js";
|
|
6
6
|
import { selectBackendCapabilities } from "../backendCapabilities/backendCapabilitiesSelectors.js";
|
|
7
7
|
import { selectCatalogAttributeDisplayForms, selectCatalogAttributesWithComputed, selectCatalogDateDatasets, selectCatalogMeasures, } from "../catalog/catalogSelectors.js";
|
|
8
8
|
import { selectLocale } from "../config/configSelectors.js";
|
|
9
|
-
import { selectWidgetByRef } from "../tabs/layout/layoutSelectors.js";
|
|
9
|
+
import { selectAllTabsInsightWidgetContexts, selectWidgetByRef } from "../tabs/layout/layoutSelectors.js";
|
|
10
10
|
import { insightsAdapter } from "./insightsEntityAdapter.js";
|
|
11
11
|
const entitySelectors = insightsAdapter.getSelectors((state) => state.insights);
|
|
12
12
|
/**
|
|
@@ -31,6 +31,28 @@ export const selectInsights = entitySelectors.selectAll;
|
|
|
31
31
|
export const selectInsightRefs = createSelector(selectInsights, (insights) => {
|
|
32
32
|
return insights.map(insightRef);
|
|
33
33
|
});
|
|
34
|
+
const addUniqueInsightRef = (insightRefs, ref) => {
|
|
35
|
+
if (!insightRefs.some((existingRef) => areObjRefsEqual(existingRef, ref))) {
|
|
36
|
+
insightRefs.push(ref);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Selects refs of insights referenced by dashboard state (widgets, visualization switcher visualizations, and drills).
|
|
41
|
+
*
|
|
42
|
+
* @internal
|
|
43
|
+
*/
|
|
44
|
+
export const selectDashboardInsightRefs = createSelector(selectAllTabsInsightWidgetContexts, (contexts) => {
|
|
45
|
+
const insightRefs = [];
|
|
46
|
+
contexts.forEach(({ widget }) => {
|
|
47
|
+
addUniqueInsightRef(insightRefs, widget.insight);
|
|
48
|
+
widget.drills.forEach((drill) => {
|
|
49
|
+
if (isDrillToInsight(drill)) {
|
|
50
|
+
addUniqueInsightRef(insightRefs, drill.target);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
return insightRefs;
|
|
55
|
+
});
|
|
34
56
|
/**
|
|
35
57
|
* Selects all insights and returns them in a mapping of obj ref to the insight object.
|
|
36
58
|
*
|
|
@@ -39,6 +61,33 @@ export const selectInsightRefs = createSelector(selectInsights, (insights) => {
|
|
|
39
61
|
export const selectInsightsMap = createSelector(selectInsights, selectBackendCapabilities, (insights, capabilities) => {
|
|
40
62
|
return newInsightMap(insights, capabilities.hasTypeScopedIdentifiers);
|
|
41
63
|
});
|
|
64
|
+
/**
|
|
65
|
+
* Selects insights referenced by dashboard state (widgets, visualization switcher visualizations, and drills).
|
|
66
|
+
*
|
|
67
|
+
* @internal
|
|
68
|
+
*/
|
|
69
|
+
export const selectInsightsUsedOnDashboard = createSelector(selectDashboardInsightRefs, selectInsightsMap, selectInsights, (insightRefs, insightsMap, insights) => {
|
|
70
|
+
return insightRefs
|
|
71
|
+
.map((ref) => {
|
|
72
|
+
return (insightsMap.get(ref) ??
|
|
73
|
+
insights.find((currentInsight) => {
|
|
74
|
+
return currentInsight.insight.ref
|
|
75
|
+
? areObjRefsEqual(currentInsight.insight.ref, ref)
|
|
76
|
+
: false;
|
|
77
|
+
}));
|
|
78
|
+
})
|
|
79
|
+
.filter((insight) => {
|
|
80
|
+
return Boolean(insight);
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
/**
|
|
84
|
+
* Selects draft insights referenced by dashboard state (widgets, visualization switcher visualizations, and drills).
|
|
85
|
+
*
|
|
86
|
+
* @internal
|
|
87
|
+
*/
|
|
88
|
+
export const selectDraftInsightsUsedOnDashboard = createSelector(selectInsightsUsedOnDashboard, (insights) => {
|
|
89
|
+
return insights.filter((insight) => insight.insight.isDraft);
|
|
90
|
+
});
|
|
42
91
|
/**
|
|
43
92
|
* Selects insight used on a dashboard by its ref.
|
|
44
93
|
*
|