@gooddata/sdk-ui-dashboard 11.58.0-alpha.1 → 11.58.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 +9 -9
- package/esm/__version.d.ts +1 -1
- package/esm/__version.js +1 -1
- package/esm/_staging/sharedHooks/useFiltersNamings.d.ts.map +1 -1
- package/esm/_staging/sharedHooks/useFiltersNamings.js +5 -3
- package/esm/index.d.ts +4 -4
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +2 -2
- package/esm/model/DashboardTester.d.ts.map +1 -1
- package/esm/model/DashboardTester.js +7 -1
- package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/index.d.ts.map +1 -1
- package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/index.js +13 -6
- package/esm/model/commandHandlers/parameters/filterParameterDependenciesWorker.d.ts +45 -0
- package/esm/model/commandHandlers/parameters/filterParameterDependenciesWorker.d.ts.map +1 -0
- package/esm/model/commandHandlers/parameters/filterParameterDependenciesWorker.js +99 -0
- package/esm/model/commandHandlers/parameters/insightParameterDependenciesWorker.d.ts +11 -0
- package/esm/model/commandHandlers/parameters/insightParameterDependenciesWorker.d.ts.map +1 -0
- package/esm/model/commandHandlers/parameters/insightParameterDependenciesWorker.js +71 -0
- package/esm/model/commandHandlers/parameters/loadFilterParameterDependencies.d.ts +22 -0
- package/esm/model/commandHandlers/parameters/loadFilterParameterDependencies.d.ts.map +1 -0
- package/esm/model/commandHandlers/parameters/loadFilterParameterDependencies.js +39 -0
- package/esm/model/commandHandlers/parameters/loadInsightParameterDependencies.d.ts +21 -0
- package/esm/model/commandHandlers/parameters/loadInsightParameterDependencies.d.ts.map +1 -0
- package/esm/model/commandHandlers/parameters/loadInsightParameterDependencies.js +86 -0
- package/esm/model/react/useInitializeDashboardStore.d.ts.map +1 -1
- package/esm/model/react/useInitializeDashboardStore.js +4 -0
- package/esm/model/react/useIsWidgetRestricted.d.ts.map +1 -1
- package/esm/model/react/useIsWidgetRestricted.js +14 -7
- package/esm/model/react/useWidgetExecConfig.d.ts +4 -4
- package/esm/model/react/useWidgetExecConfig.d.ts.map +1 -1
- package/esm/model/react/useWidgetExecConfig.js +2 -2
- package/esm/model/store/catalog/catalogReducers.d.ts +16 -4
- package/esm/model/store/catalog/catalogReducers.d.ts.map +1 -1
- package/esm/model/store/catalog/catalogReducers.js +15 -3
- package/esm/model/store/catalog/catalogSelectors.d.ts +21 -6
- package/esm/model/store/catalog/catalogSelectors.d.ts.map +1 -1
- package/esm/model/store/catalog/catalogSelectors.js +20 -5
- package/esm/model/store/catalog/catalogState.d.ts +30 -9
- package/esm/model/store/catalog/catalogState.d.ts.map +1 -1
- package/esm/model/store/catalog/catalogState.js +2 -1
- package/esm/model/store/catalog/index.d.ts +4 -1
- package/esm/model/store/catalog/index.d.ts.map +1 -1
- package/esm/model/store/tabs/layout/layoutSelectors.d.ts +10 -0
- package/esm/model/store/tabs/layout/layoutSelectors.d.ts.map +1 -1
- package/esm/model/store/tabs/layout/layoutSelectors.js +55 -26
- package/esm/model/store/tabs/parameters/parametersHelpers.d.ts +42 -8
- package/esm/model/store/tabs/parameters/parametersHelpers.d.ts.map +1 -1
- package/esm/model/store/tabs/parameters/parametersHelpers.js +88 -19
- package/esm/model/store/tabs/parameters/parametersSelectors.d.ts +13 -6
- package/esm/model/store/tabs/parameters/parametersSelectors.d.ts.map +1 -1
- package/esm/model/store/tabs/parameters/parametersSelectors.js +24 -13
- package/esm/presentation/automations/shared/automationFilters/components/AutomationAttributeFilter.d.ts.map +1 -1
- package/esm/presentation/automations/shared/automationFilters/components/AutomationAttributeFilter.js +16 -2
- package/esm/presentation/automations/shared/hooks/useFiltersNamings.d.ts.map +1 -1
- package/esm/presentation/automations/shared/hooks/useFiltersNamings.js +5 -3
- package/esm/presentation/flexibleLayout/DefaultDashboardLayoutRenderer/EditableHeader/SectionHeaderEditable.d.ts.map +1 -1
- package/esm/presentation/flexibleLayout/DefaultDashboardLayoutRenderer/EditableHeader/SectionHeaderEditable.js +35 -13
- package/esm/presentation/localization/bundles/de-DE.localization-bundle.d.ts +3 -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 +5 -2
- package/esm/presentation/localization/bundles/en-AU.localization-bundle.d.ts +3 -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 +5 -2
- package/esm/presentation/localization/bundles/en-GB.localization-bundle.d.ts +3 -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 +5 -2
- package/esm/presentation/localization/bundles/en-US.localization-bundle.d.ts +12 -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 +14 -2
- package/esm/presentation/localization/bundles/es-419.localization-bundle.d.ts +3 -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 +5 -2
- package/esm/presentation/localization/bundles/es-ES.localization-bundle.d.ts +3 -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 +5 -2
- package/esm/presentation/localization/bundles/fi-FI.localization-bundle.d.ts +3 -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 +5 -2
- package/esm/presentation/localization/bundles/fr-CA.localization-bundle.d.ts +3 -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 +5 -2
- package/esm/presentation/localization/bundles/fr-FR.localization-bundle.d.ts +3 -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 +5 -2
- package/esm/presentation/localization/bundles/id-ID.localization-bundle.d.ts +3 -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 +5 -2
- package/esm/presentation/localization/bundles/it-IT.localization-bundle.d.ts +3 -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 +5 -2
- package/esm/presentation/localization/bundles/ja-JP.localization-bundle.d.ts +3 -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 +5 -2
- package/esm/presentation/localization/bundles/ko-KR.localization-bundle.d.ts +3 -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 +5 -2
- package/esm/presentation/localization/bundles/nl-NL.localization-bundle.d.ts +3 -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 +5 -2
- package/esm/presentation/localization/bundles/pl-PL.localization-bundle.d.ts +3 -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 +5 -2
- package/esm/presentation/localization/bundles/pt-BR.localization-bundle.d.ts +3 -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 +5 -2
- package/esm/presentation/localization/bundles/pt-PT.localization-bundle.d.ts +3 -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 +5 -2
- package/esm/presentation/localization/bundles/ru-RU.localization-bundle.d.ts +3 -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 +5 -2
- package/esm/presentation/localization/bundles/sl-SI.localization-bundle.d.ts +3 -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 +5 -2
- package/esm/presentation/localization/bundles/th-TH.localization-bundle.d.ts +3 -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 +5 -2
- package/esm/presentation/localization/bundles/tr-TR.localization-bundle.d.ts +3 -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 +5 -2
- package/esm/presentation/localization/bundles/uk-UA.localization-bundle.d.ts +3 -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 +5 -2
- package/esm/presentation/localization/bundles/vi-VN.localization-bundle.d.ts +3 -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 +5 -2
- package/esm/presentation/localization/bundles/zh-HK.localization-bundle.d.ts +3 -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 +5 -2
- package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.d.ts +3 -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 +5 -2
- package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.d.ts +3 -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 +5 -2
- package/esm/presentation/widget/common/RestrictedPlaceholder.d.ts +4 -8
- package/esm/presentation/widget/common/RestrictedPlaceholder.d.ts.map +1 -1
- package/esm/presentation/widget/common/RestrictedPlaceholder.js +16 -23
- package/esm/presentation/widget/insight/DefaultInsightBody/DefaultInsightBody.d.ts.map +1 -1
- package/esm/presentation/widget/insight/DefaultInsightBody/DefaultInsightBody.js +2 -4
- package/esm/presentation/widget/insight/LayeredTableView.d.ts +1 -1
- package/esm/presentation/widget/insight/LayeredTableView.d.ts.map +1 -1
- package/esm/presentation/widget/insight/ViewModeDashboardInsight/InsightDrillDialog/DrillDialogInsight.d.ts.map +1 -1
- package/esm/presentation/widget/insight/ViewModeDashboardInsight/InsightDrillDialog/DrillDialogInsight.js +2 -3
- package/esm/presentation/widget/insight/ViewModeDashboardInsight/InsightDrillDialog/InsightDrillDialog.d.ts.map +1 -1
- package/esm/presentation/widget/insight/ViewModeDashboardInsight/InsightDrillDialog/InsightDrillDialog.js +1 -1
- package/esm/presentation/widget/insight/configuration/InsightDescriptionConfig/InsightDescription.d.ts.map +1 -1
- package/esm/presentation/widget/insight/configuration/InsightDescriptionConfig/InsightDescription.js +30 -12
- package/esm/presentation/widget/insight/types.d.ts +1 -1
- package/esm/presentation/widget/insight/types.d.ts.map +1 -1
- package/esm/presentation/widget/richText/EditModeDashboardRichText.d.ts.map +1 -1
- package/esm/presentation/widget/richText/EditModeDashboardRichText.js +18 -6
- package/esm/presentation/widget/richText/RestrictedReferencesDialog.d.ts +22 -0
- package/esm/presentation/widget/richText/RestrictedReferencesDialog.d.ts.map +1 -0
- package/esm/presentation/widget/richText/RestrictedReferencesDialog.js +41 -0
- package/esm/presentation/widget/richText/useEditableRichTextMenu.d.ts.map +1 -1
- package/esm/presentation/widget/richText/useEditableRichTextMenu.js +6 -2
- package/esm/presentation/widget/visualizationSwitcher/ViewModeDashboardVisualizationSwitcher.js +1 -1
- package/esm/presentation/widget/visualizationSwitcher/configuration/VisualizationsList/VisualizationListItem.d.ts.map +1 -1
- package/esm/presentation/widget/visualizationSwitcher/configuration/VisualizationsList/VisualizationListItem.js +1 -4
- package/esm/presentation/widget/widget/InsightWidget/DefaultDashboardInsightWidget.js +2 -3
- package/esm/sdk-ui-dashboard.d.ts +99 -42
- package/package.json +23 -23
- package/styles/css/main.css +28 -16
- package/styles/css/main.css.map +1 -1
- package/styles/css/richTextWidget.css +4 -0
- package/styles/css/richTextWidget.css.map +1 -1
- package/styles/scss/richTextWidget.scss +5 -1
- package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/loadMeasureParameterDependencies.d.ts +0 -13
- package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/loadMeasureParameterDependencies.d.ts.map +0 -1
- package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/loadMeasureParameterDependencies.js +0 -98
- package/esm/presentation/widget/insight/geoDefaultDisplayFormRefs.d.ts +0 -5
- package/esm/presentation/widget/insight/geoDefaultDisplayFormRefs.d.ts.map +0 -1
- package/esm/presentation/widget/insight/geoDefaultDisplayFormRefs.js +0 -28
- package/esm/presentation/widget/insight/insightToTable.d.ts +0 -74
- package/esm/presentation/widget/insight/insightToTable.d.ts.map +0 -1
- package/esm/presentation/widget/insight/insightToTable.js +0 -482
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { type SagaIterator } from "redux-saga";
|
|
2
|
+
import { type DashboardContext } from "../../types/commonTypes.js";
|
|
3
|
+
/**
|
|
4
|
+
* Keeps the dashboard-filter → parameter dependency map complete as the filter contexts change.
|
|
5
|
+
*
|
|
6
|
+
* @remarks
|
|
7
|
+
* Counterpart of {@link newInsightParameterDependenciesWorker} for dashboard filters. After any write
|
|
8
|
+
* to the tabs slice it collects the objects the current filters of every tab read and loads the ones
|
|
9
|
+
* the map does not know yet, so a widget picks up a parameter it now depends on through a filter added
|
|
10
|
+
* or changed after initialization (edit mode, an applied filter view, a new tab). Removing a filter
|
|
11
|
+
* needs nothing: the map is keyed by the object a filter reads, not by the filter, and a widget only
|
|
12
|
+
* consults the entries of the filters it currently has. A failed load leaves the map as it is, so the
|
|
13
|
+
* dependencies known so far stay in effect; the failed roots are not retried until the map is
|
|
14
|
+
* initialized again (a dashboard reload), so a filter on an object the graph rejects does not trigger a
|
|
15
|
+
* request on every later write.
|
|
16
|
+
*/
|
|
17
|
+
export declare function newFilterParameterDependenciesWorker(): (ctx: DashboardContext) => SagaIterator<void>;
|
|
18
|
+
/**
|
|
19
|
+
* The roots one store has already requested but that are not in the map: those in flight and those whose
|
|
20
|
+
* request failed. Neither is requested again until {@link IFilterParameterRootTracker.reset}, which also
|
|
21
|
+
* starts a new generation so that a request still in flight from before the reset is discarded on
|
|
22
|
+
* completion instead of writing into the freshly initialized map.
|
|
23
|
+
*
|
|
24
|
+
* @internal
|
|
25
|
+
*/
|
|
26
|
+
export interface IFilterParameterRootTracker {
|
|
27
|
+
pending: Set<string>;
|
|
28
|
+
failed: Set<string>;
|
|
29
|
+
generation: number;
|
|
30
|
+
reset(): void;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* @internal
|
|
34
|
+
*/
|
|
35
|
+
export declare function newFilterParameterRootTracker(): IFilterParameterRootTracker;
|
|
36
|
+
/**
|
|
37
|
+
* Loads the dependencies of the filter roots the map does not know yet. A root is requested at most once
|
|
38
|
+
* between two initializations of the map: one in flight is skipped by the handlers that run meanwhile,
|
|
39
|
+
* and one the graph rejected (a deleted or forbidden object, typically) is remembered by the tracker
|
|
40
|
+
* rather than retried on every later write to the tabs slice. Only real results reach the map.
|
|
41
|
+
*
|
|
42
|
+
* @internal
|
|
43
|
+
*/
|
|
44
|
+
export declare function registerFilterParameterDependencies(ctx: DashboardContext, tracker: IFilterParameterRootTracker): SagaIterator<void>;
|
|
45
|
+
//# sourceMappingURL=filterParameterDependenciesWorker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filterParameterDependenciesWorker.d.ts","sourceRoot":"","sources":["../../../../src/model/commandHandlers/parameters/filterParameterDependenciesWorker.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAa/C,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AASnE;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oCAAoC,UACQ,gBAAgB,KAAG,YAAY,CAAC,IAAI,CAAC,CAShG;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,2BAA2B;IACxC,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACrB,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,IAAI,IAAI,CAAC;CACjB;AAED;;GAEG;AACH,wBAAgB,6BAA6B,IAAI,2BAA2B,CAa3E;AAED;;;;;;;GAOG;AACH,wBAAiB,mCAAmC,CAChD,GAAG,EAAE,gBAAgB,EACrB,OAAO,EAAE,2BAA2B,GACrC,YAAY,CAAC,IAAI,CAAC,CAuCpB"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
// (C) 2026 GoodData Corporation
|
|
2
|
+
import { call, put, select, takeEvery } from "redux-saga/effects";
|
|
3
|
+
import { serializeObjRef } from "@gooddata/sdk-model";
|
|
4
|
+
import { selectCatalogFilterParameters, selectCatalogFilterParametersStatus, } from "../../store/catalog/catalogSelectors.js";
|
|
5
|
+
import { catalogActions } from "../../store/catalog/index.js";
|
|
6
|
+
import { selectFiltersByTab } from "../../store/tabs/filterContext/filterContextSelectors.js";
|
|
7
|
+
import { tabsActions } from "../../store/tabs/index.js";
|
|
8
|
+
import { collectFilterParameterRoots } from "../../store/tabs/parameters/parametersHelpers.js";
|
|
9
|
+
import { unbatched } from "./insightParameterDependenciesWorker.js";
|
|
10
|
+
import { loadReachableParameterMap } from "./loadInsightParameterDependencies.js";
|
|
11
|
+
// every filter context write is a `tabs/*` action (the filter contexts live in the tabs slice)
|
|
12
|
+
const TABS_ACTION_PREFIX = `${tabsActions.setTabs.type.split("/")[0]}/`;
|
|
13
|
+
/**
|
|
14
|
+
* Keeps the dashboard-filter → parameter dependency map complete as the filter contexts change.
|
|
15
|
+
*
|
|
16
|
+
* @remarks
|
|
17
|
+
* Counterpart of {@link newInsightParameterDependenciesWorker} for dashboard filters. After any write
|
|
18
|
+
* to the tabs slice it collects the objects the current filters of every tab read and loads the ones
|
|
19
|
+
* the map does not know yet, so a widget picks up a parameter it now depends on through a filter added
|
|
20
|
+
* or changed after initialization (edit mode, an applied filter view, a new tab). Removing a filter
|
|
21
|
+
* needs nothing: the map is keyed by the object a filter reads, not by the filter, and a widget only
|
|
22
|
+
* consults the entries of the filters it currently has. A failed load leaves the map as it is, so the
|
|
23
|
+
* dependencies known so far stay in effect; the failed roots are not retried until the map is
|
|
24
|
+
* initialized again (a dashboard reload), so a filter on an object the graph rejects does not trigger a
|
|
25
|
+
* request on every later write.
|
|
26
|
+
*/
|
|
27
|
+
export function newFilterParameterDependenciesWorker() {
|
|
28
|
+
return function* filterParameterDependenciesWorker(ctx) {
|
|
29
|
+
const tracker = newFilterParameterRootTracker();
|
|
30
|
+
yield takeEvery(catalogActions.setCatalogFilterParameters.match, function onMapReset() {
|
|
31
|
+
tracker.reset();
|
|
32
|
+
});
|
|
33
|
+
yield takeEvery(writesTabs, function* onTabsWritten() {
|
|
34
|
+
yield call(registerFilterParameterDependencies, ctx, tracker);
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* @internal
|
|
40
|
+
*/
|
|
41
|
+
export function newFilterParameterRootTracker() {
|
|
42
|
+
const pending = new Set();
|
|
43
|
+
const failed = new Set();
|
|
44
|
+
return {
|
|
45
|
+
pending,
|
|
46
|
+
failed,
|
|
47
|
+
generation: 0,
|
|
48
|
+
reset() {
|
|
49
|
+
pending.clear();
|
|
50
|
+
failed.clear();
|
|
51
|
+
this.generation += 1;
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Loads the dependencies of the filter roots the map does not know yet. A root is requested at most once
|
|
57
|
+
* between two initializations of the map: one in flight is skipped by the handlers that run meanwhile,
|
|
58
|
+
* and one the graph rejected (a deleted or forbidden object, typically) is remembered by the tracker
|
|
59
|
+
* rather than retried on every later write to the tabs slice. Only real results reach the map.
|
|
60
|
+
*
|
|
61
|
+
* @internal
|
|
62
|
+
*/
|
|
63
|
+
export function* registerFilterParameterDependencies(ctx, tracker) {
|
|
64
|
+
const status = yield select(selectCatalogFilterParametersStatus);
|
|
65
|
+
if (status !== "loaded") {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const filtersByTab = yield select(selectFiltersByTab);
|
|
69
|
+
const known = yield select(selectCatalogFilterParameters);
|
|
70
|
+
const unknownRoots = collectFilterParameterRoots(Object.values(filtersByTab).flat()).filter((root) => {
|
|
71
|
+
const key = serializeObjRef(root);
|
|
72
|
+
return !(key in known) && !tracker.pending.has(key) && !tracker.failed.has(key);
|
|
73
|
+
});
|
|
74
|
+
if (unknownRoots.length === 0) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const keys = unknownRoots.map(serializeObjRef);
|
|
78
|
+
const generation = tracker.generation;
|
|
79
|
+
keys.forEach((key) => tracker.pending.add(key));
|
|
80
|
+
try {
|
|
81
|
+
const byRef = yield call(loadReachableParameterMap, ctx, unknownRoots);
|
|
82
|
+
if (tracker.generation === generation) {
|
|
83
|
+
yield put(catalogActions.mergeCatalogFilterParameters(byRef));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
if (tracker.generation === generation) {
|
|
88
|
+
keys.forEach((key) => tracker.failed.add(key));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
finally {
|
|
92
|
+
if (tracker.generation === generation) {
|
|
93
|
+
keys.forEach((key) => tracker.pending.delete(key));
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
function writesTabs(action) {
|
|
98
|
+
return unbatched(action).some((item) => item.type.startsWith(TABS_ACTION_PREFIX));
|
|
99
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type Action } from "@reduxjs/toolkit";
|
|
2
|
+
import { type SagaIterator } from "redux-saga";
|
|
3
|
+
import { type DashboardContext } from "../../types/commonTypes.js";
|
|
4
|
+
export declare function newInsightParameterDependenciesWorker(): (ctx: DashboardContext) => SagaIterator<void>;
|
|
5
|
+
/**
|
|
6
|
+
* The plain actions an action stands for: itself, or the (recursively unbatched) members of a batch.
|
|
7
|
+
*
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
10
|
+
export declare function unbatched(action: Action): Action[];
|
|
11
|
+
//# sourceMappingURL=insightParameterDependenciesWorker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"insightParameterDependenciesWorker.d.ts","sourceRoot":"","sources":["../../../../src/model/commandHandlers/parameters/insightParameterDependenciesWorker.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE/C,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAW/C,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAKnE,wBAAgB,qCAAqC,UACQ,gBAAgB,KAAG,YAAY,CAAC,IAAI,CAAC,CAKjG;AA4DD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAElD"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// (C) 2026 GoodData Corporation
|
|
2
|
+
import { call, put, select, takeEvery } from "redux-saga/effects";
|
|
3
|
+
import { insightRef, serializeObjRef } from "@gooddata/sdk-model";
|
|
4
|
+
import { selectCatalogInsightParameters, selectCatalogInsightParametersStatus, } from "../../store/catalog/catalogSelectors.js";
|
|
5
|
+
import { catalogActions } from "../../store/catalog/index.js";
|
|
6
|
+
import { insightsActions } from "../../store/insights/index.js";
|
|
7
|
+
import { loadInsightParameterDependencies } from "./loadInsightParameterDependencies.js";
|
|
8
|
+
export function newInsightParameterDependenciesWorker() {
|
|
9
|
+
return function* insightParameterDependenciesWorker(ctx) {
|
|
10
|
+
yield takeEvery(writesInsights, function* onInsightsWritten(action) {
|
|
11
|
+
yield call(registerInsightParameterDependencies, ctx, action);
|
|
12
|
+
});
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function* registerInsightParameterDependencies(ctx, action) {
|
|
16
|
+
const status = yield select(selectCatalogInsightParametersStatus);
|
|
17
|
+
if (status !== "loaded") {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const known = yield select(selectCatalogInsightParameters);
|
|
21
|
+
const insights = [
|
|
22
|
+
...writtenInsights(action),
|
|
23
|
+
...replacedInsights(action).filter((insight) => !(serializeObjRef(insightRef(insight)) in known)),
|
|
24
|
+
];
|
|
25
|
+
if (insights.length === 0) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const dependencies = yield call(loadInsightParameterDependencies, ctx, insights, true);
|
|
29
|
+
if (dependencies.status === "loaded") {
|
|
30
|
+
yield put(catalogActions.mergeCatalogInsightParameters(dependencies.byInsight));
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function writesInsights(action) {
|
|
34
|
+
return writtenInsights(action).length > 0 || replacedInsights(action).length > 0;
|
|
35
|
+
}
|
|
36
|
+
function writtenInsights(action) {
|
|
37
|
+
return unbatched(action).flatMap(writtenInsightsOf);
|
|
38
|
+
}
|
|
39
|
+
function writtenInsightsOf(action) {
|
|
40
|
+
if (insightsActions.addInsights.match(action)) {
|
|
41
|
+
return entityPayloadInsights(action.payload);
|
|
42
|
+
}
|
|
43
|
+
if (insightsActions.upsertInsight.match(action)) {
|
|
44
|
+
return [action.payload];
|
|
45
|
+
}
|
|
46
|
+
return [];
|
|
47
|
+
}
|
|
48
|
+
function replacedInsights(action) {
|
|
49
|
+
return unbatched(action).flatMap(replacedInsightsOf);
|
|
50
|
+
}
|
|
51
|
+
function replacedInsightsOf(action) {
|
|
52
|
+
return insightsActions.setInsights.match(action) ? entityPayloadInsights(action.payload) : [];
|
|
53
|
+
}
|
|
54
|
+
function entityPayloadInsights(payload) {
|
|
55
|
+
return Array.isArray(payload) ? [...payload] : Object.values(payload);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* The plain actions an action stands for: itself, or the (recursively unbatched) members of a batch.
|
|
59
|
+
*
|
|
60
|
+
* @internal
|
|
61
|
+
*/
|
|
62
|
+
export function unbatched(action) {
|
|
63
|
+
return isBatchAction(action) ? action.payload.flatMap(unbatched) : [action];
|
|
64
|
+
}
|
|
65
|
+
function isBatchAction(action) {
|
|
66
|
+
return ("meta" in action &&
|
|
67
|
+
typeof action.meta === "object" &&
|
|
68
|
+
action.meta !== null &&
|
|
69
|
+
"batch" in action.meta &&
|
|
70
|
+
action.meta.batch === true);
|
|
71
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type FilterContextItem, type IDashboard } from "@gooddata/sdk-model";
|
|
2
|
+
import { type ICatalogFilterParametersState } from "../../store/catalog/catalogState.js";
|
|
3
|
+
import { type DashboardContext } from "../../types/commonTypes.js";
|
|
4
|
+
/**
|
|
5
|
+
* Loads the dashboard-wide dashboard-filter → parameter dependency map from the workspace references
|
|
6
|
+
* service.
|
|
7
|
+
*
|
|
8
|
+
* @remarks
|
|
9
|
+
* A dashboard filter is not part of any insight, so the insight-rooted map cannot see the parameters a
|
|
10
|
+
* widget depends on through it. The roots are the objects the filters read (see
|
|
11
|
+
* {@link collectFilterParameterRoots}); they go to the service in the same single `direction: "down"`
|
|
12
|
+
* request shape as the insight roots, and the map is keyed by `serializeObjRef(root)`. Disabled
|
|
13
|
+
* parameters return `uninitialized`; backend errors return `failed`.
|
|
14
|
+
*/
|
|
15
|
+
export declare function loadFilterParameterDependencies(ctx: DashboardContext, filters: ReadonlyArray<FilterContextItem>, enableParameters: boolean): Promise<ICatalogFilterParametersState>;
|
|
16
|
+
/**
|
|
17
|
+
* Every dashboard filter of the dashboard being initialized: the filters of each tab plus those of the root
|
|
18
|
+
* filter context. The root context is the single tab of a dashboard without tabs, and the tab state keeps
|
|
19
|
+
* it as a default tab even when tabs exist, so it is always included; roots are deduped downstream.
|
|
20
|
+
*/
|
|
21
|
+
export declare function collectDashboardFilterContextItems(dashboard: IDashboard): FilterContextItem[];
|
|
22
|
+
//# sourceMappingURL=loadFilterParameterDependencies.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadFilterParameterDependencies.d.ts","sourceRoot":"","sources":["../../../../src/model/commandHandlers/parameters/loadFilterParameterDependencies.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAE9E,OAAO,EAAE,KAAK,6BAA6B,EAAE,MAAM,qCAAqC,CAAC;AAEzF,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAInE;;;;;;;;;;GAUG;AACH,wBAAsB,+BAA+B,CACjD,GAAG,EAAE,gBAAgB,EACrB,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,EACzC,gBAAgB,EAAE,OAAO,GAC1B,OAAO,CAAC,6BAA6B,CAAC,CAgBxC;AAED;;;;GAIG;AACH,wBAAgB,kCAAkC,CAAC,SAAS,EAAE,UAAU,GAAG,iBAAiB,EAAE,CAG7F"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// (C) 2026 GoodData Corporation
|
|
2
|
+
import { collectFilterParameterRoots } from "../../store/tabs/parameters/parametersHelpers.js";
|
|
3
|
+
import { loadReachableParameterMap } from "./loadInsightParameterDependencies.js";
|
|
4
|
+
/**
|
|
5
|
+
* Loads the dashboard-wide dashboard-filter → parameter dependency map from the workspace references
|
|
6
|
+
* service.
|
|
7
|
+
*
|
|
8
|
+
* @remarks
|
|
9
|
+
* A dashboard filter is not part of any insight, so the insight-rooted map cannot see the parameters a
|
|
10
|
+
* widget depends on through it. The roots are the objects the filters read (see
|
|
11
|
+
* {@link collectFilterParameterRoots}); they go to the service in the same single `direction: "down"`
|
|
12
|
+
* request shape as the insight roots, and the map is keyed by `serializeObjRef(root)`. Disabled
|
|
13
|
+
* parameters return `uninitialized`; backend errors return `failed`.
|
|
14
|
+
*/
|
|
15
|
+
export async function loadFilterParameterDependencies(ctx, filters, enableParameters) {
|
|
16
|
+
if (!enableParameters) {
|
|
17
|
+
return { status: "uninitialized", byRef: {} };
|
|
18
|
+
}
|
|
19
|
+
const roots = collectFilterParameterRoots(filters);
|
|
20
|
+
if (roots.length === 0) {
|
|
21
|
+
return { status: "loaded", byRef: {} };
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
const byRef = await loadReachableParameterMap(ctx, roots);
|
|
25
|
+
return { status: "loaded", byRef };
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return { status: "failed", byRef: {} };
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Every dashboard filter of the dashboard being initialized: the filters of each tab plus those of the root
|
|
33
|
+
* filter context. The root context is the single tab of a dashboard without tabs, and the tab state keeps
|
|
34
|
+
* it as a default tab even when tabs exist, so it is always included; roots are deduped downstream.
|
|
35
|
+
*/
|
|
36
|
+
export function collectDashboardFilterContextItems(dashboard) {
|
|
37
|
+
const tabFilters = (dashboard.tabs ?? []).flatMap((tab) => tab.filterContext?.filters ?? []);
|
|
38
|
+
return [...tabFilters, ...(dashboard.filterContext?.filters ?? [])];
|
|
39
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type IInsight, type IdentifierRef } from "@gooddata/sdk-model";
|
|
2
|
+
import { type ICatalogInsightParametersState } from "../../store/catalog/catalogState.js";
|
|
3
|
+
import { type DashboardContext } from "../../types/commonTypes.js";
|
|
4
|
+
/**
|
|
5
|
+
* Loads the dashboard-wide insight -> parameter dependency map from the workspace references service.
|
|
6
|
+
*
|
|
7
|
+
* @remarks
|
|
8
|
+
* Walks the dependency graph in `direction: "down"` from each insight, then collects the parameter
|
|
9
|
+
* nodes reachable from it through metrics and computed attributes. Disabled parameters return
|
|
10
|
+
* `uninitialized`; backend errors return `failed`.
|
|
11
|
+
*/
|
|
12
|
+
export declare function loadInsightParameterDependencies(ctx: DashboardContext, insights: IInsight[], enableParameters: boolean): Promise<ICatalogInsightParametersState>;
|
|
13
|
+
/**
|
|
14
|
+
* Asks the workspace references service for the dependency graph below `roots` (one request for all of
|
|
15
|
+
* them) and maps each root (keyed by `serializeObjRef`) to the parameter refs reachable from it. Throws
|
|
16
|
+
* when the service does; the caller decides how that degrades.
|
|
17
|
+
*
|
|
18
|
+
* @internal
|
|
19
|
+
*/
|
|
20
|
+
export declare function loadReachableParameterMap(ctx: DashboardContext, roots: IdentifierRef[]): Promise<Record<string, IdentifierRef[]>>;
|
|
21
|
+
//# sourceMappingURL=loadInsightParameterDependencies.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadInsightParameterDependencies.d.ts","sourceRoot":"","sources":["../../../../src/model/commandHandlers/parameters/loadInsightParameterDependencies.ts"],"names":[],"mappings":"AAGA,OAAO,EACH,KAAK,QAAQ,EACb,KAAK,aAAa,EAIrB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,KAAK,8BAA8B,EAAE,MAAM,qCAAqC,CAAC;AAC1F,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAEnE;;;;;;;GAOG;AACH,wBAAsB,gCAAgC,CAClD,GAAG,EAAE,gBAAgB,EACrB,QAAQ,EAAE,QAAQ,EAAE,EACpB,gBAAgB,EAAE,OAAO,GAC1B,OAAO,CAAC,8BAA8B,CAAC,CAgBzC;AAED;;;;;;GAMG;AACH,wBAAsB,yBAAyB,CAC3C,GAAG,EAAE,gBAAgB,EACrB,KAAK,EAAE,aAAa,EAAE,GACvB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC,CAO1C"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// (C) 2026 GoodData Corporation
|
|
2
|
+
import { insightRef, isIdentifierRef, serializeObjRef, } from "@gooddata/sdk-model";
|
|
3
|
+
/**
|
|
4
|
+
* Loads the dashboard-wide insight -> parameter dependency map from the workspace references service.
|
|
5
|
+
*
|
|
6
|
+
* @remarks
|
|
7
|
+
* Walks the dependency graph in `direction: "down"` from each insight, then collects the parameter
|
|
8
|
+
* nodes reachable from it through metrics and computed attributes. Disabled parameters return
|
|
9
|
+
* `uninitialized`; backend errors return `failed`.
|
|
10
|
+
*/
|
|
11
|
+
export async function loadInsightParameterDependencies(ctx, insights, enableParameters) {
|
|
12
|
+
if (!enableParameters) {
|
|
13
|
+
return { status: "uninitialized", byInsight: {} };
|
|
14
|
+
}
|
|
15
|
+
const roots = insights.map(insightRef).filter(isIdentifierRef);
|
|
16
|
+
if (roots.length === 0) {
|
|
17
|
+
return { status: "loaded", byInsight: {} };
|
|
18
|
+
}
|
|
19
|
+
try {
|
|
20
|
+
const byInsight = await loadReachableParameterMap(ctx, roots);
|
|
21
|
+
return { status: "loaded", byInsight };
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return { status: "failed", byInsight: {} };
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Asks the workspace references service for the dependency graph below `roots` (one request for all of
|
|
29
|
+
* them) and maps each root (keyed by `serializeObjRef`) to the parameter refs reachable from it. Throws
|
|
30
|
+
* when the service does; the caller decides how that degrades.
|
|
31
|
+
*
|
|
32
|
+
* @internal
|
|
33
|
+
*/
|
|
34
|
+
export async function loadReachableParameterMap(ctx, roots) {
|
|
35
|
+
const result = await ctx.backend
|
|
36
|
+
.workspace(ctx.workspace)
|
|
37
|
+
.references()
|
|
38
|
+
.getReferences(roots, { direction: "down" });
|
|
39
|
+
return buildReachableParameterMap(roots, result.edges);
|
|
40
|
+
}
|
|
41
|
+
function buildReachableParameterMap(roots, edges) {
|
|
42
|
+
const adjacency = buildAdjacency(edges);
|
|
43
|
+
const result = {};
|
|
44
|
+
for (const root of roots) {
|
|
45
|
+
result[serializeObjRef(root)] = reachableParameterRefs(graphInsightRef(root), adjacency);
|
|
46
|
+
}
|
|
47
|
+
return result;
|
|
48
|
+
}
|
|
49
|
+
function graphInsightRef(root) {
|
|
50
|
+
return root.type ? root : { ...root, type: "insight" };
|
|
51
|
+
}
|
|
52
|
+
function buildAdjacency(edges) {
|
|
53
|
+
const adjacency = new Map();
|
|
54
|
+
for (const edge of edges) {
|
|
55
|
+
const fromKey = serializeObjRef(edge.from);
|
|
56
|
+
const neighbors = adjacency.get(fromKey);
|
|
57
|
+
if (neighbors) {
|
|
58
|
+
neighbors.push(edge.to);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
adjacency.set(fromKey, [edge.to]);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return adjacency;
|
|
65
|
+
}
|
|
66
|
+
function reachableParameterRefs(start, adjacency) {
|
|
67
|
+
const parameters = [];
|
|
68
|
+
const visited = new Set([serializeObjRef(start)]);
|
|
69
|
+
const queue = [start];
|
|
70
|
+
for (let i = 0; i < queue.length; i++) {
|
|
71
|
+
for (const neighbor of adjacency.get(serializeObjRef(queue[i])) ?? []) {
|
|
72
|
+
const key = serializeObjRef(neighbor);
|
|
73
|
+
if (visited.has(key)) {
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
visited.add(key);
|
|
77
|
+
if (neighbor.type === "parameter") {
|
|
78
|
+
parameters.push(neighbor);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
queue.push(neighbor);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return parameters;
|
|
86
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useInitializeDashboardStore.d.ts","sourceRoot":"","sources":["../../../src/model/react/useInitializeDashboardStore.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useInitializeDashboardStore.d.ts","sourceRoot":"","sources":["../../../src/model/react/useInitializeDashboardStore.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAE,KAAK,sBAAsB,EAAwB,MAAM,4BAA4B,CAAC;AAI/F,OAAO,EAAE,KAAK,4BAA4B,EAAE,MAAM,YAAY,CAAC;AA6D/D;;;;;;GAMG;AACH,eAAO,MAAM,2BAA2B,UAC7B,4BAA4B,KACpC,sBAAsB,GAAG,IA4G3B,CAAC"}
|
|
@@ -6,6 +6,8 @@ import { enrichMapboxToken, useMapboxToken } from "@gooddata/sdk-ui-geo";
|
|
|
6
6
|
import { enrichAgGridToken, useAgGridToken } from "@gooddata/sdk-ui-pivot/next";
|
|
7
7
|
import { shallowEqualObjects } from "@gooddata/util";
|
|
8
8
|
import { newDashboardSummaryWorkflowWorker } from "../commandHandlers/dashboard/dashboardSummaryWorkflowWorker.js";
|
|
9
|
+
import { newFilterParameterDependenciesWorker } from "../commandHandlers/parameters/filterParameterDependenciesWorker.js";
|
|
10
|
+
import { newInsightParameterDependenciesWorker } from "../commandHandlers/parameters/insightParameterDependenciesWorker.js";
|
|
9
11
|
import { newRenderingWorker } from "../commandHandlers/render/renderingWorker.js";
|
|
10
12
|
import { InitialLoadCorrelationId, initializeDashboardWithPersistedDashboard, } from "../commands/dashboard.js";
|
|
11
13
|
import { dashboardDeinitialized } from "../events/dashboard.js";
|
|
@@ -111,6 +113,8 @@ export const useInitializeDashboardStore = (props) => {
|
|
|
111
113
|
isExport: config?.isExport,
|
|
112
114
|
}),
|
|
113
115
|
newDashboardSummaryWorkflowWorker(),
|
|
116
|
+
newInsightParameterDependenciesWorker(),
|
|
117
|
+
newFilterParameterDependenciesWorker(),
|
|
114
118
|
];
|
|
115
119
|
// Create new store and fire load dashboard command.
|
|
116
120
|
const newDashboardStore = createDashboardStore({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useIsWidgetRestricted.d.ts","sourceRoot":"","sources":["../../../src/model/react/useIsWidgetRestricted.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useIsWidgetRestricted.d.ts","sourceRoot":"","sources":["../../../src/model/react/useIsWidgetRestricted.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,KAAK,uBAAuB,EAAmC,MAAM,yBAAyB,CAAC;AAuCxG;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,uBAAuB,GAAG,OAAO,CAK9E;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,uBAAuB,EAAE,GAAG,OAAO,CAKpF"}
|
|
@@ -1,24 +1,29 @@
|
|
|
1
1
|
// (C) 2026 GoodData Corporation
|
|
2
|
-
import { isInsightWidget, isVisualizationSwitcherWidget } from "@gooddata/sdk-model";
|
|
3
|
-
import {
|
|
2
|
+
import { areObjRefsEqual, isInsightWidget, isRichTextWidget, isVisualizationSwitcherWidget, } from "@gooddata/sdk-model";
|
|
3
|
+
import { collectReferences } from "@gooddata/sdk-ui-kit";
|
|
4
|
+
import { selectRestrictedInsightsMap, selectRestrictedRichTextReferences, } from "../store/unavailableObjects/unavailableObjectsSelectors.js";
|
|
4
5
|
import { isExtendedDashboardLayoutWidget } from "../types/layoutTypes.js";
|
|
5
6
|
import { useDashboardSelector } from "./DashboardStoreProvider.js";
|
|
6
7
|
/**
|
|
7
8
|
* A switcher counts as restricted as soon as one of its entries is: its size comes from a
|
|
8
9
|
* visualization type the editor may not read, exactly as for a single restricted visualization. A
|
|
9
|
-
*
|
|
10
|
+
* rich text widget counts once its text references an object that is withheld, and a container once
|
|
11
|
+
* anything inside it does, because its own resize reaches every descendant.
|
|
10
12
|
*/
|
|
11
|
-
function isWidgetRestricted(widget, restrictedInsights) {
|
|
13
|
+
function isWidgetRestricted(widget, restrictedInsights, restrictedReferences) {
|
|
12
14
|
if (isInsightWidget(widget)) {
|
|
13
15
|
return restrictedInsights.has(widget.insight);
|
|
14
16
|
}
|
|
15
17
|
if (isVisualizationSwitcherWidget(widget)) {
|
|
16
18
|
return widget.visualizations.some((visualization) => restrictedInsights.has(visualization.insight));
|
|
17
19
|
}
|
|
20
|
+
if (isRichTextWidget(widget)) {
|
|
21
|
+
return Object.values(collectReferences(widget.content)).some((reference) => restrictedReferences.some((restricted) => areObjRefsEqual(restricted, reference.ref)));
|
|
22
|
+
}
|
|
18
23
|
if (isExtendedDashboardLayoutWidget(widget)) {
|
|
19
24
|
// resizing a container writes its new width to every widget inside it, so a container holding
|
|
20
25
|
// a restricted widget cannot be resized either
|
|
21
|
-
return widget.sections.some((section) => section.items.some((item) => item.widget && isWidgetRestricted(item.widget, restrictedInsights)));
|
|
26
|
+
return widget.sections.some((section) => section.items.some((item) => item.widget && isWidgetRestricted(item.widget, restrictedInsights, restrictedReferences)));
|
|
22
27
|
}
|
|
23
28
|
return false;
|
|
24
29
|
}
|
|
@@ -30,7 +35,8 @@ function isWidgetRestricted(widget, restrictedInsights) {
|
|
|
30
35
|
*/
|
|
31
36
|
export function useIsWidgetRestricted(widget) {
|
|
32
37
|
const restrictedInsights = useDashboardSelector(selectRestrictedInsightsMap);
|
|
33
|
-
|
|
38
|
+
const restrictedReferences = useDashboardSelector(selectRestrictedRichTextReferences);
|
|
39
|
+
return isWidgetRestricted(widget, restrictedInsights, restrictedReferences);
|
|
34
40
|
}
|
|
35
41
|
/**
|
|
36
42
|
* Tells whether any of the widgets is restricted. Used where an action covers several widgets at once,
|
|
@@ -40,5 +46,6 @@ export function useIsWidgetRestricted(widget) {
|
|
|
40
46
|
*/
|
|
41
47
|
export function useIsAnyWidgetRestricted(widgets) {
|
|
42
48
|
const restrictedInsights = useDashboardSelector(selectRestrictedInsightsMap);
|
|
43
|
-
|
|
49
|
+
const restrictedReferences = useDashboardSelector(selectRestrictedRichTextReferences);
|
|
50
|
+
return widgets.some((widget) => isWidgetRestricted(widget, restrictedInsights, restrictedReferences));
|
|
44
51
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type IExecutionConfig, type
|
|
1
|
+
import { type IExecutionConfig, type IInsight, type ObjRef } from "@gooddata/sdk-model";
|
|
2
2
|
/**
|
|
3
3
|
* Dashboard-level execution config shared by every execution the dashboard spawns: the execution
|
|
4
4
|
* timestamp and the effective dashboard timezone. Use this hook for executions that do not go
|
|
@@ -13,9 +13,9 @@ export declare function useDashboardExecConfig(): IExecutionConfig;
|
|
|
13
13
|
* drill overlay execute consistently instead of each duplicating (and drifting) the logic.
|
|
14
14
|
*
|
|
15
15
|
* @param ref - source widget whose tab provides the parameter overrides
|
|
16
|
-
* @param insight - the insight being executed (the drill target, not `ref`'s own insight); its
|
|
17
|
-
* decide which parameters apply
|
|
16
|
+
* @param insight - the insight being executed (the drill target, not `ref`'s own insight); its
|
|
17
|
+
* dependencies decide which parameters apply
|
|
18
18
|
* @internal
|
|
19
19
|
*/
|
|
20
|
-
export declare function useWidgetExecConfig(ref: ObjRef, insight:
|
|
20
|
+
export declare function useWidgetExecConfig(ref: ObjRef, insight: IInsight): IExecutionConfig;
|
|
21
21
|
//# sourceMappingURL=useWidgetExecConfig.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useWidgetExecConfig.d.ts","sourceRoot":"","sources":["../../../src/model/react/useWidgetExecConfig.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"useWidgetExecConfig.d.ts","sourceRoot":"","sources":["../../../src/model/react/useWidgetExecConfig.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,QAAQ,EAAE,KAAK,MAAM,EAAE,MAAM,qBAAqB,CAAC;AASxF;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,IAAI,gBAAgB,CAWzD;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,GAAG,gBAAgB,CAepF"}
|
|
@@ -27,8 +27,8 @@ export function useDashboardExecConfig() {
|
|
|
27
27
|
* drill overlay execute consistently instead of each duplicating (and drifting) the logic.
|
|
28
28
|
*
|
|
29
29
|
* @param ref - source widget whose tab provides the parameter overrides
|
|
30
|
-
* @param insight - the insight being executed (the drill target, not `ref`'s own insight); its
|
|
31
|
-
* decide which parameters apply
|
|
30
|
+
* @param insight - the insight being executed (the drill target, not `ref`'s own insight); its
|
|
31
|
+
* dependencies decide which parameters apply
|
|
32
32
|
* @internal
|
|
33
33
|
*/
|
|
34
34
|
export function useWidgetExecConfig(ref, insight) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type Action, type CaseReducer } from "@reduxjs/toolkit";
|
|
2
|
-
import { type ICatalogAttribute, type ICatalogAttributeHierarchy, type ICatalogComputedAttribute, type ICatalogDateDataset, type ICatalogFact, type ICatalogMeasure, type IDateHierarchyTemplate } from "@gooddata/sdk-model";
|
|
3
|
-
import { type CatalogState, type
|
|
2
|
+
import { type ICatalogAttribute, type ICatalogAttributeHierarchy, type ICatalogComputedAttribute, type ICatalogDateDataset, type ICatalogFact, type ICatalogMeasure, type IDateHierarchyTemplate, type IdentifierRef } from "@gooddata/sdk-model";
|
|
3
|
+
import { type CatalogState, type ICatalogFilterParametersState, type ICatalogInsightParametersState, type ICatalogParametersState } from "./catalogState.js";
|
|
4
4
|
type CatalogReducer<A extends Action> = CaseReducer<CatalogState, A>;
|
|
5
5
|
/**
|
|
6
6
|
* @public
|
|
@@ -46,8 +46,20 @@ export declare const catalogReducers: {
|
|
|
46
46
|
payload: ICatalogParametersState;
|
|
47
47
|
type: string;
|
|
48
48
|
}>;
|
|
49
|
-
|
|
50
|
-
payload:
|
|
49
|
+
setCatalogInsightParameters: CatalogReducer<{
|
|
50
|
+
payload: ICatalogInsightParametersState;
|
|
51
|
+
type: string;
|
|
52
|
+
}>;
|
|
53
|
+
mergeCatalogInsightParameters: CatalogReducer<{
|
|
54
|
+
payload: Record<string, IdentifierRef[]>;
|
|
55
|
+
type: string;
|
|
56
|
+
}>;
|
|
57
|
+
setCatalogFilterParameters: CatalogReducer<{
|
|
58
|
+
payload: ICatalogFilterParametersState;
|
|
59
|
+
type: string;
|
|
60
|
+
}>;
|
|
61
|
+
mergeCatalogFilterParameters: CatalogReducer<{
|
|
62
|
+
payload: Record<string, IdentifierRef[]>;
|
|
51
63
|
type: string;
|
|
52
64
|
}>;
|
|
53
65
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"catalogReducers.d.ts","sourceRoot":"","sources":["../../../../src/model/store/catalog/catalogReducers.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,WAAW,EAAsB,MAAM,kBAAkB,CAAC;AAErF,OAAO,EACH,KAAK,iBAAiB,EACtB,KAAK,0BAA0B,EAC/B,KAAK,yBAAyB,EAC9B,KAAK,mBAAmB,EACxB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,sBAAsB,
|
|
1
|
+
{"version":3,"file":"catalogReducers.d.ts","sourceRoot":"","sources":["../../../../src/model/store/catalog/catalogReducers.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,WAAW,EAAsB,MAAM,kBAAkB,CAAC;AAErF,OAAO,EACH,KAAK,iBAAiB,EACtB,KAAK,0BAA0B,EAC/B,KAAK,yBAAyB,EAC9B,KAAK,mBAAmB,EACxB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,sBAAsB,EAC3B,KAAK,aAAa,EACrB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACH,KAAK,YAAY,EACjB,KAAK,6BAA6B,EAClC,KAAK,8BAA8B,EACnC,KAAK,uBAAuB,EAC/B,MAAM,mBAAmB,CAAC;AAE3B,KAAK,cAAc,CAAC,CAAC,SAAS,MAAM,IAAI,WAAW,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;AAErE;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACjC,UAAU,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACjC,QAAQ,CAAC,EAAE,eAAe,EAAE,CAAC;IAC7B,KAAK,CAAC,EAAE,YAAY,EAAE,CAAC;IACvB,YAAY,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACrC,oBAAoB,CAAC,EAAE,0BAA0B,EAAE,CAAC;IACpD,kBAAkB,CAAC,EAAE,yBAAyB,EAAE,CAAC;IACjD,sBAAsB,CAAC,EAAE,sBAAsB,EAAE,CAAC;CACrD,CAAC;AAsBF;;GAEG;AACH,MAAM,MAAM,iCAAiC,GAAG;IAC5C,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,KAAK,EAAE,YAAY,EAAE,CAAC;CACzB,CAAC;AA0EF,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAW3B,CAAC"}
|
|
@@ -33,8 +33,17 @@ const deleteAttributeHierarchy = (state, action) => {
|
|
|
33
33
|
const setCatalogParameters = (state, action) => {
|
|
34
34
|
state.parameters = action.payload;
|
|
35
35
|
};
|
|
36
|
-
const
|
|
37
|
-
state.
|
|
36
|
+
const setCatalogInsightParameters = (state, action) => {
|
|
37
|
+
state.insightParameters = action.payload;
|
|
38
|
+
};
|
|
39
|
+
const mergeCatalogInsightParameters = (state, action) => {
|
|
40
|
+
Object.assign(state.insightParameters.byInsight, action.payload);
|
|
41
|
+
};
|
|
42
|
+
const setCatalogFilterParameters = (state, action) => {
|
|
43
|
+
state.filterParameters = action.payload;
|
|
44
|
+
};
|
|
45
|
+
const mergeCatalogFilterParameters = (state, action) => {
|
|
46
|
+
Object.assign(state.filterParameters.byRef, action.payload);
|
|
38
47
|
};
|
|
39
48
|
export const catalogReducers = {
|
|
40
49
|
setCatalogItems,
|
|
@@ -43,5 +52,8 @@ export const catalogReducers = {
|
|
|
43
52
|
updateAttributeHierarchy,
|
|
44
53
|
deleteAttributeHierarchy,
|
|
45
54
|
setCatalogParameters,
|
|
46
|
-
|
|
55
|
+
setCatalogInsightParameters,
|
|
56
|
+
mergeCatalogInsightParameters,
|
|
57
|
+
setCatalogFilterParameters,
|
|
58
|
+
mergeCatalogFilterParameters,
|
|
47
59
|
};
|