@gooddata/sdk-ui-dashboard 11.62.0-alpha.1 → 11.62.0-alpha.3
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 +40 -618
- 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/composition/KdaAttributesDropdown.d.ts +2 -1
- package/esm/kdaDialog/composition/KdaAttributesDropdown.d.ts.map +1 -1
- package/esm/kdaDialog/composition/KdaAttributesDropdown.js +4 -5
- package/esm/kdaDialog/composition/KeyDriversFooter.d.ts.map +1 -1
- package/esm/kdaDialog/composition/KeyDriversFooter.js +12 -4
- package/esm/model/commandHandlers/dashboard/common/filterViews.d.ts +3 -2
- package/esm/model/commandHandlers/dashboard/common/filterViews.d.ts.map +1 -1
- package/esm/model/commandHandlers/dashboard/common/filterViews.js +12 -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/initializeDashboardHandler/index.d.ts.map +1 -1
- package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/index.js +1 -1
- 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.map +1 -1
- package/esm/model/commandHandlers/dashboard/resetDashboardHandler.js +3 -1
- package/esm/model/commandHandlers/dashboard/saveDashboardHandler.d.ts.map +1 -1
- package/esm/model/commandHandlers/dashboard/saveDashboardHandler.js +27 -10
- 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/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/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/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/events/dashboard.d.ts +17 -1
- package/esm/model/events/dashboard.d.ts.map +1 -1
- package/esm/model/events/dashboard.js +2 -1
- 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/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 +13 -3
- 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/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/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/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/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/widget/insight/ViewModeDashboardInsight/InsightDrillDialog/DrillDialogExportDropdown.d.ts.map +1 -1
- package/esm/presentation/widget/insight/ViewModeDashboardInsight/InsightDrillDialog/DrillDialogExportDropdown.js +1 -1
- 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 +151 -13
- package/package.json +23 -23
- package/styles/css/drillDialog.css +4 -0
- package/styles/css/drillDialog.css.map +1 -1
- package/styles/css/main.css +8 -0
- package/styles/css/main.css.map +1 -1
- package/styles/scss/drillDialog.scss +5 -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
|
@@ -11,7 +11,7 @@ import { DEFAULT_FISCAL_DATE_FILTER_PRESET } from "../../../../_staging/dateFilt
|
|
|
11
11
|
import { configHasFiscalPresets } from "../../../../_staging/dateFilterConfig/validation.js";
|
|
12
12
|
import { getPrivateContext } from "../../../store/_infra/contexts.js";
|
|
13
13
|
import { drillActions } from "../../../store/drill/index.js";
|
|
14
|
-
import {
|
|
14
|
+
import { isDashboardFilterUsingRestrictedObject, isDashboardObjectRestricted, } from "../../../store/filtering/restrictedFilterUtils.js";
|
|
15
15
|
import { insightsActions } from "../../../store/insights/index.js";
|
|
16
16
|
import { metaActions } from "../../../store/meta/index.js";
|
|
17
17
|
import { selectIsNewDashboard } from "../../../store/meta/metaSelectors.js";
|
|
@@ -70,7 +70,7 @@ function* processExistingTabFilterContext(ctx, tab, effectiveDateFilterConfig, d
|
|
|
70
70
|
const storeUnavailableObjects = yield select(selectUnavailableObjects);
|
|
71
71
|
const unavailableObjects = unavailableObjectsOverride ?? storeUnavailableObjects;
|
|
72
72
|
// Resolve display forms for filters
|
|
73
|
-
const attributeFilterDisplayForms = yield call(resolveFilterDisplayForms, ctx, migratedFilterContext.filters.filter((filter) => !
|
|
73
|
+
const attributeFilterDisplayForms = yield call(resolveFilterDisplayForms, ctx, migratedFilterContext.filters.filter((filter) => !isDashboardFilterUsingRestrictedObject(filter, unavailableObjects)), displayAsLabels.filter((displayForm) => !isDashboardObjectRestricted(displayForm, "displayForm", unavailableObjects)), displayForms);
|
|
74
74
|
// Return the complete FilterContextState for this tab
|
|
75
75
|
return [
|
|
76
76
|
{
|
|
@@ -256,7 +256,7 @@ function* actionsToInitializeOrFillNewDashboard(ctx, settings, dateFilterConfig,
|
|
|
256
256
|
const displayAsLabels = getDisplayAsLabels(effectiveAttributeFilterConfigs);
|
|
257
257
|
const unavailableObjects = yield select(selectUnavailableObjects);
|
|
258
258
|
// load DFs for both filter refs and displayAsLabels
|
|
259
|
-
const attributeFilterDisplayForms = yield call(resolveFilterDisplayForms, ctx, filterContextDefinition.filters.filter((filter) => !
|
|
259
|
+
const attributeFilterDisplayForms = yield call(resolveFilterDisplayForms, ctx, filterContextDefinition.filters.filter((filter) => !isDashboardFilterUsingRestrictedObject(filter, unavailableObjects)), displayAsLabels.filter((displayForm) => !isDashboardObjectRestricted(displayForm, "displayForm", unavailableObjects)), displayForms);
|
|
260
260
|
/*
|
|
261
261
|
* NOTE: cannot do without the cast here. The layout in IDashboard is parameterized with IDashboardWidget
|
|
262
262
|
* which also includes KPI and Insight widget definitions = those without identity. That is however
|
|
@@ -278,7 +278,7 @@ function* actionsToInitializeOrFillNewDashboard(ctx, settings, dateFilterConfig,
|
|
|
278
278
|
};
|
|
279
279
|
}
|
|
280
280
|
const keepOnlyFiltersWithValidRef = (filter, availableDfRefs, validDataSetIds, unavailableObjects) => {
|
|
281
|
-
if (
|
|
281
|
+
if (isDashboardFilterUsingRestrictedObject(filter, unavailableObjects)) {
|
|
282
282
|
return true;
|
|
283
283
|
}
|
|
284
284
|
if (!isDashboardAttributeFilter(filter)) {
|
|
@@ -306,7 +306,7 @@ function* sanitizeFilterContext(ctx, filterContext, dataSets = [], displayForms,
|
|
|
306
306
|
const unavailableObjects = unavailableObjectsOverride ?? storeUnavailableObjects;
|
|
307
307
|
const usedFilterDisplayForms = filterContext.filters
|
|
308
308
|
.filter(isDashboardAttributeFilter)
|
|
309
|
-
.filter((filter) => !
|
|
309
|
+
.filter((filter) => !isDashboardFilterUsingRestrictedObject(filter, unavailableObjects))
|
|
310
310
|
.map((f) => f.attributeFilter.displayForm);
|
|
311
311
|
// With enableDashboardPartialRendering on, the unavailableObjects store already knows which of
|
|
312
312
|
// these display forms are missing (resolved from the filter-context labels), so the lookups
|
|
@@ -334,7 +334,6 @@ function* sanitizeFilterContext(ctx, filterContext, dataSets = [], displayForms,
|
|
|
334
334
|
const additionalDateFilters = filterContext.filters
|
|
335
335
|
.filter((filter) => !isDashboardAttributeFilter(filter))
|
|
336
336
|
.filter(isDashboardDateFilterWithDimension)
|
|
337
|
-
.filter((filter) => !isDashboardFilterRestricted(filter, unavailableObjects))
|
|
338
337
|
.map((filter) => filter.dateFilter.dataSet);
|
|
339
338
|
// check which are missing and load them
|
|
340
339
|
const missingDataSets = additionalDateFilters
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/model/commandHandlers/dashboard/initializeDashboardHandler/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,WAAW,EAAgB,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAI/C,OAAO,EACH,KAAK,UAAU,EAIf,KAAK,sBAAsB,EAW9B,MAAM,qBAAqB,CAAC;AAO7B,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AA0B1E,OAAO,EACH,KAAK,gBAAgB,EAGxB,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/model/commandHandlers/dashboard/initializeDashboardHandler/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,WAAW,EAAgB,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAI/C,OAAO,EACH,KAAK,UAAU,EAIf,KAAK,sBAAsB,EAW9B,MAAM,qBAAqB,CAAC;AAO7B,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AA0B1E,OAAO,EACH,KAAK,gBAAgB,EAGxB,MAAM,+BAA+B,CAAC;AAyfvC,wBAAiB,cAAc,CAAC,GAAG,EAAE,gBAAgB,EAAE,GAAG,EAAE,mBAAmB;;;uIAyB9E;AAkCD,wBAAiB,2BAA2B,CAAC,GAAG,EAAE,gBAAgB,EAAE,SAAS,EAAE,UAAU;;;8KAOxF;AAED,wBAAiB,qBAAqB,CAAC,GAAG,EAAE,gBAAgB,sNAW3D;AAoCD,wBAAiB,0BAA0B,CAAC,GAAG,EAAE,gBAAgB,EAAE,GAAG,EAAE,mBAAmB,GAAG,YAAY,CAoCzG"}
|
|
@@ -191,7 +191,7 @@ function* loadExistingDashboard(ctx, cmd, dashboardRef) {
|
|
|
191
191
|
// FF off => nothing is ever marked unavailable and behavior is unchanged
|
|
192
192
|
const unavailableReferences = yield call(loadUnavailableReferences, ctx, loadedDashboard, unavailable, Boolean(config.settings?.enableDashboardPartialRendering), !!cmd.payload.persistedDashboard);
|
|
193
193
|
yield put(unavailableObjectsActions.setUnavailableObjects(unavailableReferences));
|
|
194
|
-
const dashboardWithFilterView = applyDefaultFilterView(loadedDashboard, filterViews, config.exportId);
|
|
194
|
+
const dashboardWithFilterView = applyDefaultFilterView(loadedDashboard, filterViews, config.exportId, unavailableReferences);
|
|
195
195
|
// Resolve active tab: URL's initialTabId takes precedence, otherwise default to first tab
|
|
196
196
|
// Note: activeTabLocalIdentifier is app state only, NOT persisted to/read from dashboard MD
|
|
197
197
|
const resolvedActiveTabId = resolveActiveTabId(dashboardWithFilterView.tabs, cmd.payload.initialTabId, undefined);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loadUnavailableReferences.d.ts","sourceRoot":"","sources":["../../../../../src/model/commandHandlers/dashboard/initializeDashboardHandler/loadUnavailableReferences.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACR,8BAA8B,EAC9B,gCAAgC,EACnC,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"loadUnavailableReferences.d.ts","sourceRoot":"","sources":["../../../../../src/model/commandHandlers/dashboard/initializeDashboardHandler/loadUnavailableReferences.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACR,8BAA8B,EAC9B,gCAAgC,EACnC,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AA+BtE;;;;;;;;;GASG;AACH,wBAAgB,8BAA8B,CAC1C,uBAAuB,EAAE,OAAO,GACjC,gCAAgC,EAAE,CAEpC;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,GAAG,EAAE,gBAAgB,GAAG,gCAAgC,EAAE,CAErG;AAED;;;;;;GAMG;AACH,wBAAsB,yBAAyB,CAC3C,GAAG,EAAE,gBAAgB,EACrB,SAAS,EAAE,UAAU,EACrB,eAAe,EAAE,8BAA8B,EAAE,GAAG,SAAS,EAC7D,uBAAuB,EAAE,OAAO,EAChC,qBAAqB,EAAE,OAAO,GAC/B,OAAO,CAAC,8BAA8B,EAAE,CAAC,CAkB3C"}
|
package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/loadUnavailableReferences.js
CHANGED
|
@@ -7,6 +7,7 @@ const ALL_TYPES = [
|
|
|
7
7
|
"analyticalDashboard",
|
|
8
8
|
"measure",
|
|
9
9
|
"fact",
|
|
10
|
+
"attribute",
|
|
10
11
|
"computedAttribute",
|
|
11
12
|
];
|
|
12
13
|
const ENRICHED_TYPES = [
|
|
@@ -14,6 +15,7 @@ const ENRICHED_TYPES = [
|
|
|
14
15
|
"analyticalDashboard",
|
|
15
16
|
"measure",
|
|
16
17
|
"fact",
|
|
18
|
+
"attribute",
|
|
17
19
|
"computedAttribute",
|
|
18
20
|
];
|
|
19
21
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resetDashboardHandler.d.ts","sourceRoot":"","sources":["../../../../src/model/commandHandlers/dashboard/resetDashboardHandler.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAa/C,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,KAAK,kBAAkB,EAAqB,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"resetDashboardHandler.d.ts","sourceRoot":"","sources":["../../../../src/model/commandHandlers/dashboard/resetDashboardHandler.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAa/C,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,KAAK,kBAAkB,EAAqB,MAAM,2BAA2B,CAAC;AAgBvF,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAWnE,wBAAiB,qBAAqB,CAClC,GAAG,EAAE,gBAAgB,EACrB,GAAG,EAAE,eAAe,GACrB,YAAY,CAAC,kBAAkB,CAAC,CAOlC;AAED,wBAAiB,qBAAqB,CAAC,GAAG,EAAE,gBAAgB,EAAE,GAAG,EAAE,eAAe;;;;;;;;;;;;;;;GASjF"}
|
|
@@ -11,6 +11,7 @@ import { selectFilterViews } from "../../store/filterViews/filterViewsReducersSe
|
|
|
11
11
|
import { selectPersistedDashboard } from "../../store/meta/metaSelectors.js";
|
|
12
12
|
import { selectActiveTabLocalIdentifier, selectTabs } from "../../store/tabs/tabsSelectors.js";
|
|
13
13
|
import { DEFAULT_TAB_ID } from "../../store/tabs/tabsState.js";
|
|
14
|
+
import { selectUnavailableObjects } from "../../store/unavailableObjects/unavailableObjectsSelectors.js";
|
|
14
15
|
import { resolveInsights } from "../../utils/insightResolver.js";
|
|
15
16
|
import { applyDefaultFilterView } from "./common/filterViews.js";
|
|
16
17
|
import { insightReferencesFromDashboard } from "./common/insightReferences.js";
|
|
@@ -111,7 +112,8 @@ function* resetDashboardFromPersisted(ctx) {
|
|
|
111
112
|
// end of ad-hoc migration content
|
|
112
113
|
const settings = yield select(selectSettings);
|
|
113
114
|
const filterViews = yield select(selectFilterViews);
|
|
114
|
-
const
|
|
115
|
+
const unavailableObjects = yield select(selectUnavailableObjects);
|
|
116
|
+
const dashboardWithUpdatedFilterContext = applyDefaultFilterView(persistedDashboard, filterViews, ctx.config?.exportId, unavailableObjects);
|
|
115
117
|
const insightRefsFromWidgets = insightReferencesFromDashboard(dashboardWithUpdatedFilterContext);
|
|
116
118
|
const uniqueInsightRefsFromWidgets = uniqWith(insightRefsFromWidgets, areObjRefsEqual);
|
|
117
119
|
const resolvedInsights = yield call(resolveInsights, ctx, uniqueInsightRefsFromWidgets);
|
|
@@ -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,EAYxB,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;AA4M1E,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;AAwUD,wBAAiB,oBAAoB,CACjC,GAAG,EAAE,gBAAgB,EACrB,GAAG,EAAE,cAAc,GACpB,YAAY,CAAC,cAAc,GAAG,SAAS,CAAC,CA2G1C"}
|
|
@@ -3,7 +3,7 @@ import { batchActions } from "redux-batched-actions";
|
|
|
3
3
|
import { all, 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 { areObjRefsEqual, insightRef, isTempFilterContext, } from "@gooddata/sdk-model";
|
|
6
|
+
import { areObjRefsEqual, insightRef, isIdentifierRef, 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";
|
|
@@ -14,7 +14,7 @@ import { dashboardSaved } from "../../events/dashboard.js";
|
|
|
14
14
|
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
|
-
import { selectLocale } from "../../store/config/configSelectors.js";
|
|
17
|
+
import { selectIsAiMode, selectLocale } from "../../store/config/configSelectors.js";
|
|
18
18
|
import { insightsActions } from "../../store/insights/index.js";
|
|
19
19
|
import { selectDraftInsightsUsedOnDashboard, selectInsights, } from "../../store/insights/insightsSelectors.js";
|
|
20
20
|
import { listedDashboardsActions } from "../../store/listedDashboards/index.js";
|
|
@@ -40,6 +40,7 @@ import { changeRenderModeHandler } from "../renderMode/changeRenderModeHandler.j
|
|
|
40
40
|
import { switchDashboardTabHandler } from "../tabs/switchDashboardTabHandler.js";
|
|
41
41
|
import { dashboardWithDrillReferences } from "./dashboardDrillReferences.js";
|
|
42
42
|
function* persistDraftInsights(ctx, cmd, insights) {
|
|
43
|
+
const savedInsights = [];
|
|
43
44
|
for (const draftInsight of insights) {
|
|
44
45
|
const persistedInsight = yield call(async () => {
|
|
45
46
|
return ctx.backend.workspace(ctx.workspace).insights().createInsight(draftInsight, false);
|
|
@@ -72,7 +73,19 @@ function* persistDraftInsights(ctx, cmd, insights) {
|
|
|
72
73
|
}));
|
|
73
74
|
}
|
|
74
75
|
yield put(insightsActions.setInsights(updatedInsights));
|
|
76
|
+
const originalInsightRef = insightRef(draftInsight);
|
|
77
|
+
const savedInsightRef = insightRef(persistedInsight);
|
|
78
|
+
const originalInsightId = isIdentifierRef(originalInsightRef)
|
|
79
|
+
? originalInsightRef.identifier
|
|
80
|
+
: draftInsight.insight.identifier;
|
|
81
|
+
const savedInsightId = isIdentifierRef(savedInsightRef)
|
|
82
|
+
? savedInsightRef.identifier
|
|
83
|
+
: persistedInsight.insight.identifier;
|
|
84
|
+
if (originalInsightId && savedInsightId) {
|
|
85
|
+
savedInsights.push({ originalInsightId, savedInsightId });
|
|
86
|
+
}
|
|
75
87
|
}
|
|
88
|
+
return savedInsights;
|
|
76
89
|
}
|
|
77
90
|
async function draftInsightExistsOnBackend(ctx, draftInsight) {
|
|
78
91
|
const ref = insightRef(draftInsight);
|
|
@@ -128,7 +141,7 @@ function saveDashboard(ctx, saveCtx) {
|
|
|
128
141
|
return ctx.backend
|
|
129
142
|
.workspace(ctx.workspace)
|
|
130
143
|
.dashboards()
|
|
131
|
-
.createDashboard(dashboardToSave, !
|
|
144
|
+
.createDashboard(dashboardToSave, !saveCtx.isAiMode)
|
|
132
145
|
.then((dashboard) => ({ dashboard, created: true }));
|
|
133
146
|
}
|
|
134
147
|
throw error;
|
|
@@ -246,7 +259,7 @@ function resolveProcessedTabs(tabs, rootFilterContext, layout, dateFilterConfig,
|
|
|
246
259
|
* capability, this code should use either the selectBasicLayout (that strips any custom widgets) or
|
|
247
260
|
* selectLayout (that keeps custom widgets).
|
|
248
261
|
*/
|
|
249
|
-
function* createDashboardSaveContext(cmd, isNewDashboard) {
|
|
262
|
+
function* createDashboardSaveContext(cmd, isNewDashboard, isAiMode) {
|
|
250
263
|
const persistedDashboard = yield select(selectPersistedDashboard);
|
|
251
264
|
const dashboardDescriptor = yield select(selectDashboardDescriptor);
|
|
252
265
|
const tabs = yield select(selectTabs);
|
|
@@ -324,6 +337,7 @@ function* createDashboardSaveContext(cmd, isNewDashboard) {
|
|
|
324
337
|
const insights = yield select(selectInsights);
|
|
325
338
|
return {
|
|
326
339
|
cmd,
|
|
340
|
+
isAiMode,
|
|
327
341
|
persistedDashboard,
|
|
328
342
|
dashboardFromState,
|
|
329
343
|
dashboardToSave: getDashboardWithSharing(dashboardWithDrillReferences(dashboardToSave, insights), capabilities.supportsAccessControl, isNewDashboard),
|
|
@@ -431,13 +445,13 @@ export function* saveDashboardHandler(ctx, cmd) {
|
|
|
431
445
|
if (isInsightNotSavedDialogOpen) {
|
|
432
446
|
yield put(uiActions.closeInsightNotSavedDialog());
|
|
433
447
|
}
|
|
434
|
-
|
|
435
|
-
yield call(persistDraftInsights, ctx, cmd, draftInsightsToPersist)
|
|
436
|
-
|
|
448
|
+
const savedInsights = shouldPersistDraftInsights && draftInsightsToPersist.length > 0
|
|
449
|
+
? yield call(persistDraftInsights, ctx, cmd, draftInsightsToPersist)
|
|
450
|
+
: [];
|
|
437
451
|
const persistedDashboard = yield select(selectPersistedDashboard);
|
|
438
452
|
const isNewDashboard = persistedDashboard === undefined;
|
|
439
|
-
const isAiBuilder =
|
|
440
|
-
const saveCtx = yield call(createDashboardSaveContext, cmd, isNewDashboard);
|
|
453
|
+
const isAiBuilder = yield select(selectIsAiMode);
|
|
454
|
+
const saveCtx = yield call(createDashboardSaveContext, cmd, isNewDashboard, isAiBuilder);
|
|
441
455
|
let result;
|
|
442
456
|
if (isAiBuilder) {
|
|
443
457
|
result = yield call(save, ctx, saveCtx, saveDashboard, "@@GDC.DASH.SAVE_BUILDED");
|
|
@@ -470,7 +484,10 @@ export function* saveDashboardHandler(ctx, cmd) {
|
|
|
470
484
|
yield dispatchDashboardEvent(switchedEvent);
|
|
471
485
|
}
|
|
472
486
|
yield put(savingActions.setSavingSuccess());
|
|
473
|
-
return dashboardSaved(ctx, dashboard, created, cmd.correlationId
|
|
487
|
+
return dashboardSaved(ctx, dashboard, created, cmd.correlationId, {
|
|
488
|
+
...(isAiBuilder ? { originalDashboardId: saveCtx.dashboardFromState.identifier } : {}),
|
|
489
|
+
...(savedInsights.length > 0 ? { savedInsights } : {}),
|
|
490
|
+
});
|
|
474
491
|
}
|
|
475
492
|
catch (e) {
|
|
476
493
|
yield put(savingActions.setSavingError(e));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drillToDashboardHandler.d.ts","sourceRoot":"","sources":["../../../../src/model/commandHandlers/drill/drillToDashboardHandler.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAiC/C,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,EACH,KAAK,kCAAkC,EAG1C,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"drillToDashboardHandler.d.ts","sourceRoot":"","sources":["../../../../src/model/commandHandlers/drill/drillToDashboardHandler.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAiC/C,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,OAAO,EACH,KAAK,kCAAkC,EAG1C,MAAM,uBAAuB,CAAC;AAmB/B,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAWnE,wBAAiB,uBAAuB,CACpC,GAAG,EAAE,gBAAgB,EACrB,GAAG,EAAE,iBAAiB,GACvB,YAAY,CAAC,kCAAkC,CAAC,CAoIlD"}
|
|
@@ -8,6 +8,7 @@ import { drillToDashboardRequested, drillToDashboardResolved, } from "../../even
|
|
|
8
8
|
import { generateFilterLocalIdentifier } from "../../store/_infra/generators.js";
|
|
9
9
|
import { selectSupportsMultipleDateFilters } from "../../store/backendCapabilities/backendCapabilitiesSelectors.js";
|
|
10
10
|
import { selectCatalogDateAttributes } from "../../store/catalog/catalogSelectors.js";
|
|
11
|
+
import { selectRestrictedDashboardFilterLocalIdentifiers } from "../../store/filtering/dashboardFilterSelectors.js";
|
|
11
12
|
import { selectInsightByRef } from "../../store/insights/insightsSelectors.js";
|
|
12
13
|
import { selectAttributeFilterConfigsDisplayAsLabelMap, selectAttributeFilterConfigsOverrides, } from "../../store/tabs/attributeFilterConfigs/attributeFilterConfigsSelectors.js";
|
|
13
14
|
import { selectFilterContextAttributeFilterItems, selectFilterContextDateFilter, selectFilterContextDraggableFilterItems, selectFilterContextMeasureValueFilters, } from "../../store/tabs/filterContext/filterContextSelectors.js";
|
|
@@ -40,7 +41,9 @@ export function* drillToDashboardHandler(ctx, cmd) {
|
|
|
40
41
|
const allAttributeFilters = yield select(selectAllAttributeFilters);
|
|
41
42
|
const allMeasureValueFilters = yield select(selectAllMeasureValueFilters);
|
|
42
43
|
const allNonDateFilters = [...allAttributeFilters, ...allMeasureValueFilters];
|
|
43
|
-
const
|
|
44
|
+
const restrictedLocalIdentifiers = yield select(selectRestrictedDashboardFilterLocalIdentifiers);
|
|
45
|
+
// a restricted filter is applied nowhere, so the target dashboard does not get it either
|
|
46
|
+
const dashboardFiltersToResolve = (includeOtherDateFilters ? allDraggableFilters : allNonDateFilters).filter((filter) => !restrictedLocalIdentifiers.has(dashboardFilterLocalIdentifier(filter) ?? ""));
|
|
44
47
|
const widgetAwareFilters = isDrillingToSelf
|
|
45
48
|
? []
|
|
46
49
|
: yield call(getWidgetAwareDashboardFilters, ctx, widget, dashboardFiltersToResolve);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keyDriverAnalysisHandler.d.ts","sourceRoot":"","sources":["../../../../src/model/commandHandlers/drill/keyDriverAnalysisHandler.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAc/C,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EACH,KAAK,mCAAmC,EAG3C,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"keyDriverAnalysisHandler.d.ts","sourceRoot":"","sources":["../../../../src/model/commandHandlers/drill/keyDriverAnalysisHandler.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAc/C,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EACH,KAAK,mCAAmC,EAG3C,MAAM,uBAAuB,CAAC;AAW/B,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAKnE,wBAAiB,wBAAwB,CACrC,GAAG,EAAE,gBAAgB,EACrB,GAAG,EAAE,kBAAkB,GACxB,YAAY,CAAC,mCAAmC,CAAC,CA4HnD"}
|
|
@@ -5,7 +5,8 @@ import { keyDriverAnalysisRequested, keyDriverAnalysisResolved, } from "../../ev
|
|
|
5
5
|
import { invalidArgumentsProvided } from "../../events/general.js";
|
|
6
6
|
import { generateFilterLocalIdentifier } from "../../store/_infra/generators.js";
|
|
7
7
|
import { selectCatalogDateAttributes } from "../../store/catalog/catalogSelectors.js";
|
|
8
|
-
import {
|
|
8
|
+
import { selectRestrictedDashboardFilterLocalIdentifiers } from "../../store/filtering/dashboardFilterSelectors.js";
|
|
9
|
+
import { isDashboardFilterCopyRestricted, isDashboardFilterUsingRestrictedObject, } from "../../store/filtering/restrictedFilterUtils.js";
|
|
9
10
|
import { selectWidgetByRef } from "../../store/tabs/layout/layoutSelectors.js";
|
|
10
11
|
import { selectUnavailableObjects } from "../../store/unavailableObjects/unavailableObjectsSelectors.js";
|
|
11
12
|
import { getAttributeFilters, removeIgnoredWidgetFilters } from "../../utils/widgetFilters.js";
|
|
@@ -55,14 +56,15 @@ export function* keyDriverAnalysisHandler(ctx, cmd) {
|
|
|
55
56
|
});
|
|
56
57
|
const widget = yield select(selectWidgetByRef(drillEvent.widgetRef));
|
|
57
58
|
const unavailableObjects = yield select(selectUnavailableObjects);
|
|
58
|
-
const
|
|
59
|
+
const restrictedLocalIdentifiers = yield select(selectRestrictedDashboardFilterLocalIdentifiers);
|
|
60
|
+
const executableFilters = availableFilters.filter((filter) => !isDashboardFilterCopyRestricted(filter, restrictedLocalIdentifiers, unavailableObjects));
|
|
59
61
|
const widgetFilters = removeIgnoredWidgetFilters(executableFilters, widget);
|
|
60
62
|
// KDA defines its own date range — drop date filters. Keep attribute and measure value
|
|
61
63
|
// filters so the change analysis respects the rest of the dashboard filter context.
|
|
62
64
|
const attributeFilters = getAttributeFilters(widgetFilters);
|
|
63
65
|
const measureValueFilters = widgetFilters.filter(isDashboardMeasureValueFilter);
|
|
64
66
|
// the drill intersection brings its own attribute filters, which the check above did not see
|
|
65
|
-
const filters = mergeFilters(intersectionFilters, attributeFilters).filter((filter) => !
|
|
67
|
+
const filters = mergeFilters(intersectionFilters, attributeFilters).filter((filter) => !isDashboardFilterUsingRestrictedObject(filter, unavailableObjects));
|
|
66
68
|
return keyDriverAnalysisResolved(ctx, cmd.payload.drillDefinition, cmd.payload.drillEvent, {
|
|
67
69
|
metric: {
|
|
68
70
|
...metric,
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { type SagaIterator } from "redux-saga";
|
|
2
|
-
import { type DashboardTextAttributeFilter, type IAttributeDisplayFormMetadataObject, type IDrillToCustomUrl as IDrillToCustomUrlModel, type MeasureValueFilterCondition, type ObjRef, type TextAttributeFilter } from "@gooddata/sdk-model";
|
|
2
|
+
import { type DashboardAttributeFilterItem, type DashboardTextAttributeFilter, type IAttributeDisplayFormMetadataObject, type IDashboardAttributeFilter, type IDrillToCustomUrl as IDrillToCustomUrlModel, type MeasureValueFilterCondition, type ObjRef, type TextAttributeFilter } from "@gooddata/sdk-model";
|
|
3
3
|
import { type IDrillEvent, type IDrillEventIntersectionElement } from "@gooddata/sdk-ui";
|
|
4
4
|
import { type IDrillToCustomUrl } from "../../commands/drill.js";
|
|
5
|
+
import { selectAllCatalogDisplayFormsMap } from "../../store/catalog/catalogSelectors.js";
|
|
6
|
+
import { selectAttributeFilterConfigsOverrides } from "../../store/tabs/attributeFilterConfigs/attributeFilterConfigsSelectors.js";
|
|
5
7
|
import { type DashboardContext } from "../../types/commonTypes.js";
|
|
6
8
|
interface IDrillToUrlPlaceholderReplacement {
|
|
7
9
|
toBeReplaced: string;
|
|
@@ -24,6 +26,24 @@ export declare function splitDFToLoadingAndMapping(attributesDisplayForms: IAttr
|
|
|
24
26
|
}>;
|
|
25
27
|
export declare function loadAttributeElementsForDrillIntersection(drillIntersectionElements: IDrillEventIntersectionElement[], attributesDisplayForms: IAttributeDisplayFormMetadataObject[], ctx: DashboardContext): SagaIterator<IDrillToUrlElement[]>;
|
|
26
28
|
export declare function getAttributeIdentifiersReplacements(url: string, drillIntersectionElements: IDrillEventIntersectionElement[], ctx: DashboardContext): SagaIterator<IDrillToUrlPlaceholderReplacement[]>;
|
|
29
|
+
/**
|
|
30
|
+
* The filter a dashboard attribute filter placeholder names. A readable filter wins: a text filter with
|
|
31
|
+
* the placeholder's label, then a list filter with it, then a list filter displayed by it. A restricted
|
|
32
|
+
* filter matched in any of these ways is applied nowhere, so it filters nothing.
|
|
33
|
+
*/
|
|
34
|
+
export type DashboardAttributeFilterPlaceholderMatch = {
|
|
35
|
+
type: "text";
|
|
36
|
+
filter: DashboardTextAttributeFilter;
|
|
37
|
+
} | {
|
|
38
|
+
type: "label";
|
|
39
|
+
filter: IDashboardAttributeFilter;
|
|
40
|
+
} | {
|
|
41
|
+
type: "displayAsLabel";
|
|
42
|
+
filter: IDashboardAttributeFilter;
|
|
43
|
+
} | {
|
|
44
|
+
type: "restricted";
|
|
45
|
+
};
|
|
46
|
+
export declare function findDashboardAttributeFilterPlaceholderMatch(ref: ObjRef, attributeFilters: DashboardAttributeFilterItem[], restrictedLocalIdentifiers: ReadonlySet<string>, catalogDisplayForms: ReturnType<typeof selectAllCatalogDisplayFormsMap>, attributeFilterConfigs: ReturnType<typeof selectAttributeFilterConfigsOverrides>): DashboardAttributeFilterPlaceholderMatch | undefined;
|
|
27
47
|
export declare function getDashboardAttributeFilterReplacements(url: string, ctx: DashboardContext): SagaIterator<IDrillToUrlPlaceholderReplacement[]>;
|
|
28
48
|
export declare function getDashboardMeasureValueFilterReplacements(url: string): SagaIterator<IDrillToUrlPlaceholderReplacement[]>;
|
|
29
49
|
export declare function getInsightMeasureValueFilterReplacements(url: string, widgetRef: ObjRef): 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,
|
|
1
|
+
{"version":3,"file":"resolveDrillToCustomUrl.d.ts","sourceRoot":"","sources":["../../../../src/model/commandHandlers/drill/resolveDrillToCustomUrl.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,12 +2,13 @@
|
|
|
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,
|
|
5
|
+
import { areObjRefsEqual, dashboardAttributeFilterItemDisplayForm, dashboardAttributeFilterItemLocalIdentifier, dashboardFilterLocalIdentifier, dashboardMeasureValueFilterLocalIdentifier, 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
6
|
import { DRILL_TO_URL_PLACEHOLDER, displayFormPlaceholderRef, getAttributeIdentifiersPlaceholdersFromUrl, getDashboardAttributeFilterPlaceholdersFromUrl, getDashboardMeasureValueFilterPlaceholdersFromUrl, getDrillUrlPlaceholderTypes, 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";
|
|
10
10
|
import { selectEnableMeasureValueFilterKD } from "../../store/config/configSelectors.js";
|
|
11
|
+
import { selectRestrictedDashboardFilterLocalIdentifiers } from "../../store/filtering/dashboardFilterSelectors.js";
|
|
11
12
|
import { selectInsightByRef } from "../../store/insights/insightsSelectors.js";
|
|
12
13
|
import { selectDashboardId } from "../../store/meta/metaSelectors.js";
|
|
13
14
|
import { selectAttributeFilterConfigsOverrides } from "../../store/tabs/attributeFilterConfigs/attributeFilterConfigsSelectors.js";
|
|
@@ -167,55 +168,51 @@ export function* getAttributeIdentifiersReplacements(url, drillIntersectionEleme
|
|
|
167
168
|
};
|
|
168
169
|
});
|
|
169
170
|
}
|
|
170
|
-
function
|
|
171
|
-
|
|
172
|
-
const
|
|
173
|
-
if (!isDashboardTextAttributeFilter(filter)) {
|
|
174
|
-
return false;
|
|
175
|
-
}
|
|
171
|
+
export function findDashboardAttributeFilterPlaceholderMatch(ref, attributeFilters, restrictedLocalIdentifiers, catalogDisplayForms, attributeFilterConfigs) {
|
|
172
|
+
const isReadable = (filter) => !restrictedLocalIdentifiers.has(dashboardFilterLocalIdentifier(filter) ?? "");
|
|
173
|
+
const hasLabel = (filter) => {
|
|
176
174
|
const df = catalogDisplayForms.get(dashboardAttributeFilterItemDisplayForm(filter));
|
|
177
|
-
return df && areObjRefsEqual(displayFormPlaceholderRef(df), ref);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
};
|
|
175
|
+
return !!df && areObjRefsEqual(displayFormPlaceholderRef(df), ref);
|
|
176
|
+
};
|
|
177
|
+
const isDisplayedByLabel = (filter) => attributeFilterConfigs.some((config) => config.localIdentifier === dashboardAttributeFilterItemLocalIdentifier(filter) &&
|
|
178
|
+
!!config.displayAsLabel &&
|
|
179
|
+
areObjRefsEqual(config.displayAsLabel, ref));
|
|
180
|
+
const textFilter = attributeFilters.find((filter) => isDashboardTextAttributeFilter(filter) && isReadable(filter) && hasLabel(filter));
|
|
181
|
+
if (textFilter) {
|
|
182
|
+
return { type: "text", filter: textFilter };
|
|
186
183
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
const df = catalogDisplayForms.get(filter.attributeFilter.displayForm);
|
|
191
|
-
return df && areObjRefsEqual(displayFormPlaceholderRef(df), ref);
|
|
192
|
-
});
|
|
193
|
-
let attributeElementsValues = [];
|
|
194
|
-
if (usedFilter) {
|
|
195
|
-
const elements = usedFilter?.attributeFilter.attributeElements;
|
|
196
|
-
attributeElementsValues = isAttributeElementsByValue(elements)
|
|
197
|
-
? elements.values
|
|
198
|
-
: (elements?.uris ?? []);
|
|
184
|
+
const labelFilter = attributeFilters.find((filter) => isDashboardAttributeFilter(filter) && isReadable(filter) && hasLabel(filter));
|
|
185
|
+
if (labelFilter) {
|
|
186
|
+
return { type: "label", filter: labelFilter };
|
|
199
187
|
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
});
|
|
204
|
-
usedFilter = standardFilters.find((filter) => {
|
|
205
|
-
return filter.attributeFilter.localIdentifier === usedConfig?.localIdentifier;
|
|
206
|
-
});
|
|
207
|
-
const elements = usedFilter?.attributeFilter.attributeElements;
|
|
208
|
-
const primaryElementsValues = elements
|
|
209
|
-
? isAttributeElementsByValue(elements)
|
|
210
|
-
? elements.values
|
|
211
|
-
: elements.uris
|
|
212
|
-
: [];
|
|
213
|
-
attributeElementsValues = yield call(loadSecondaryElementTitles, ref, primaryElementsValues, ctx);
|
|
188
|
+
const displayedFilter = attributeFilters.find((filter) => isDashboardAttributeFilter(filter) && isReadable(filter) && isDisplayedByLabel(filter));
|
|
189
|
+
if (displayedFilter) {
|
|
190
|
+
return { type: "displayAsLabel", filter: displayedFilter };
|
|
214
191
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
? stringifyAttributeFilterSelection(attributeElementsValues, isNegative)
|
|
192
|
+
return attributeFilters.some((filter) => !isReadable(filter) && (hasLabel(filter) || isDisplayedByLabel(filter)))
|
|
193
|
+
? { type: "restricted" }
|
|
218
194
|
: undefined;
|
|
195
|
+
}
|
|
196
|
+
function* resolveDashboardAttributeFilterReplacement({ placeholder: toBeReplaced, ref }, attributeFilters, restrictedLocalIdentifiers, catalogDisplayForms, attributeFilterConfigs, ctx) {
|
|
197
|
+
const match = findDashboardAttributeFilterPlaceholderMatch(ref, attributeFilters, restrictedLocalIdentifiers, catalogDisplayForms, attributeFilterConfigs);
|
|
198
|
+
// a placeholder whose filter is missing from the dashboard stays unresolved, which rejects the drill
|
|
199
|
+
let parsedFilter;
|
|
200
|
+
if (match?.type === "text") {
|
|
201
|
+
parsedFilter = stringifyTextFilterSelection(match.filter);
|
|
202
|
+
}
|
|
203
|
+
else if (match?.type === "label") {
|
|
204
|
+
const elements = match.filter.attributeFilter.attributeElements;
|
|
205
|
+
parsedFilter = stringifyAttributeFilterSelection(isAttributeElementsByValue(elements) ? elements.values : elements.uris, match.filter.attributeFilter.negativeSelection);
|
|
206
|
+
}
|
|
207
|
+
else if (match?.type === "displayAsLabel") {
|
|
208
|
+
const elements = match.filter.attributeFilter.attributeElements;
|
|
209
|
+
const primaryElementsValues = isAttributeElementsByValue(elements) ? elements.values : elements.uris;
|
|
210
|
+
const elementTitles = yield call(loadSecondaryElementTitles, ref, primaryElementsValues, ctx);
|
|
211
|
+
parsedFilter = stringifyAttributeFilterSelection(elementTitles, match.filter.attributeFilter.negativeSelection);
|
|
212
|
+
}
|
|
213
|
+
else if (match?.type === "restricted") {
|
|
214
|
+
parsedFilter = stringifyAttributeFilterSelection([], true);
|
|
215
|
+
}
|
|
219
216
|
const replacement = encodeParameterIfSet(parsedFilter);
|
|
220
217
|
return {
|
|
221
218
|
toBeReplaced,
|
|
@@ -228,17 +225,21 @@ export function* getDashboardAttributeFilterReplacements(url, ctx) {
|
|
|
228
225
|
return [];
|
|
229
226
|
}
|
|
230
227
|
const attributeFilters = yield select(selectFilterContextAttributeFilterItems);
|
|
228
|
+
const restrictedLocalIdentifiers = yield select(selectRestrictedDashboardFilterLocalIdentifiers);
|
|
231
229
|
const catalogDisplayForms = yield select(selectAllCatalogDisplayFormsMap);
|
|
232
230
|
const attributeFilterConfigs = yield select(selectAttributeFilterConfigsOverrides);
|
|
233
|
-
return yield all(attributeFilterPlaceholders.map((placeholder) => call(resolveDashboardAttributeFilterReplacement, placeholder, attributeFilters, catalogDisplayForms, attributeFilterConfigs, ctx)));
|
|
231
|
+
return yield all(attributeFilterPlaceholders.map((placeholder) => call(resolveDashboardAttributeFilterReplacement, placeholder, attributeFilters, restrictedLocalIdentifiers, catalogDisplayForms, attributeFilterConfigs, ctx)));
|
|
234
232
|
}
|
|
235
|
-
function resolveDashboardMeasureValueFilterReplacement({ placeholder: toBeReplaced, identifier }, measureValueFilters, catalogMeasures) {
|
|
236
|
-
const
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
const
|
|
233
|
+
function resolveDashboardMeasureValueFilterReplacement({ placeholder: toBeReplaced, identifier }, measureValueFilters, restrictedLocalIdentifiers, catalogMeasures) {
|
|
234
|
+
const isPlaceholderFilter = (filter) => dashboardMeasureValueFilterMatchesIdentifier(filter.dashboardMeasureValueFilter.measure, identifier, catalogMeasures);
|
|
235
|
+
const usedFilter = measureValueFilters.find((filter) => !restrictedLocalIdentifiers.has(dashboardMeasureValueFilterLocalIdentifier(filter)) &&
|
|
236
|
+
isPlaceholderFilter(filter));
|
|
237
|
+
// A restricted filter is applied nowhere, so it filters nothing and resolves as "ALL". A
|
|
238
|
+
// placeholder whose filter is missing from the dashboard stays unresolved, which rejects the drill.
|
|
239
|
+
const parsedFilter = usedFilter || measureValueFilters.some(isPlaceholderFilter)
|
|
240
|
+
? stringifyMeasureValueFilterCondition(usedFilter?.dashboardMeasureValueFilter.conditions)
|
|
241
|
+
: undefined;
|
|
242
|
+
const replacement = encodeParameterIfSet(parsedFilter);
|
|
242
243
|
return {
|
|
243
244
|
toBeReplaced,
|
|
244
245
|
replacement: replacement,
|
|
@@ -250,8 +251,9 @@ export function* getDashboardMeasureValueFilterReplacements(url) {
|
|
|
250
251
|
return [];
|
|
251
252
|
}
|
|
252
253
|
const measureValueFilters = yield select(selectFilterContextMeasureValueFilters);
|
|
254
|
+
const restrictedLocalIdentifiers = yield select(selectRestrictedDashboardFilterLocalIdentifiers);
|
|
253
255
|
const catalogMeasures = yield select(selectAllCatalogMeasuresMap);
|
|
254
|
-
return measureValueFilterPlaceholders.map((placeholder) => resolveDashboardMeasureValueFilterReplacement(placeholder, measureValueFilters, catalogMeasures));
|
|
256
|
+
return measureValueFilterPlaceholders.map((placeholder) => resolveDashboardMeasureValueFilterReplacement(placeholder, measureValueFilters, restrictedLocalIdentifiers, catalogMeasures));
|
|
255
257
|
}
|
|
256
258
|
function resolveInsightMeasureValueFilterReplacement({ placeholder: toBeReplaced, identifier }, measureValueFilters) {
|
|
257
259
|
const usedFilter = measureValueFilters.find((filter) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"changeAttributeFilterSelectionHandler.d.ts","sourceRoot":"","sources":["../../../../../src/model/commandHandlers/filterContext/attributeFilter/changeAttributeFilterSelectionHandler.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAI/C,OAAO,EAAE,KAAK,8BAA8B,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"changeAttributeFilterSelectionHandler.d.ts","sourceRoot":"","sources":["../../../../../src/model/commandHandlers/filterContext/attributeFilter/changeAttributeFilterSelectionHandler.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAI/C,OAAO,EAAE,KAAK,8BAA8B,EAAE,MAAM,8BAA8B,CAAC;AAmBnF,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAStE,wBAAiB,qCAAqC,CAClD,GAAG,EAAE,gBAAgB,EACrB,GAAG,EAAE,8BAA8B,GACpC,YAAY,CAAC,IAAI,CAAC,CA4FpB"}
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
// (C) 2021-
|
|
1
|
+
// (C) 2021-2026 GoodData Corporation
|
|
2
2
|
import { all, call, put, select } from "redux-saga/effects";
|
|
3
3
|
import { invariant } from "ts-invariant";
|
|
4
4
|
import { attributeFilterSelectionChanged } from "../../../events/filters.js";
|
|
5
5
|
import { invalidArgumentsProvided } from "../../../events/general.js";
|
|
6
6
|
import { dispatchDashboardEvent } from "../../../store/_infra/eventDispatcher.js";
|
|
7
7
|
import { selectEnableImmediateAttributeFilterDisplayAsLabelMigration, selectIsApplyFiltersAllAtOnceEnabledAndSet, } from "../../../store/config/configSelectors.js";
|
|
8
|
-
import { selectIsCrossFiltering, selectIsFilterFromCrossFilteringByLocalIdentifier, } from "../../../store/drill/drillSelectors.js";
|
|
8
|
+
import { selectCrossFilteringFiltersLocalIdentifiersByTab, selectIsCrossFiltering, selectIsFilterFromCrossFilteringByLocalIdentifier, } from "../../../store/drill/drillSelectors.js";
|
|
9
|
+
import { selectEnablePersistentFiltersAcrossTabs } from "../../../store/meta/metaSelectors.js";
|
|
9
10
|
import { selectAttributeFilterDescendants, selectFilterContextAttributeFilterByLocalId, } from "../../../store/tabs/filterContext/filterContextSelectors.js";
|
|
10
11
|
import { tabsActions } from "../../../store/tabs/index.js";
|
|
11
|
-
import { dispatchFilterContextChanged, resetCrossFiltering } from "../common.js";
|
|
12
|
+
import { captureFilterContextByTabSnapshot, dispatchFilterContextChanged, dispatchFilterContextChangedForMutatedTabs, resetCrossFiltering, } from "../common.js";
|
|
12
13
|
export function* changeAttributeFilterSelectionHandler(ctx, cmd) {
|
|
13
14
|
const { elements, filterLocalId, selectionType, isWorkingSelectionChange, isResultOfMigration, isSelectionInvalid, } = cmd.payload;
|
|
14
15
|
// validate filterLocalId
|
|
@@ -18,6 +19,9 @@ export function* changeAttributeFilterSelectionHandler(ctx, cmd) {
|
|
|
18
19
|
}
|
|
19
20
|
const isApplyAllAtOnceEnabledAndSet = yield select(selectIsApplyFiltersAllAtOnceEnabledAndSet);
|
|
20
21
|
const enableImmediateAttributeFilterDisplayAsLabelMigration = yield select(selectEnableImmediateAttributeFilterDisplayAsLabelMigration);
|
|
22
|
+
const crossFilteringLocalIdsByTab = yield select(selectCrossFilteringFiltersLocalIdentifiersByTab);
|
|
23
|
+
const enablePersistentFiltersAcrossTabs = yield select(selectEnablePersistentFiltersAcrossTabs);
|
|
24
|
+
const filterContextSnapshot = yield call(captureFilterContextByTabSnapshot);
|
|
21
25
|
yield put(tabsActions.updateAttributeFilterSelection({
|
|
22
26
|
elements,
|
|
23
27
|
filterLocalId,
|
|
@@ -26,6 +30,8 @@ export function* changeAttributeFilterSelectionHandler(ctx, cmd) {
|
|
|
26
30
|
enableImmediateAttributeFilterDisplayAsLabelMigration,
|
|
27
31
|
isResultOfMigration,
|
|
28
32
|
isSelectionInvalid,
|
|
33
|
+
crossFilteringLocalIdsByTab,
|
|
34
|
+
enablePersistentFiltersAcrossTabs,
|
|
29
35
|
}));
|
|
30
36
|
const changedFilter = yield select(selectFilterContextAttributeFilterByLocalId(cmd.payload.filterLocalId));
|
|
31
37
|
invariant(changedFilter, "Inconsistent state in attributeFilterChangeSelectionCommandHandler");
|
|
@@ -38,6 +44,8 @@ export function* changeAttributeFilterSelectionHandler(ctx, cmd) {
|
|
|
38
44
|
},
|
|
39
45
|
negativeSelection: true,
|
|
40
46
|
isWorkingSelectionChange: isWorkingSelectionChange && isApplyAllAtOnceEnabledAndSet,
|
|
47
|
+
crossFilteringLocalIdsByTab,
|
|
48
|
+
enablePersistentFiltersAcrossTabs,
|
|
41
49
|
}))));
|
|
42
50
|
}
|
|
43
51
|
const isCrossFiltering = yield select(selectIsCrossFiltering);
|
|
@@ -48,5 +56,10 @@ export function* changeAttributeFilterSelectionHandler(ctx, cmd) {
|
|
|
48
56
|
yield call(resetCrossFiltering, cmd);
|
|
49
57
|
}
|
|
50
58
|
yield dispatchDashboardEvent(attributeFilterSelectionChanged(ctx, changedFilter, cmd.correlationId));
|
|
51
|
-
|
|
59
|
+
if (enablePersistentFiltersAcrossTabs) {
|
|
60
|
+
yield call(dispatchFilterContextChangedForMutatedTabs, ctx, cmd, filterContextSnapshot);
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
yield call(dispatchFilterContextChanged, ctx, cmd);
|
|
64
|
+
}
|
|
52
65
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"replaceAttributeFilterItemSelectionHandler.d.ts","sourceRoot":"","sources":["../../../../../src/model/commandHandlers/filterContext/attributeFilter/replaceAttributeFilterItemSelectionHandler.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAK/C,OAAO,EAAE,KAAK,mCAAmC,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"replaceAttributeFilterItemSelectionHandler.d.ts","sourceRoot":"","sources":["../../../../../src/model/commandHandlers/filterContext/attributeFilter/replaceAttributeFilterItemSelectionHandler.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAK/C,OAAO,EAAE,KAAK,mCAAmC,EAAE,MAAM,8BAA8B,CAAC;AAaxF,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAKtE,wBAAiB,0CAA0C,CACvD,GAAG,EAAE,gBAAgB,EACrB,GAAG,EAAE,mCAAmC,GACzC,YAAY,CAAC,IAAI,CAAC,CA0DpB"}
|
|
@@ -5,7 +5,8 @@ import { attributeFilterItemSelectionReplaced } from "../../../events/filters.js
|
|
|
5
5
|
import { invalidArgumentsProvided } from "../../../events/general.js";
|
|
6
6
|
import { dispatchDashboardEvent } from "../../../store/_infra/eventDispatcher.js";
|
|
7
7
|
import { selectIsApplyFiltersAllAtOnceEnabledAndSet } from "../../../store/config/configSelectors.js";
|
|
8
|
-
import { selectIsCrossFiltering, selectIsFilterFromCrossFilteringByLocalIdentifier, } from "../../../store/drill/drillSelectors.js";
|
|
8
|
+
import { selectCrossFilteringFiltersLocalIdentifiersByTab, selectIsCrossFiltering, selectIsFilterFromCrossFilteringByLocalIdentifier, } from "../../../store/drill/drillSelectors.js";
|
|
9
|
+
import { selectEnablePersistentFiltersAcrossTabs } from "../../../store/meta/metaSelectors.js";
|
|
9
10
|
import { selectFilterContextAttributeFilterItemByLocalId } from "../../../store/tabs/filterContext/filterContextSelectors.js";
|
|
10
11
|
import { tabsActions } from "../../../store/tabs/index.js";
|
|
11
12
|
import { dispatchFilterContextChanged, resetCrossFiltering } from "../common.js";
|
|
@@ -18,11 +19,15 @@ export function* replaceAttributeFilterItemSelectionHandler(ctx, cmd) {
|
|
|
18
19
|
throw invalidArgumentsProvided(ctx, cmd, `Filter with filterLocalId ${filterLocalId} not found.`);
|
|
19
20
|
}
|
|
20
21
|
const isApplyAllAtOnceEnabledAndSet = yield select(selectIsApplyFiltersAllAtOnceEnabledAndSet);
|
|
22
|
+
const crossFilteringLocalIdsByTab = yield select(selectCrossFilteringFiltersLocalIdentifiersByTab);
|
|
23
|
+
const enablePersistentFiltersAcrossTabs = yield select(selectEnablePersistentFiltersAcrossTabs);
|
|
21
24
|
yield put(tabsActions.replaceAttributeFilterItem({
|
|
22
25
|
filterLocalId,
|
|
23
26
|
filter,
|
|
24
27
|
isWorkingSelectionChange: isWorkingSelectionChange && isApplyAllAtOnceEnabledAndSet,
|
|
25
28
|
isSelectionInvalid,
|
|
29
|
+
crossFilteringLocalIdsByTab,
|
|
30
|
+
enablePersistentFiltersAcrossTabs,
|
|
26
31
|
}));
|
|
27
32
|
// Ensure the new filter's displayForm is registered in the displayFormsMap.
|
|
28
33
|
// This is needed for cross-type migration (e.g. text→list) where the new filter's
|