@gooddata/sdk-ui-dashboard 11.62.0-alpha.2 → 11.62.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 +33 -610
- package/esm/__version.d.ts +1 -1
- package/esm/__version.js +1 -1
- package/esm/_staging/dashboard/dashboardFilterContext.d.ts.map +1 -1
- package/esm/_staging/dashboard/dashboardFilterContext.js +4 -2
- package/esm/_staging/dashboard/dashboardFilterContextValidation.js +1 -1
- package/esm/index.d.ts +5 -3
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +1 -1
- package/esm/kdaDialog/utils.d.ts.map +1 -1
- package/esm/kdaDialog/utils.js +6 -8
- package/esm/model/DashboardTester.js +2 -2
- package/esm/model/commandHandlers/dashboard/common/filterViews.d.ts +10 -2
- package/esm/model/commandHandlers/dashboard/common/filterViews.d.ts.map +1 -1
- package/esm/model/commandHandlers/dashboard/common/filterViews.js +22 -6
- package/esm/model/commandHandlers/dashboard/common/stateInitializers.d.ts.map +1 -1
- package/esm/model/commandHandlers/dashboard/common/stateInitializers.js +5 -6
- package/esm/model/commandHandlers/dashboard/exportDashboardToPdfPresentationHandler.js +1 -1
- package/esm/model/commandHandlers/dashboard/exportDashboardToPptPresentationHandler.js +1 -1
- package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/index.d.ts.map +1 -1
- package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/index.js +5 -3
- package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/loadUnavailableReferences.d.ts.map +1 -1
- package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/loadUnavailableReferences.js +2 -0
- package/esm/model/commandHandlers/dashboard/resetDashboardHandler.d.ts +5 -1
- package/esm/model/commandHandlers/dashboard/resetDashboardHandler.d.ts.map +1 -1
- package/esm/model/commandHandlers/dashboard/resetDashboardHandler.js +16 -8
- package/esm/model/commandHandlers/dashboard/saveDashboardHandler.d.ts.map +1 -1
- package/esm/model/commandHandlers/dashboard/saveDashboardHandler.js +6 -5
- package/esm/model/commandHandlers/drill/drillToDashboardHandler.d.ts.map +1 -1
- package/esm/model/commandHandlers/drill/drillToDashboardHandler.js +4 -1
- package/esm/model/commandHandlers/drill/keyDriverAnalysisHandler.d.ts.map +1 -1
- package/esm/model/commandHandlers/drill/keyDriverAnalysisHandler.js +5 -3
- package/esm/model/commandHandlers/drill/resolveDrillToCustomUrl.d.ts +21 -1
- package/esm/model/commandHandlers/drill/resolveDrillToCustomUrl.d.ts.map +1 -1
- package/esm/model/commandHandlers/drill/resolveDrillToCustomUrl.js +56 -54
- package/esm/model/commandHandlers/filterContext/attributeFilter/changeAttributeFilterSelectionHandler.d.ts.map +1 -1
- package/esm/model/commandHandlers/filterContext/attributeFilter/changeAttributeFilterSelectionHandler.js +17 -4
- package/esm/model/commandHandlers/filterContext/attributeFilter/replaceAttributeFilterItemSelectionHandler.d.ts.map +1 -1
- package/esm/model/commandHandlers/filterContext/attributeFilter/replaceAttributeFilterItemSelectionHandler.js +6 -1
- package/esm/model/commandHandlers/filterContext/attributeFilter/resolveDisplayFormMetadata.js +1 -1
- package/esm/model/commandHandlers/filterContext/changeFilterContextSelectionHandler.d.ts.map +1 -1
- package/esm/model/commandHandlers/filterContext/changeFilterContextSelectionHandler.js +188 -70
- package/esm/model/commandHandlers/filterContext/common.d.ts +14 -2
- package/esm/model/commandHandlers/filterContext/common.d.ts.map +1 -1
- package/esm/model/commandHandlers/filterContext/common.js +43 -6
- package/esm/model/commandHandlers/filterContext/dateFilter/changeDateFilterSelectionHandler.d.ts.map +1 -1
- package/esm/model/commandHandlers/filterContext/dateFilter/changeDateFilterSelectionHandler.js +13 -3
- package/esm/model/commandHandlers/filterContext/measureValueFilter/changeMeasureValueFilterConditionHandler.d.ts.map +1 -1
- package/esm/model/commandHandlers/filterContext/measureValueFilter/changeMeasureValueFilterConditionHandler.js +11 -2
- package/esm/model/commandHandlers/filterContext/measureValueFilter/changeMeasureValueFilterDimensionalityHandler.d.ts.map +1 -1
- package/esm/model/commandHandlers/filterContext/measureValueFilter/changeMeasureValueFilterDimensionalityHandler.js +3 -0
- package/esm/model/commandHandlers/layout/containerHeightSanitization.js +2 -2
- package/esm/model/commandHandlers/parameters/changeParameterValuesHandler.d.ts +10 -2
- package/esm/model/commandHandlers/parameters/changeParameterValuesHandler.d.ts.map +1 -1
- package/esm/model/commandHandlers/parameters/changeParameterValuesHandler.js +20 -3
- package/esm/model/commandHandlers/renderMode/changeRenderModeHandler.d.ts.map +1 -1
- package/esm/model/commandHandlers/renderMode/changeRenderModeHandler.js +1 -1
- package/esm/model/commandHandlers/scheduledEmail/initializeAutomationsHandler.d.ts.map +1 -1
- package/esm/model/commandHandlers/scheduledEmail/initializeAutomationsHandler.js +21 -4
- package/esm/model/commandHandlers/tabs/createDashboardTabHandler.d.ts.map +1 -1
- package/esm/model/commandHandlers/tabs/createDashboardTabHandler.js +27 -3
- package/esm/model/commands/filters.d.ts +16 -1
- package/esm/model/commands/filters.d.ts.map +1 -1
- package/esm/model/commands/filters.js +4 -3
- package/esm/model/commands/parameters.d.ts +4 -3
- package/esm/model/commands/parameters.d.ts.map +1 -1
- package/esm/model/commands/parameters.js +3 -2
- package/esm/model/react/useDasboardScheduledEmails/useDashboardScheduledEmailsCommands.js +1 -3
- package/esm/model/react/useDashboardAlerting/useDashboardAlertsCommands.js +1 -3
- package/esm/model/store/drill/drillSelectors.d.ts +6 -0
- package/esm/model/store/drill/drillSelectors.d.ts.map +1 -1
- package/esm/model/store/drill/drillSelectors.js +9 -0
- package/esm/model/store/filterViews/filterViewsReducersSelectors.d.ts +6 -0
- package/esm/model/store/filterViews/filterViewsReducersSelectors.d.ts.map +1 -1
- package/esm/model/store/filterViews/filterViewsReducersSelectors.js +12 -1
- package/esm/model/store/filtering/dashboardFilterSelectors.d.ts +6 -1
- package/esm/model/store/filtering/dashboardFilterSelectors.d.ts.map +1 -1
- package/esm/model/store/filtering/dashboardFilterSelectors.js +21 -19
- package/esm/model/store/filtering/restrictedFilterUtils.d.ts +26 -1
- package/esm/model/store/filtering/restrictedFilterUtils.d.ts.map +1 -1
- package/esm/model/store/filtering/restrictedFilterUtils.js +74 -6
- package/esm/model/store/meta/metaSelectors.d.ts +6 -0
- package/esm/model/store/meta/metaSelectors.d.ts.map +1 -1
- package/esm/model/store/meta/metaSelectors.js +14 -4
- package/esm/model/store/tabs/filterContext/filterContextReducers.d.ts +48 -0
- package/esm/model/store/tabs/filterContext/filterContextReducers.d.ts.map +1 -1
- package/esm/model/store/tabs/filterContext/filterContextReducers.js +362 -102
- package/esm/model/store/tabs/filterContext/filterContextSelectors.d.ts +74 -1
- package/esm/model/store/tabs/filterContext/filterContextSelectors.d.ts.map +1 -1
- package/esm/model/store/tabs/filterContext/filterContextSelectors.js +27 -21
- package/esm/model/store/tabs/filterContext/filterSync.d.ts +101 -0
- package/esm/model/store/tabs/filterContext/filterSync.d.ts.map +1 -0
- package/esm/model/store/tabs/filterContext/filterSync.js +361 -0
- package/esm/model/store/tabs/index.d.ts +2 -0
- package/esm/model/store/tabs/index.d.ts.map +1 -1
- package/esm/model/store/tabs/layout/layoutReducers.js +3 -3
- package/esm/model/store/tabs/parameters/parametersReducers.d.ts +5 -0
- package/esm/model/store/tabs/parameters/parametersReducers.d.ts.map +1 -1
- package/esm/model/store/tabs/parameters/parametersReducers.js +9 -5
- package/esm/model/store/tabs/tabsReducers.d.ts +6 -0
- package/esm/model/store/tabs/tabsReducers.d.ts.map +1 -1
- package/esm/model/store/tabs/tabsReducers.js +14 -6
- package/esm/model/store/tabs/tabsState.d.ts +10 -0
- package/esm/model/store/tabs/tabsState.d.ts.map +1 -1
- package/esm/model/store/tabs/tabsState.js +20 -0
- package/esm/model/store/unavailableObjects/copyBlockingReferences.d.ts +5 -3
- package/esm/model/store/unavailableObjects/copyBlockingReferences.d.ts.map +1 -1
- package/esm/model/store/unavailableObjects/copyBlockingReferences.js +9 -16
- package/esm/model/store/unavailableObjects/unavailableObjectsSelectors.d.ts +0 -16
- package/esm/model/store/unavailableObjects/unavailableObjectsSelectors.d.ts.map +1 -1
- package/esm/model/store/unavailableObjects/unavailableObjectsSelectors.js +0 -18
- package/esm/model/utils/attributeFilterMatching.d.ts +38 -0
- package/esm/model/utils/attributeFilterMatching.d.ts.map +1 -0
- package/esm/model/utils/attributeFilterMatching.js +110 -0
- package/esm/model/utils/attributeFilterSelectionTypeCompatibility.d.ts.map +1 -0
- package/esm/plugins/customizationApis/customizationBuilder.js +1 -1
- package/esm/presentation/automations/alerting/state/types.d.ts +2 -2
- package/esm/presentation/automations/alerting/state/types.d.ts.map +1 -1
- package/esm/presentation/automations/connectors/hooks/useBuildAutomationsContext.d.ts.map +1 -1
- package/esm/presentation/automations/connectors/hooks/useBuildAutomationsContext.js +7 -3
- package/esm/presentation/automations/contexts/AutomationsContext.d.ts +6 -2
- package/esm/presentation/automations/contexts/AutomationsContext.d.ts.map +1 -1
- package/esm/presentation/automations/scheduledEmail/state/types.d.ts +2 -2
- package/esm/presentation/automations/scheduledEmail/state/types.d.ts.map +1 -1
- package/esm/presentation/automations/scheduledEmail/types.d.ts +2 -2
- package/esm/presentation/automations/scheduledEmail/types.d.ts.map +1 -1
- package/esm/presentation/automations/shared/automationFilters/automationParameters.d.ts +11 -1
- package/esm/presentation/automations/shared/automationFilters/automationParameters.d.ts.map +1 -1
- package/esm/presentation/automations/shared/automationFilters/automationParameters.js +2 -0
- package/esm/presentation/automations/shared/automationFilters/components/AutomationFiltersSelect.d.ts +3 -3
- package/esm/presentation/automations/shared/automationFilters/components/AutomationFiltersSelect.d.ts.map +1 -1
- package/esm/presentation/automations/shared/automationFilters/components/AutomationFiltersSelect.js +3 -13
- package/esm/presentation/automations/shared/automationFilters/hooks/useDefaultSelectedFiltersForExistingAutomation.d.ts +1 -1
- package/esm/presentation/automations/shared/automationFilters/hooks/useDefaultSelectedFiltersForExistingAutomation.d.ts.map +1 -1
- package/esm/presentation/automations/shared/automationFilters/hooks/useDefaultSelectedFiltersForExistingAutomation.js +1 -1
- package/esm/presentation/automations/shared/automationFilters/hooks/useValidateExistingAutomationFilters.d.ts.map +1 -1
- package/esm/presentation/automations/shared/automationFilters/hooks/useValidateExistingAutomationFilters.js +1 -1
- package/esm/presentation/automations/shared/automationFilters/useAutomationAlertParameters.d.ts +2 -2
- package/esm/presentation/automations/shared/automationFilters/useAutomationAlertParameters.d.ts.map +1 -1
- package/esm/presentation/automations/shared/automationFilters/useAutomationExportParameters.d.ts +6 -2
- package/esm/presentation/automations/shared/automationFilters/useAutomationExportParameters.d.ts.map +1 -1
- package/esm/presentation/automations/shared/automationFilters/useAutomationFilters.d.ts.map +1 -1
- package/esm/presentation/automations/shared/automationFilters/useAutomationFilters.js +2 -2
- package/esm/presentation/automations/shared/automationFilters/utils.d.ts.map +1 -1
- package/esm/presentation/automations/shared/automationFilters/utils.js +8 -0
- package/esm/presentation/automations/shared/filters/conversions.d.ts +1 -1
- package/esm/presentation/automations/shared/filters/conversions.d.ts.map +1 -1
- package/esm/presentation/automations/shared/filters/conversions.js +5 -3
- package/esm/presentation/automations/shared/slots/types.d.ts +2 -2
- package/esm/presentation/automations/shared/slots/types.d.ts.map +1 -1
- package/esm/presentation/dashboardSettingsDialog/useDialogData.js +1 -1
- package/esm/presentation/filterBar/attributeFilter/DefaultDashboardAttributeFilter.d.ts.map +1 -1
- package/esm/presentation/filterBar/attributeFilter/DefaultDashboardAttributeFilter.js +1 -4
- package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/AttributesDropdown.d.ts +2 -11
- package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/AttributesDropdown.d.ts.map +1 -1
- package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/AttributesDropdown.js +17 -16
- package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/staticListItems.d.ts +11 -0
- package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/staticListItems.d.ts.map +1 -0
- package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/staticListItems.js +7 -0
- package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/useMetricDropdownItems.d.ts +2 -11
- package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/useMetricDropdownItems.d.ts.map +1 -1
- package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/useMetricDropdownItems.js +0 -6
- package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/useParameterDropdownItems.d.ts +34 -0
- package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/useParameterDropdownItems.d.ts.map +1 -0
- package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/useParameterDropdownItems.js +41 -0
- package/esm/presentation/filterBar/attributeFilter/dashboardDropdownBody/configuration/hooks/useLimitingItemsConfiguration.d.ts.map +1 -1
- package/esm/presentation/filterBar/attributeFilter/dashboardDropdownBody/configuration/hooks/useLimitingItemsConfiguration.js +4 -17
- package/esm/presentation/filterBar/attributeFilter/useDependentDateFilters.d.ts.map +1 -1
- package/esm/presentation/filterBar/attributeFilter/useDependentDateFilters.js +4 -13
- package/esm/presentation/filterBar/attributeFilter/useParentFilters.d.ts.map +1 -1
- package/esm/presentation/filterBar/attributeFilter/useParentFilters.js +3 -10
- package/esm/presentation/filterBar/filterBar/DefaultDashboardFilterGroup.d.ts.map +1 -1
- package/esm/presentation/filterBar/filterBar/DefaultDashboardFilterGroup.js +0 -9
- package/esm/presentation/filterBar/filterBar/DefaultFilterBarContainer.d.ts.map +1 -1
- package/esm/presentation/filterBar/filterBar/DefaultFilterBarContainer.js +2 -2
- package/esm/presentation/filterBar/filterBar/DefaultFilterBarItem.d.ts.map +1 -1
- package/esm/presentation/filterBar/filterBar/DefaultFilterBarItem.js +15 -3
- package/esm/presentation/filterBar/filterBar/hooks/useResetFiltersButton.d.ts.map +1 -1
- package/esm/presentation/filterBar/filterBar/hooks/useResetFiltersButton.js +4 -0
- package/esm/presentation/localization/bundles/de-DE.localization-bundle.d.ts +2 -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 +2 -0
- package/esm/presentation/localization/bundles/en-AU.localization-bundle.d.ts +2 -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 +2 -0
- package/esm/presentation/localization/bundles/en-GB.localization-bundle.d.ts +2 -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 +2 -0
- package/esm/presentation/localization/bundles/en-US.localization-bundle.d.ts +8 -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 +8 -0
- package/esm/presentation/localization/bundles/es-419.localization-bundle.d.ts +2 -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 +2 -0
- package/esm/presentation/localization/bundles/es-ES.localization-bundle.d.ts +2 -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 +2 -0
- package/esm/presentation/localization/bundles/fi-FI.localization-bundle.d.ts +2 -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 +2 -0
- package/esm/presentation/localization/bundles/fr-CA.localization-bundle.d.ts +2 -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 +2 -0
- package/esm/presentation/localization/bundles/fr-FR.localization-bundle.d.ts +2 -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 +2 -0
- package/esm/presentation/localization/bundles/id-ID.localization-bundle.d.ts +2 -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 +2 -0
- package/esm/presentation/localization/bundles/it-IT.localization-bundle.d.ts +2 -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 +2 -0
- package/esm/presentation/localization/bundles/ja-JP.localization-bundle.d.ts +2 -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 +2 -0
- package/esm/presentation/localization/bundles/ko-KR.localization-bundle.d.ts +2 -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 +2 -0
- package/esm/presentation/localization/bundles/nl-NL.localization-bundle.d.ts +2 -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 +2 -0
- package/esm/presentation/localization/bundles/pl-PL.localization-bundle.d.ts +2 -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 +2 -0
- package/esm/presentation/localization/bundles/pt-BR.localization-bundle.d.ts +2 -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 +2 -0
- package/esm/presentation/localization/bundles/pt-PT.localization-bundle.d.ts +2 -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 +2 -0
- package/esm/presentation/localization/bundles/ru-RU.localization-bundle.d.ts +2 -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 -0
- package/esm/presentation/localization/bundles/sl-SI.localization-bundle.d.ts +2 -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 +2 -0
- package/esm/presentation/localization/bundles/th-TH.localization-bundle.d.ts +2 -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 +2 -0
- package/esm/presentation/localization/bundles/tr-TR.localization-bundle.d.ts +2 -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 +2 -0
- package/esm/presentation/localization/bundles/uk-UA.localization-bundle.d.ts +2 -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 +2 -0
- package/esm/presentation/localization/bundles/vi-VN.localization-bundle.d.ts +2 -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 +2 -0
- package/esm/presentation/localization/bundles/zh-HK.localization-bundle.d.ts +2 -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 +2 -0
- package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.d.ts +2 -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 +2 -0
- package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.d.ts +2 -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 +2 -0
- package/esm/presentation/widget/insight/configuration/DrillFilters/drillFiltersConfigUtils.d.ts +2 -3
- package/esm/presentation/widget/insight/configuration/DrillFilters/drillFiltersConfigUtils.d.ts.map +1 -1
- package/esm/presentation/widget/insight/configuration/DrillFilters/drillFiltersConfigUtils.js +29 -133
- package/esm/presentation/widget/insight/configuration/DrillFilters/optionMappings/mapDashboardFilterToOption.d.ts.map +1 -1
- package/esm/presentation/widget/insight/configuration/DrillFilters/optionMappings/mapDashboardFilterToOption.js +1 -1
- package/esm/presentation/widget/insight/configuration/DrillFilters/optionMappings/mapSourceInsightFilterToOption.d.ts.map +1 -1
- package/esm/presentation/widget/insight/configuration/DrillFilters/optionMappings/mapSourceInsightFilterToOption.js +1 -1
- package/esm/presentation/widget/insight/configuration/DrillFilters/optionMappings/mapSourceMeasureFilterToOption.d.ts.map +1 -1
- package/esm/presentation/widget/insight/configuration/DrillFilters/optionMappings/mapSourceMeasureFilterToOption.js +1 -1
- package/esm/sdk-ui-dashboard.d.ts +135 -13
- package/package.json +23 -23
- package/styles/css/filterBar.css +2 -0
- package/styles/css/filterBar.css.map +1 -1
- package/styles/css/main.css +6 -0
- package/styles/css/main.css.map +1 -1
- package/styles/scss/filterBar.scss +2 -0
- package/esm/model/commandHandlers/dashboard/common/attributeFilterSelectionTypeCompatibility.d.ts.map +0 -1
- /package/esm/model/{commandHandlers/dashboard/common → utils}/attributeFilterSelectionTypeCompatibility.d.ts +0 -0
- /package/esm/model/{commandHandlers/dashboard/common → utils}/attributeFilterSelectionTypeCompatibility.js +0 -0
|
@@ -3,53 +3,100 @@ import { compact, partition, uniqBy } from "lodash-es";
|
|
|
3
3
|
import { batchActions } from "redux-batched-actions";
|
|
4
4
|
import { all, call, put, select } from "redux-saga/effects";
|
|
5
5
|
import { NotSupported } from "@gooddata/sdk-backend-spi";
|
|
6
|
-
import { areObjRefsEqual, attributeElementsIsEmpty, dashboardAttributeFilterItemDisplayForm, dashboardAttributeFilterItemFilterElementsBy, dashboardAttributeFilterItemFilterElementsByDate, dashboardAttributeFilterItemLocalIdentifier, dashboardAttributeFilterItemValidateElementsBy, dashboardFilterObjRef, dashboardMeasureValueFilterLocalIdentifier, getAttributeElementsItems, isAllTimeDashboardDateFilter, isDashboardArbitraryAttributeFilter, isDashboardAttributeFilter, isDashboardAttributeFilterItem, isDashboardCommonDateFilter, isDashboardDateFilter, isDashboardMeasureValueFilter, isDashboardTextAttributeFilter, isSingleSelectionFilter, isUriRef, objRefToString, serializeObjRef, updateAttributeElementsItems, } from "@gooddata/sdk-model";
|
|
6
|
+
import { areObjRefsEqual, attributeElementsIsEmpty, dashboardAttributeFilterItemDisplayForm, dashboardAttributeFilterItemFilterElementsBy, dashboardAttributeFilterItemFilterElementsByDate, dashboardAttributeFilterItemLocalIdentifier, dashboardAttributeFilterItemValidateElementsBy, dashboardFilterLocalIdentifier, dashboardFilterObjRef, dashboardMeasureValueFilterLocalIdentifier, getAttributeElementsItems, isAllTimeDashboardDateFilter, isDashboardArbitraryAttributeFilter, isDashboardAttributeFilter, isDashboardAttributeFilterItem, isDashboardCommonDateFilter, isDashboardDateFilter, isDashboardMeasureValueFilter, isDashboardTextAttributeFilter, isSingleSelectionFilter, isUriRef, objRefToString, serializeObjRef, updateAttributeElementsItems, } from "@gooddata/sdk-model";
|
|
7
7
|
import { dashboardFilterToFilterContextItem } from "../../../_staging/dashboard/dashboardFilterContext.js";
|
|
8
8
|
import { invalidArgumentsProvided } from "../../events/general.js";
|
|
9
9
|
import { dispatchDashboardEvent } from "../../store/_infra/eventDispatcher.js";
|
|
10
|
-
import {
|
|
10
|
+
import { selectCrossFilteringFiltersLocalIdentifiersByTab } from "../../store/drill/drillSelectors.js";
|
|
11
|
+
import { selectRestrictedDashboardFilterLocalIdentifiers, selectRestrictedDashboardFilterLocalIdentifiersForTab, } from "../../store/filtering/dashboardFilterSelectors.js";
|
|
12
|
+
import { isDashboardFilterUsingRestrictedObject } from "../../store/filtering/restrictedFilterUtils.js";
|
|
13
|
+
import { selectEnablePersistentFiltersAcrossTabs } from "../../store/meta/metaSelectors.js";
|
|
11
14
|
import { selectAttributeFilterConfigsOverrides, selectAttributeFilterConfigsOverridesByTab, selectAttributeFilterConfigsSelectionTypeMap, selectAttributeFilterConfigsSelectionTypeMapByTab, } from "../../store/tabs/attributeFilterConfigs/attributeFilterConfigsSelectors.js";
|
|
12
|
-
import {
|
|
15
|
+
import { isDisplayFormRefOf, selectAttributeFilterDisplayFormsMap, selectFilterContextAttributeFilterItems, selectFilterContextAttributeFilterItemsForTab, selectFilterContextDateFilterByDataSet, selectFilterContextDateFilterByDataSetForTab, selectFilterContextDateFiltersWithDimension, selectFilterContextDateFiltersWithDimensionForTab, selectFilterContextFilters, selectFilterContextMeasureValueFilters, selectFiltersForTab, } from "../../store/tabs/filterContext/filterContextSelectors.js";
|
|
13
16
|
import { tabsActions } from "../../store/tabs/index.js";
|
|
14
17
|
import { selectTabs } from "../../store/tabs/tabsSelectors.js";
|
|
15
18
|
import { selectUnavailableObjects } from "../../store/unavailableObjects/unavailableObjectsSelectors.js";
|
|
19
|
+
import { canApplyFilterTypeToTarget } from "../../utils/attributeFilterSelectionTypeCompatibility.js";
|
|
16
20
|
import { resolveAttributeMetadata } from "../../utils/attributeResolver.js";
|
|
17
21
|
import { resolveDisplayFormMetadata, } from "../../utils/displayFormResolver.js";
|
|
18
|
-
import { canApplyFilterTypeToTarget } from "../dashboard/common/attributeFilterSelectionTypeCompatibility.js";
|
|
19
22
|
import { resolveAndRegisterDisplayFormMetadata } from "./attributeFilter/resolveDisplayFormMetadata.js";
|
|
20
23
|
import { computedAttributesDisabledMessage, findDisabledComputedAttributeRef, } from "./attributeFilter/validation/computedAttributesEnabledValidation.js";
|
|
21
|
-
import { canApplyDateFilter, dispatchFilterContextChanged } from "./common.js";
|
|
24
|
+
import { canApplyDateFilter, captureFilterContextByTabSnapshot, dispatchFilterContextChanged, dispatchFilterContextChangedForMutatedTabs, } from "./common.js";
|
|
25
|
+
function classifyRestore(type, restoresOriginal) {
|
|
26
|
+
// A computed key is not inferred as a single-property mapped type.
|
|
27
|
+
return { [type]: restoresOriginal };
|
|
28
|
+
}
|
|
29
|
+
const RESTORE_TARGET_ORIGINAL = {
|
|
30
|
+
...classifyRestore(tabsActions.updateAttributeFilterSelection.type, true),
|
|
31
|
+
...classifyRestore(tabsActions.replaceAttributeFilterItem.type, true),
|
|
32
|
+
...classifyRestore(tabsActions.clearAttributeFiltersSelection.type, true),
|
|
33
|
+
...classifyRestore(tabsActions.upsertDateFilter.type, true),
|
|
34
|
+
...classifyRestore(tabsActions.changeMeasureValueFilterCondition.type, true),
|
|
35
|
+
...classifyRestore(tabsActions.setMeasureValueFilterDimensionality.type, true),
|
|
36
|
+
...classifyRestore(tabsActions.addAttributeFilterDisplayForm.type, false),
|
|
37
|
+
...classifyRestore(tabsActions.changeAttributeDisplayForm.type, false),
|
|
38
|
+
...classifyRestore(tabsActions.changeDisplayAsLabel.type, false),
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Reset persists one payload (the active tab's saved values). Mark the value-writing actions so
|
|
42
|
+
* other tabs restore their own originals instead of receiving that payload.
|
|
43
|
+
*/
|
|
44
|
+
function markRestoreTargetOriginal(actions, enabled) {
|
|
45
|
+
if (!enabled) {
|
|
46
|
+
return actions;
|
|
47
|
+
}
|
|
48
|
+
for (const action of actions) {
|
|
49
|
+
if (RESTORE_TARGET_ORIGINAL[action.type]) {
|
|
50
|
+
action.payload.restoreTargetOriginal = true;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return actions;
|
|
54
|
+
}
|
|
22
55
|
// Tab-aware select helpers — encapsulate the "if tab select ForTab else select" pattern.
|
|
23
56
|
// Named after the base selector they wrap.
|
|
24
|
-
|
|
57
|
+
//
|
|
58
|
+
// The attribute filter helpers see readable filters only. A restricted filter keeps its stored selection,
|
|
59
|
+
// so matching passes it over to a readable filter with the same label and resetOthers leaves it alone;
|
|
60
|
+
// an entry that addresses it exactly is dropped before matching.
|
|
61
|
+
function* selectRestrictedDashboardFilterLocalIdentifiersTabAware(tabLocalIdentifier) {
|
|
25
62
|
return tabLocalIdentifier
|
|
26
|
-
? yield select(
|
|
27
|
-
: yield select(
|
|
63
|
+
? yield select(selectRestrictedDashboardFilterLocalIdentifiersForTab(tabLocalIdentifier))
|
|
64
|
+
: yield select(selectRestrictedDashboardFilterLocalIdentifiers);
|
|
28
65
|
}
|
|
29
|
-
function*
|
|
30
|
-
|
|
31
|
-
? yield select(
|
|
32
|
-
: yield select(
|
|
66
|
+
function* selectFilterContextAttributeFilterItemsTabAware(tabLocalIdentifier) {
|
|
67
|
+
const items = tabLocalIdentifier
|
|
68
|
+
? yield select(selectFilterContextAttributeFilterItemsForTab(tabLocalIdentifier))
|
|
69
|
+
: yield select(selectFilterContextAttributeFilterItems);
|
|
70
|
+
const restrictedLocalIdentifiers = yield call(selectRestrictedDashboardFilterLocalIdentifiersTabAware, tabLocalIdentifier);
|
|
71
|
+
return items.filter((item) => !restrictedLocalIdentifiers.has(dashboardAttributeFilterItemLocalIdentifier(item) ?? ""));
|
|
33
72
|
}
|
|
34
|
-
function*
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
73
|
+
function* selectFilterContextAttributeFiltersTabAware(tabLocalIdentifier) {
|
|
74
|
+
const items = yield call(selectFilterContextAttributeFilterItemsTabAware, tabLocalIdentifier);
|
|
75
|
+
return items.filter(isDashboardAttributeFilter);
|
|
76
|
+
}
|
|
77
|
+
function* selectFilterContextAttributeFilterItemByLocalIdTabAware(localId, tabLocalIdentifier) {
|
|
78
|
+
const items = yield call(selectFilterContextAttributeFilterItemsTabAware, tabLocalIdentifier);
|
|
79
|
+
return items.find((item) => dashboardAttributeFilterItemLocalIdentifier(item) === localId);
|
|
38
80
|
}
|
|
39
81
|
function* selectFilterContextAttributeFilterByLocalIdTabAware(localId, tabLocalIdentifier) {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
: yield select(selectFilterContextAttributeFilterByLocalId(localId));
|
|
82
|
+
const filters = yield call(selectFilterContextAttributeFiltersTabAware, tabLocalIdentifier);
|
|
83
|
+
return filters.find((filter) => filter.attributeFilter.localIdentifier === localId);
|
|
43
84
|
}
|
|
44
|
-
function*
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
85
|
+
function* selectFilterContextAttributeFilterItemByDisplayFormTabAware(displayForm, tabLocalIdentifier) {
|
|
86
|
+
const items = yield call(selectFilterContextAttributeFilterItemsTabAware, tabLocalIdentifier);
|
|
87
|
+
const displayFormsMap = yield select(selectAttributeFilterDisplayFormsMap);
|
|
88
|
+
const df = displayFormsMap.get(displayForm);
|
|
89
|
+
return df
|
|
90
|
+
? items.find((item) => isDisplayFormRefOf(dashboardAttributeFilterItemDisplayForm(item), df))
|
|
91
|
+
: undefined;
|
|
48
92
|
}
|
|
49
|
-
function*
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
93
|
+
function* selectFilterContextAttributeFilterByDisplayFormTabAware(displayForm, tabLocalIdentifier) {
|
|
94
|
+
const filters = yield call(selectFilterContextAttributeFiltersTabAware, tabLocalIdentifier);
|
|
95
|
+
const displayFormsMap = yield select(selectAttributeFilterDisplayFormsMap);
|
|
96
|
+
const df = displayFormsMap.get(displayForm);
|
|
97
|
+
return df
|
|
98
|
+
? filters.find((filter) => isDisplayFormRefOf(filter.attributeFilter.displayForm, df))
|
|
99
|
+
: undefined;
|
|
53
100
|
}
|
|
54
101
|
function* selectFilterContextDateFilterByDataSetTabAware(dataSet, tabLocalIdentifier) {
|
|
55
102
|
return tabLocalIdentifier
|
|
@@ -69,7 +116,7 @@ function* selectAttributeFilterConfigsSelectionTypeMapTabAware(tabLocalIdentifie
|
|
|
69
116
|
return yield select(selectAttributeFilterConfigsSelectionTypeMap);
|
|
70
117
|
}
|
|
71
118
|
export function* changeFilterContextSelectionHandler(ctx, cmd) {
|
|
72
|
-
const { filters, resetOthers, attributeFilterConfigs = [], tabLocalIdentifier, matchByLocalIdentifier = false, } = cmd.payload;
|
|
119
|
+
const { filters, resetOthers, attributeFilterConfigs = [], tabLocalIdentifier, matchByLocalIdentifier = false, restorePerTabOriginals = false, } = cmd.payload;
|
|
73
120
|
// Validate that the target tab exists if tabLocalIdentifier is provided
|
|
74
121
|
if (tabLocalIdentifier) {
|
|
75
122
|
const tabs = yield select(selectTabs);
|
|
@@ -82,8 +129,32 @@ export function* changeFilterContextSelectionHandler(ctx, cmd) {
|
|
|
82
129
|
// Cross-filtering is always compatible with dashboard tabs now
|
|
83
130
|
// (removed the check that prevented cross-filtering without tabs)
|
|
84
131
|
const unavailableObjects = yield select(selectUnavailableObjects);
|
|
85
|
-
// A restricted
|
|
86
|
-
//
|
|
132
|
+
// A restricted filter keeps its stored selection. An entry that uses a restricted object is dropped:
|
|
133
|
+
// a restricted label is never resolved, and a restricted "For attribute" would restrict the measure
|
|
134
|
+
// value filter it is applied to. With matchByLocalIdentifier, an entry that addresses a restricted
|
|
135
|
+
// filter exactly is dropped too; a list entry addresses a filter exactly only with an equivalent
|
|
136
|
+
// display form, as its element values are valid for one display form only.
|
|
137
|
+
const restrictedLocalIdentifiers = yield call(selectRestrictedDashboardFilterLocalIdentifiersTabAware, tabLocalIdentifier);
|
|
138
|
+
const tabFilters = tabLocalIdentifier
|
|
139
|
+
? yield select(selectFiltersForTab(tabLocalIdentifier))
|
|
140
|
+
: yield select(selectFilterContextFilters);
|
|
141
|
+
const displayFormsMap = yield select(selectAttributeFilterDisplayFormsMap);
|
|
142
|
+
const addressesRestrictedFilter = (entry) => {
|
|
143
|
+
const localIdentifier = dashboardFilterLocalIdentifier(entry);
|
|
144
|
+
const target = localIdentifier && restrictedLocalIdentifiers.has(localIdentifier)
|
|
145
|
+
? tabFilters.find((filter) => dashboardFilterLocalIdentifier(filter) === localIdentifier)
|
|
146
|
+
: undefined;
|
|
147
|
+
if (isDashboardAttributeFilter(entry)) {
|
|
148
|
+
const df = displayFormsMap.get(entry.attributeFilter.displayForm);
|
|
149
|
+
return (!!df &&
|
|
150
|
+
isDashboardAttributeFilter(target) &&
|
|
151
|
+
isDisplayFormRefOf(target.attributeFilter.displayForm, df));
|
|
152
|
+
}
|
|
153
|
+
if (isDashboardAttributeFilterItem(entry)) {
|
|
154
|
+
return isDashboardAttributeFilterItem(target);
|
|
155
|
+
}
|
|
156
|
+
return isDashboardMeasureValueFilter(entry) && isDashboardMeasureValueFilter(target);
|
|
157
|
+
};
|
|
87
158
|
const normalizedFilters = compact(filters.map((filter) => {
|
|
88
159
|
if (isDashboardAttributeFilterItem(filter) ||
|
|
89
160
|
isDashboardDateFilter(filter) ||
|
|
@@ -91,8 +162,8 @@ export function* changeFilterContextSelectionHandler(ctx, cmd) {
|
|
|
91
162
|
return filter;
|
|
92
163
|
}
|
|
93
164
|
return dashboardFilterToFilterContextItem(filter, !!ctx.backend.capabilities.supportsMultipleDateFilters);
|
|
94
|
-
})).filter((filter) => !(isDashboardAttributeFilterItem(filter) &&
|
|
95
|
-
|
|
165
|
+
})).filter((filter) => !((isDashboardAttributeFilterItem(filter) || isDashboardMeasureValueFilter(filter)) &&
|
|
166
|
+
isDashboardFilterUsingRestrictedObject(filter, unavailableObjects)) && !(matchByLocalIdentifier && addressesRestrictedFilter(filter)));
|
|
96
167
|
const disabledComputedAttributeRef = yield call(findDisabledComputedAttributeRef, [
|
|
97
168
|
...normalizedFilters
|
|
98
169
|
.filter(isDashboardAttributeFilterItem)
|
|
@@ -140,11 +211,13 @@ export function* changeFilterContextSelectionHandler(ctx, cmd) {
|
|
|
140
211
|
const [[commonDateFilter], dateFiltersWithDimension] = partition(dateFilters, isDashboardCommonDateFilter);
|
|
141
212
|
const selectionTypeMap = yield call(selectAttributeFilterConfigsSelectionTypeMapTabAware, tabLocalIdentifier);
|
|
142
213
|
const [attributeFilterResult, commonDateFilterUpdateActions, dateFiltersUpdateActions, measureValueFilterUpdateActions,] = yield all([
|
|
143
|
-
call(getAttributeFiltersUpdateActions, [...attributeFilters].reverse(), textAttributeFilters, attributeFilterConfigs, resetOthers,
|
|
214
|
+
call(getAttributeFiltersUpdateActions, [...attributeFilters].reverse(), textAttributeFilters, attributeFilterConfigs, resetOthers, ctx, tabLocalIdentifier, selectionTypeMap, matchByLocalIdentifier),
|
|
144
215
|
call(getDateFilterUpdateActions, commonDateFilter, resetOthers, tabLocalIdentifier),
|
|
145
216
|
call(getDateFiltersUpdateActions, dateFiltersWithDimension, resetOthers, tabLocalIdentifier),
|
|
146
217
|
call(getMeasureValueFiltersUpdateActions, measureValueFilters, resetOthers),
|
|
147
218
|
]);
|
|
219
|
+
const enablePersistentFiltersAcrossTabs = yield select(selectEnablePersistentFiltersAcrossTabs);
|
|
220
|
+
const filterContextSnapshot = yield call(captureFilterContextByTabSnapshot);
|
|
148
221
|
// Ensure display form metadata is loaded for filters that will actually be applied.
|
|
149
222
|
// This handles the case where a default saved view changed filter types (e.g., list→text)
|
|
150
223
|
// and then local storage restores original types whose display forms weren't loaded during init.
|
|
@@ -156,13 +229,18 @@ export function* changeFilterContextSelectionHandler(ctx, cmd) {
|
|
|
156
229
|
}
|
|
157
230
|
}
|
|
158
231
|
}
|
|
159
|
-
yield put(batchActions([
|
|
232
|
+
yield put(batchActions(markRestoreTargetOriginal([
|
|
160
233
|
...attributeFilterResult.actions,
|
|
161
234
|
...commonDateFilterUpdateActions,
|
|
162
235
|
...dateFiltersUpdateActions,
|
|
163
236
|
...measureValueFilterUpdateActions,
|
|
164
|
-
]));
|
|
165
|
-
|
|
237
|
+
], restorePerTabOriginals)));
|
|
238
|
+
if (enablePersistentFiltersAcrossTabs) {
|
|
239
|
+
yield call(dispatchFilterContextChangedForMutatedTabs, ctx, cmd, filterContextSnapshot);
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
yield call(dispatchFilterContextChanged, ctx, cmd, tabLocalIdentifier);
|
|
243
|
+
}
|
|
166
244
|
}
|
|
167
245
|
function* getDashboardFilterByAttributeMatching(filterRef, resolvedDisplayForms, ctx, tabLocalIdentifier, isFilterExcluded, areDisplayFormsEquivalent = areObjRefsEqual) {
|
|
168
246
|
if (isUriRef(filterRef) && !ctx.backend.capabilities.supportsObjectUris) {
|
|
@@ -203,11 +281,15 @@ function* getDashboardFilterByDisplayAsLabelMatching(attributeFilter, attributeF
|
|
|
203
281
|
const dashboardFiltersConfigs = tabLocalIdentifier
|
|
204
282
|
? dashboardFiltersConfigsByTab[tabLocalIdentifier]
|
|
205
283
|
: dashboardFiltersConfigsForActiveTab;
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
284
|
+
// the config of a restricted filter may come first, its filter is not found
|
|
285
|
+
const matchingDashboardFilterConfigs = dashboardFiltersConfigs.filter((config) => areObjRefsEqual(config.displayAsLabel, filterRef));
|
|
286
|
+
for (const config of matchingDashboardFilterConfigs) {
|
|
287
|
+
dashboardFilter = yield call(selectFilterContextAttributeFilterByLocalIdTabAware, config.localIdentifier, tabLocalIdentifier);
|
|
288
|
+
if (dashboardFilter) {
|
|
289
|
+
break;
|
|
290
|
+
}
|
|
210
291
|
}
|
|
292
|
+
foundByDashboardFilterDisplayAsLabel = !!dashboardFilter;
|
|
211
293
|
}
|
|
212
294
|
return { foundByDisplayAsLabel, foundByDashboardFilterDisplayAsLabel, dashboardFilter };
|
|
213
295
|
}
|
|
@@ -229,17 +311,24 @@ function* findTargetFilterItemByDisplayForm(displayFormRef, tabLocalIdentifier)
|
|
|
229
311
|
const dashboardFiltersConfigs = tabLocalIdentifier
|
|
230
312
|
? dashboardFiltersConfigsByTab[tabLocalIdentifier]
|
|
231
313
|
: dashboardFiltersConfigsForActiveTab;
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
314
|
+
// the config of a restricted filter may come first, its filter is not found
|
|
315
|
+
const matchingConfigs = dashboardFiltersConfigs?.filter((config) => areObjRefsEqual(config.displayAsLabel, displayFormRef)) ??
|
|
316
|
+
[];
|
|
317
|
+
for (const config of matchingConfigs) {
|
|
318
|
+
const target = yield call(selectFilterContextAttributeFilterItemByLocalIdTabAware, config.localIdentifier, tabLocalIdentifier);
|
|
319
|
+
if (target) {
|
|
320
|
+
return target;
|
|
321
|
+
}
|
|
235
322
|
}
|
|
236
323
|
return undefined;
|
|
237
324
|
}
|
|
238
|
-
function* getAttributeFiltersUpdateActions(attributeFilters, textAttributeFilters, attributeFilterConfigs, resetOthers,
|
|
325
|
+
function* getAttributeFiltersUpdateActions(attributeFilters, textAttributeFilters, attributeFilterConfigs, resetOthers, ctx, tabLocalIdentifier, selectionTypeMap, matchByLocalIdentifier) {
|
|
239
326
|
const updateActions = [];
|
|
240
327
|
const displayFormsToResolve = [];
|
|
241
328
|
const handledLocalIds = new Set();
|
|
329
|
+
const crossFilteringLocalIdsByTab = yield select(selectCrossFilteringFiltersLocalIdentifiersByTab);
|
|
242
330
|
const resolvedDisplayForms = yield call(resolveDisplayFormMetadata, ctx, attributeFilters.map((af) => dashboardAttributeFilterItemDisplayForm(af)));
|
|
331
|
+
const enablePersistentFiltersAcrossTabs = yield select(selectEnablePersistentFiltersAcrossTabs);
|
|
243
332
|
// A payload can give a display form as a URI ref, and the dashboard can store it as an
|
|
244
333
|
// identifier ref. The two refs are equal when they point to the same display form metadata.
|
|
245
334
|
const displayFormsMap = yield select(selectAttributeFilterDisplayFormsMap);
|
|
@@ -394,6 +483,8 @@ function* getAttributeFiltersUpdateActions(attributeFilters, textAttributeFilter
|
|
|
394
483
|
updateActions.push(tabsActions.updateAttributeFilterSelection({
|
|
395
484
|
...getAttributeFilterSelectionPayload(attributeFilter, dashboardFilter),
|
|
396
485
|
tabLocalIdentifier,
|
|
486
|
+
crossFilteringLocalIdsByTab,
|
|
487
|
+
enablePersistentFiltersAcrossTabs,
|
|
397
488
|
}));
|
|
398
489
|
handledLocalIds.add(dashboardFilterLocalId);
|
|
399
490
|
}
|
|
@@ -431,20 +522,15 @@ function* getAttributeFiltersUpdateActions(attributeFilters, textAttributeFilter
|
|
|
431
522
|
if (canApplyFilterTypeToTarget("list", configSelectionType, targetTextFilter)) {
|
|
432
523
|
// Text → list: set displayAsLabel to the text filter's displayForm
|
|
433
524
|
// so the list filter visually shows the same label.
|
|
434
|
-
//
|
|
435
|
-
//
|
|
436
|
-
|
|
437
|
-
const normalizedListFilter = {
|
|
438
|
-
attributeFilter: {
|
|
439
|
-
...attributeFilter.attributeFilter,
|
|
440
|
-
localIdentifier: targetLocalId,
|
|
441
|
-
selectionMode: undefined,
|
|
442
|
-
},
|
|
443
|
-
};
|
|
525
|
+
// Strip selectionMode so the target's own config determines single/multi
|
|
526
|
+
// presentation.
|
|
527
|
+
const normalizedListFilter = fitReplacementToTarget({ attributeFilter: { ...attributeFilter.attributeFilter, selectionMode: undefined } }, targetTextFilter);
|
|
444
528
|
updateActions.push(tabsActions.replaceAttributeFilterItem({
|
|
445
529
|
filterLocalId: targetLocalId,
|
|
446
530
|
filter: normalizedListFilter,
|
|
447
531
|
tabLocalIdentifier,
|
|
532
|
+
crossFilteringLocalIdsByTab,
|
|
533
|
+
enablePersistentFiltersAcrossTabs,
|
|
448
534
|
}), tabsActions.changeDisplayAsLabel({
|
|
449
535
|
localIdentifier: targetLocalId,
|
|
450
536
|
displayAsLabel: dashboardAttributeFilterItemDisplayForm(targetTextFilter),
|
|
@@ -497,13 +583,13 @@ function* getAttributeFiltersUpdateActions(attributeFilters, textAttributeFilter
|
|
|
497
583
|
continue;
|
|
498
584
|
}
|
|
499
585
|
}
|
|
500
|
-
|
|
501
|
-
// (keyed by localId) keep matching after the replacement.
|
|
502
|
-
const normalizedTextFilter = normalizeFilterLocalIdentifier(textFilter, targetLocalId);
|
|
586
|
+
const normalizedTextFilter = fitReplacementToTarget(textFilter, existingFilter);
|
|
503
587
|
updateActions.push(tabsActions.replaceAttributeFilterItem({
|
|
504
588
|
filterLocalId: targetLocalId,
|
|
505
589
|
filter: normalizedTextFilter,
|
|
506
590
|
tabLocalIdentifier,
|
|
591
|
+
crossFilteringLocalIdsByTab,
|
|
592
|
+
enablePersistentFiltersAcrossTabs,
|
|
507
593
|
}));
|
|
508
594
|
const textDisplayForm = dashboardAttributeFilterItemDisplayForm(textFilter);
|
|
509
595
|
// List → text: update displayAsLabel to match the text filter's displayForm
|
|
@@ -522,20 +608,20 @@ function* getAttributeFiltersUpdateActions(attributeFilters, textAttributeFilter
|
|
|
522
608
|
if (resetOthers) {
|
|
523
609
|
const currentAttributeFilters = yield call(selectFilterContextAttributeFiltersTabAware, tabLocalIdentifier);
|
|
524
610
|
// for element-based filters that have not been handled, create clear selection actions
|
|
525
|
-
const unhandledFilters = currentAttributeFilters.filter((filter) => !handledLocalIds.has(dashboardAttributeFilterItemLocalIdentifier(filter))
|
|
526
|
-
!isDashboardFilterRestricted(filter, unavailableObjects));
|
|
611
|
+
const unhandledFilters = currentAttributeFilters.filter((filter) => !handledLocalIds.has(dashboardAttributeFilterItemLocalIdentifier(filter)));
|
|
527
612
|
if (unhandledFilters.length > 0) {
|
|
528
613
|
updateActions.push(tabsActions.clearAttributeFiltersSelection({
|
|
529
614
|
filterLocalIds: unhandledFilters.map((filter) => dashboardAttributeFilterItemLocalIdentifier(filter)),
|
|
530
615
|
tabLocalIdentifier,
|
|
616
|
+
crossFilteringLocalIdsByTab,
|
|
617
|
+
enablePersistentFiltersAcrossTabs,
|
|
531
618
|
}));
|
|
532
619
|
}
|
|
533
620
|
// for text filters (arbitrary/match) that have not been handled, reset to All state
|
|
534
621
|
// (negative arbitrary filter with empty selection)
|
|
535
622
|
const currentAllFilterItems = yield call(selectFilterContextAttributeFilterItemsTabAware, tabLocalIdentifier);
|
|
536
623
|
const unhandledTextFilters = currentAllFilterItems.filter((filter) => isDashboardTextAttributeFilter(filter) &&
|
|
537
|
-
!handledLocalIds.has(dashboardAttributeFilterItemLocalIdentifier(filter))
|
|
538
|
-
!isDashboardFilterRestricted(filter, unavailableObjects));
|
|
624
|
+
!handledLocalIds.has(dashboardAttributeFilterItemLocalIdentifier(filter)));
|
|
539
625
|
for (const textFilter of unhandledTextFilters) {
|
|
540
626
|
const localId = dashboardAttributeFilterItemLocalIdentifier(textFilter);
|
|
541
627
|
const resetFilter = {
|
|
@@ -553,12 +639,15 @@ function* getAttributeFiltersUpdateActions(attributeFilters, textAttributeFilter
|
|
|
553
639
|
filterLocalId: localId,
|
|
554
640
|
filter: resetFilter,
|
|
555
641
|
tabLocalIdentifier,
|
|
642
|
+
crossFilteringLocalIdsByTab,
|
|
643
|
+
enablePersistentFiltersAcrossTabs,
|
|
556
644
|
}));
|
|
557
645
|
}
|
|
558
646
|
}
|
|
559
647
|
return { actions: updateActions, displayFormsToResolve };
|
|
560
648
|
}
|
|
561
649
|
function* getDateFilterUpdateActions(dateFilter, resetOthers, tabLocalIdentifier) {
|
|
650
|
+
const enablePersistentFiltersAcrossTabs = yield select(selectEnablePersistentFiltersAcrossTabs);
|
|
562
651
|
if (dateFilter) {
|
|
563
652
|
const canApply = yield call(canApplyDateFilter, dateFilter);
|
|
564
653
|
if (!canApply) {
|
|
@@ -577,6 +666,7 @@ function* getDateFilterUpdateActions(dateFilter, resetOthers, tabLocalIdentifier
|
|
|
577
666
|
...localIdentifierObj,
|
|
578
667
|
...emptyValueHandlingObj,
|
|
579
668
|
tabLocalIdentifier,
|
|
669
|
+
enablePersistentFiltersAcrossTabs,
|
|
580
670
|
}
|
|
581
671
|
: {
|
|
582
672
|
type: dateFilter.dateFilter.type,
|
|
@@ -590,19 +680,30 @@ function* getDateFilterUpdateActions(dateFilter, resetOthers, tabLocalIdentifier
|
|
|
590
680
|
: {}),
|
|
591
681
|
...emptyValueHandlingObj,
|
|
592
682
|
tabLocalIdentifier,
|
|
683
|
+
enablePersistentFiltersAcrossTabs,
|
|
593
684
|
};
|
|
594
685
|
return [tabsActions.upsertDateFilter(upsertPayload)];
|
|
595
686
|
}
|
|
596
687
|
else if (resetOthers) {
|
|
597
|
-
return [
|
|
688
|
+
return [
|
|
689
|
+
tabsActions.upsertDateFilter({
|
|
690
|
+
type: "allTime",
|
|
691
|
+
tabLocalIdentifier,
|
|
692
|
+
enablePersistentFiltersAcrossTabs,
|
|
693
|
+
}),
|
|
694
|
+
];
|
|
598
695
|
}
|
|
599
696
|
return [];
|
|
600
697
|
}
|
|
601
698
|
function* getMeasureValueFiltersUpdateActions(measureValueFilters, resetOthers) {
|
|
602
699
|
const updateActions = [];
|
|
603
700
|
const handledLocalIds = new Set();
|
|
604
|
-
|
|
701
|
+
// a restricted filter keeps its stored conditions: it is neither matched nor reset
|
|
702
|
+
const allMeasureValueFilters = yield select(selectFilterContextMeasureValueFilters);
|
|
703
|
+
const restrictedLocalIdentifiers = yield select(selectRestrictedDashboardFilterLocalIdentifiers);
|
|
704
|
+
const currentMeasureValueFilters = allMeasureValueFilters.filter((filter) => !restrictedLocalIdentifiers.has(dashboardMeasureValueFilterLocalIdentifier(filter)));
|
|
605
705
|
const currentByLocalId = new Map(currentMeasureValueFilters.map((f) => [dashboardMeasureValueFilterLocalIdentifier(f), f]));
|
|
706
|
+
const enablePersistentFiltersAcrossTabs = yield select(selectEnablePersistentFiltersAcrossTabs);
|
|
606
707
|
for (const incoming of measureValueFilters) {
|
|
607
708
|
const incomingLocalIdentifier = dashboardMeasureValueFilterLocalIdentifier(incoming);
|
|
608
709
|
const currentFilter = currentByLocalId.get(incomingLocalIdentifier) ??
|
|
@@ -618,11 +719,13 @@ function* getMeasureValueFiltersUpdateActions(measureValueFilters, resetOthers)
|
|
|
618
719
|
updateActions.push(tabsActions.changeMeasureValueFilterCondition({
|
|
619
720
|
localIdentifier,
|
|
620
721
|
conditions: incoming.dashboardMeasureValueFilter.conditions,
|
|
722
|
+
enablePersistentFiltersAcrossTabs,
|
|
621
723
|
}));
|
|
622
724
|
if ("dimensionality" in incoming.dashboardMeasureValueFilter) {
|
|
623
725
|
updateActions.push(tabsActions.setMeasureValueFilterDimensionality({
|
|
624
726
|
localIdentifier,
|
|
625
727
|
dimensionality: incoming.dashboardMeasureValueFilter.dimensionality,
|
|
728
|
+
enablePersistentFiltersAcrossTabs,
|
|
626
729
|
}));
|
|
627
730
|
}
|
|
628
731
|
}
|
|
@@ -637,6 +740,7 @@ function* getMeasureValueFiltersUpdateActions(measureValueFilters, resetOthers)
|
|
|
637
740
|
updateActions.push(tabsActions.changeMeasureValueFilterCondition({
|
|
638
741
|
localIdentifier,
|
|
639
742
|
conditions: undefined,
|
|
743
|
+
enablePersistentFiltersAcrossTabs,
|
|
640
744
|
}));
|
|
641
745
|
}
|
|
642
746
|
}
|
|
@@ -645,6 +749,7 @@ function* getMeasureValueFiltersUpdateActions(measureValueFilters, resetOthers)
|
|
|
645
749
|
function* getDateFiltersUpdateActions(dateFilters, resetOthers, tabLocalIdentifier) {
|
|
646
750
|
const updateActions = [];
|
|
647
751
|
const handledDataSets = new Set();
|
|
752
|
+
const enablePersistentFiltersAcrossTabs = yield select(selectEnablePersistentFiltersAcrossTabs);
|
|
648
753
|
for (const dateFilter of dateFilters) {
|
|
649
754
|
const filterRef = dateFilter.dateFilter.dataSet;
|
|
650
755
|
const dashboardFilter = yield call(selectFilterContextDateFilterByDataSetTabAware, filterRef, tabLocalIdentifier);
|
|
@@ -663,6 +768,7 @@ function* getDateFiltersUpdateActions(dateFilters, resetOthers, tabLocalIdentifi
|
|
|
663
768
|
...localIdentifierObj,
|
|
664
769
|
...emptyValueHandlingObj,
|
|
665
770
|
tabLocalIdentifier,
|
|
771
|
+
enablePersistentFiltersAcrossTabs,
|
|
666
772
|
}
|
|
667
773
|
: {
|
|
668
774
|
type: dateFilter.dateFilter.type,
|
|
@@ -676,6 +782,7 @@ function* getDateFiltersUpdateActions(dateFilters, resetOthers, tabLocalIdentifi
|
|
|
676
782
|
: {}),
|
|
677
783
|
...emptyValueHandlingObj,
|
|
678
784
|
tabLocalIdentifier,
|
|
785
|
+
enablePersistentFiltersAcrossTabs,
|
|
679
786
|
};
|
|
680
787
|
updateActions.push(tabsActions.upsertDateFilter(upsertPayload));
|
|
681
788
|
}
|
|
@@ -694,6 +801,7 @@ function* getDateFiltersUpdateActions(dateFilters, resetOthers, tabLocalIdentifi
|
|
|
694
801
|
dataSet: dateFilter.dateFilter.dataSet,
|
|
695
802
|
...localIdentifierObj,
|
|
696
803
|
tabLocalIdentifier,
|
|
804
|
+
enablePersistentFiltersAcrossTabs,
|
|
697
805
|
}));
|
|
698
806
|
}
|
|
699
807
|
}
|
|
@@ -744,20 +852,30 @@ function canMapDashboardFilterFromAnotherDisplayForm(ctx) {
|
|
|
744
852
|
return ctx.backend.capabilities.supportsElementUris;
|
|
745
853
|
}
|
|
746
854
|
/**
|
|
747
|
-
*
|
|
748
|
-
*
|
|
749
|
-
*
|
|
750
|
-
*
|
|
855
|
+
* Fits a replacement to the dashboard filter it replaces. It takes the target's localIdentifier, so
|
|
856
|
+
* attributeFilterConfigs (keyed by it) keep matching, and the target's dependencies, also when the target
|
|
857
|
+
* has none: an entry's parents may name filters of another context, and such a parent could make the
|
|
858
|
+
* replaced filter restricted.
|
|
751
859
|
*/
|
|
752
|
-
function
|
|
860
|
+
function fitReplacementToTarget(filter, target) {
|
|
861
|
+
const localIdentifier = dashboardAttributeFilterItemLocalIdentifier(target);
|
|
862
|
+
const dependencies = {
|
|
863
|
+
filterElementsBy: dashboardAttributeFilterItemFilterElementsBy(target),
|
|
864
|
+
filterElementsByDate: dashboardAttributeFilterItemFilterElementsByDate(target),
|
|
865
|
+
validateElementsBy: dashboardAttributeFilterItemValidateElementsBy(target),
|
|
866
|
+
};
|
|
753
867
|
if (isDashboardAttributeFilter(filter)) {
|
|
754
868
|
return {
|
|
755
|
-
attributeFilter: { ...filter.attributeFilter, localIdentifier },
|
|
869
|
+
attributeFilter: { ...filter.attributeFilter, localIdentifier, ...dependencies },
|
|
756
870
|
};
|
|
757
871
|
}
|
|
758
872
|
if (isDashboardArbitraryAttributeFilter(filter)) {
|
|
759
873
|
return {
|
|
760
|
-
arbitraryAttributeFilter: {
|
|
874
|
+
arbitraryAttributeFilter: {
|
|
875
|
+
...filter.arbitraryAttributeFilter,
|
|
876
|
+
localIdentifier,
|
|
877
|
+
...dependencies,
|
|
878
|
+
},
|
|
761
879
|
};
|
|
762
880
|
}
|
|
763
881
|
// IDashboardMatchAttributeFilter
|
|
@@ -1,14 +1,26 @@
|
|
|
1
1
|
import { type SagaIterator } from "redux-saga";
|
|
2
|
-
import { type IDashboardDateFilter } from "@gooddata/sdk-model";
|
|
2
|
+
import { type IDashboardAttributeFilterConfig, type IDashboardDateFilter, type IFilterContextDefinition } from "@gooddata/sdk-model";
|
|
3
3
|
import { type IDashboardCommand } from "../../commands/base.js";
|
|
4
|
+
import { type IWorkingFilterContextDefinition } from "../../store/tabs/filterContext/filterContextState.js";
|
|
4
5
|
import { type DashboardContext } from "../../types/commonTypes.js";
|
|
6
|
+
/**
|
|
7
|
+
* Applied filter context and attribute filter configs of every tab, taken before a write.
|
|
8
|
+
* Compared with the store afterwards so a mirrored change emits one event per tab updated.
|
|
9
|
+
*/
|
|
10
|
+
export interface IFilterContextByTabSnapshot {
|
|
11
|
+
readonly filterContexts: Record<string, IFilterContextDefinition | undefined>;
|
|
12
|
+
readonly workingFilterContexts: Record<string, IWorkingFilterContextDefinition | undefined>;
|
|
13
|
+
readonly attributeFilterConfigs: Record<string, IDashboardAttributeFilterConfig[]>;
|
|
14
|
+
}
|
|
15
|
+
export declare function captureFilterContextByTabSnapshot(): SagaIterator<IFilterContextByTabSnapshot>;
|
|
16
|
+
export declare function dispatchFilterContextChangedForMutatedTabs(ctx: DashboardContext, cmd: IDashboardCommand, snapshot: IFilterContextByTabSnapshot): SagaIterator<void>;
|
|
5
17
|
export declare function dispatchFilterContextChanged(ctx: DashboardContext, cmd: IDashboardCommand, tabLocalIdentifier?: string): SagaIterator<void>;
|
|
6
18
|
export declare function canApplyDateFilter(dateFilter: IDashboardDateFilter): SagaIterator<boolean>;
|
|
7
19
|
export declare function resetCrossFiltering(cmd: IDashboardCommand): Generator<import("redux-saga/effects").PutEffect<import("../../commands/filters.js").IRemoveAttributeFilters> | import("redux-saga/effects").PutEffect<{
|
|
8
20
|
payload: string | undefined;
|
|
9
21
|
type: "drill/resetCrossFiltering";
|
|
10
22
|
}> | import("redux-saga/effects").SelectEffect, void, string[] & string>;
|
|
11
|
-
export declare function applyWorkingSelectionHandler(ctx: DashboardContext, cmd: IDashboardCommand): Generator<import("redux-saga/effects").CallEffect<void> | import("redux-saga/effects").PutEffect<{
|
|
23
|
+
export declare function applyWorkingSelectionHandler(ctx: DashboardContext, cmd: IDashboardCommand): Generator<import("redux-saga/effects").CallEffect<void> | import("redux-saga/effects").CallEffect<IFilterContextByTabSnapshot> | import("redux-saga/effects").PutEffect<{
|
|
12
24
|
payload: import("../../../index.js").IApplyWorkingSelectionPayload;
|
|
13
25
|
type: "tabs/applyWorkingSelection";
|
|
14
26
|
}> | import("redux-saga/effects").PutEffect<import("../../events/base.js").ICustomDashboardEvent<any> | import("../../events/base.js").IDashboardEvent<any>> | import("redux-saga/effects").SelectEffect, void, never>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../../src/model/commandHandlers/filterContext/common.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../../src/model/commandHandlers/filterContext/common.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAI/C,OAAO,EACH,KAAK,+BAA+B,EACpC,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAChC,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAuBhE,OAAO,EAAE,KAAK,+BAA+B,EAAE,MAAM,sDAAsD,CAAC;AAI5G,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAGnE;;;GAGG;AACH,MAAM,WAAW,2BAA2B;IACxC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,GAAG,SAAS,CAAC,CAAC;IAC9E,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,+BAA+B,GAAG,SAAS,CAAC,CAAC;IAC5F,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,+BAA+B,EAAE,CAAC,CAAC;CACtF;AAED,wBAAiB,iCAAiC,IAAI,YAAY,CAAC,2BAA2B,CAAC,CAU9F;AAED,wBAAiB,0CAA0C,CACvD,GAAG,EAAE,gBAAgB,EACrB,GAAG,EAAE,iBAAiB,EACtB,QAAQ,EAAE,2BAA2B,GACtC,YAAY,CAAC,IAAI,CAAC,CAwBpB;AAED,wBAAiB,4BAA4B,CACzC,GAAG,EAAE,gBAAgB,EACrB,GAAG,EAAE,iBAAiB,EACtB,kBAAkB,CAAC,EAAE,MAAM,GAC5B,YAAY,CAAC,IAAI,CAAC,CAkCpB;AAED,wBAAiB,kBAAkB,CAAC,UAAU,EAAE,oBAAoB,GAAG,YAAY,CAAC,OAAO,CAAC,CAuB3F;AAED,wBAAiB,mBAAmB,CAAC,GAAG,EAAE,iBAAiB;;;yEAU1D;AAED,wBAAiB,4BAA4B,CAAC,GAAG,EAAE,gBAAgB,EAAE,GAAG,EAAE,iBAAiB;;;uNAwC1F;AAED,wBAAiB,4BAA4B;;;mBAE5C"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// (C) 2021-2026 GoodData Corporation
|
|
2
|
+
import { isEqual } from "lodash-es";
|
|
2
3
|
import { call, put, select } from "redux-saga/effects";
|
|
3
4
|
import { invariant } from "ts-invariant";
|
|
4
5
|
import { findDateFilterOptionByValue } from "../../../_staging/dateFilterConfig/dateFilterOptionMapping.js";
|
|
@@ -6,15 +7,39 @@ import { removeAttributeFilters } from "../../commands/filters.js";
|
|
|
6
7
|
import { filterContextChanged, filterContextWorkingSelectionApplied } from "../../events/filters.js";
|
|
7
8
|
import { dispatchDashboardEvent } from "../../store/_infra/eventDispatcher.js";
|
|
8
9
|
import { selectEnableImmediateAttributeFilterDisplayAsLabelMigration } from "../../store/config/configSelectors.js";
|
|
9
|
-
import { selectCrossFilteringFiltersLocalIdentifiers, selectIsCrossFiltering, } from "../../store/drill/drillSelectors.js";
|
|
10
|
+
import { selectCrossFilteringFiltersLocalIdentifiers, selectCrossFilteringFiltersLocalIdentifiersByTab, selectIsCrossFiltering, } from "../../store/drill/drillSelectors.js";
|
|
10
11
|
import { drillActions } from "../../store/drill/index.js";
|
|
12
|
+
import { selectEnablePersistentFiltersAcrossTabs } from "../../store/meta/metaSelectors.js";
|
|
11
13
|
import { selectAttributeFilterConfigsOverrides, selectAttributeFilterConfigsOverridesByTab, } from "../../store/tabs/attributeFilterConfigs/attributeFilterConfigsSelectors.js";
|
|
12
14
|
import { selectEffectiveDateFilterOptions } from "../../store/tabs/dateFilterConfig/dateFilterConfigSelectors.js";
|
|
13
|
-
import { selectFilterContextDefinition, selectFilterContextDefinitionsByTab, selectIsWorkingFilterContextChanged, } from "../../store/tabs/filterContext/filterContextSelectors.js";
|
|
15
|
+
import { selectFilterContextDefinition, selectFilterContextDefinitionsByTab, selectIsWorkingFilterContextChanged, selectWorkingFilterContextDefinitionsByTab, } from "../../store/tabs/filterContext/filterContextSelectors.js";
|
|
14
16
|
import { tabsActions } from "../../store/tabs/index.js";
|
|
15
17
|
import { selectParameterValuesByTab } from "../../store/tabs/parameters/parametersSelectors.js";
|
|
16
18
|
import { selectActiveOrDefaultTabLocalIdentifier } from "../../store/tabs/tabsSelectors.js";
|
|
17
|
-
import {
|
|
19
|
+
import { dispatchParametersChangedForAffectedTabs } from "../parameters/changeParameterValuesHandler.js";
|
|
20
|
+
export function* captureFilterContextByTabSnapshot() {
|
|
21
|
+
const filterContexts = yield select(selectFilterContextDefinitionsByTab);
|
|
22
|
+
const workingFilterContexts = yield select(selectWorkingFilterContextDefinitionsByTab);
|
|
23
|
+
const attributeFilterConfigs = yield select(selectAttributeFilterConfigsOverridesByTab);
|
|
24
|
+
return { filterContexts, workingFilterContexts, attributeFilterConfigs };
|
|
25
|
+
}
|
|
26
|
+
export function* dispatchFilterContextChangedForMutatedTabs(ctx, cmd, snapshot) {
|
|
27
|
+
const filterContexts = yield select(selectFilterContextDefinitionsByTab);
|
|
28
|
+
const attributeFilterConfigs = yield select(selectAttributeFilterConfigsOverridesByTab);
|
|
29
|
+
const workingFilterContexts = yield select(selectWorkingFilterContextDefinitionsByTab);
|
|
30
|
+
for (const tabId of Object.keys(filterContexts)) {
|
|
31
|
+
if (!filterContexts[tabId]) {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
const configs = attributeFilterConfigs[tabId] ?? [];
|
|
35
|
+
if (isEqual(snapshot.filterContexts[tabId], filterContexts[tabId]) &&
|
|
36
|
+
isEqual(snapshot.workingFilterContexts[tabId], workingFilterContexts[tabId]) &&
|
|
37
|
+
isEqual(snapshot.attributeFilterConfigs[tabId] ?? [], configs)) {
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
yield call(dispatchFilterContextChanged, ctx, cmd, tabId);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
18
43
|
export function* dispatchFilterContextChanged(ctx, cmd, tabLocalIdentifier) {
|
|
19
44
|
let filterContext;
|
|
20
45
|
let attributeFilterConfigs;
|
|
@@ -64,14 +89,26 @@ export function* applyWorkingSelectionHandler(ctx, cmd) {
|
|
|
64
89
|
const isWorkingFilterContextChanged = yield select(selectIsWorkingFilterContextChanged);
|
|
65
90
|
const tabId = yield select(selectActiveOrDefaultTabLocalIdentifier);
|
|
66
91
|
const valuesBefore = yield select(selectParameterValuesByTab);
|
|
67
|
-
yield
|
|
92
|
+
const crossFilteringLocalIdsByTab = yield select(selectCrossFilteringFiltersLocalIdentifiersByTab);
|
|
93
|
+
const enablePersistentFiltersAcrossTabs = yield select(selectEnablePersistentFiltersAcrossTabs);
|
|
94
|
+
const filterContextSnapshot = yield call(captureFilterContextByTabSnapshot);
|
|
95
|
+
yield put(tabsActions.applyWorkingSelection({
|
|
96
|
+
enableImmediateAttributeFilterDisplayAsLabelMigration,
|
|
97
|
+
crossFilteringLocalIdsByTab,
|
|
98
|
+
enablePersistentFiltersAcrossTabs,
|
|
99
|
+
}));
|
|
68
100
|
const isCrossFiltering = yield select(selectIsCrossFiltering);
|
|
69
101
|
if (isWorkingFilterContextChanged && isCrossFiltering) {
|
|
70
102
|
yield call(resetCrossFiltering, cmd);
|
|
71
103
|
}
|
|
72
104
|
yield dispatchDashboardEvent(filterContextWorkingSelectionApplied(ctx, cmd.correlationId));
|
|
73
|
-
|
|
74
|
-
|
|
105
|
+
if (enablePersistentFiltersAcrossTabs) {
|
|
106
|
+
yield call(dispatchFilterContextChangedForMutatedTabs, ctx, cmd, filterContextSnapshot);
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
yield call(dispatchFilterContextChanged, ctx, cmd);
|
|
110
|
+
}
|
|
111
|
+
yield call(dispatchParametersChangedForAffectedTabs, ctx, cmd, valuesBefore, tabId);
|
|
75
112
|
}
|
|
76
113
|
export function* resetWorkingSelectionHandler() {
|
|
77
114
|
yield put(tabsActions.resetWorkingSelection());
|
package/esm/model/commandHandlers/filterContext/dateFilter/changeDateFilterSelectionHandler.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"changeDateFilterSelectionHandler.d.ts","sourceRoot":"","sources":["../../../../../src/model/commandHandlers/filterContext/dateFilter/changeDateFilterSelectionHandler.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAU/C,OAAO,EAAE,KAAK,yBAAyB,EAA4B,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"changeDateFilterSelectionHandler.d.ts","sourceRoot":"","sources":["../../../../../src/model/commandHandlers/filterContext/dateFilter/changeDateFilterSelectionHandler.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAU/C,OAAO,EAAE,KAAK,yBAAyB,EAA4B,MAAM,8BAA8B,CAAC;AAYxG,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAUtE,wBAAiB,gCAAgC,CAC7C,GAAG,EAAE,gBAAgB,EACrB,GAAG,EAAE,yBAAyB,GAC/B,YAAY,CAAC,IAAI,CAAC,CA8EpB"}
|