@gooddata/sdk-ui-dashboard 11.61.0-alpha.3 → 11.61.0-alpha.5
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 +409 -550
- package/esm/__version.d.ts +1 -1
- package/esm/__version.js +1 -1
- package/esm/index.d.ts +1 -0
- package/esm/index.d.ts.map +1 -1
- package/esm/model/commandHandlers/dashboard/deleteDashboardHandler.d.ts.map +1 -1
- package/esm/model/commandHandlers/dashboard/deleteDashboardHandler.js +6 -1
- package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/index.d.ts.map +1 -1
- package/esm/model/commandHandlers/dashboard/initializeDashboardHandler/index.js +2 -0
- 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/widgets/refreshInsightWidgetHandler.d.ts.map +1 -1
- package/esm/model/commandHandlers/widgets/refreshInsightWidgetHandler.js +4 -1
- package/esm/model/queryServices/queryWidgetFilters.d.ts.map +1 -1
- package/esm/model/queryServices/queryWidgetFilters.js +18 -96
- package/esm/model/react/useIsWidgetRestricted.d.ts +10 -0
- package/esm/model/react/useIsWidgetRestricted.d.ts.map +1 -1
- package/esm/model/react/useIsWidgetRestricted.js +26 -9
- package/esm/model/react/useWidgetExecutionsHandler.d.ts.map +1 -1
- package/esm/model/react/useWidgetExecutionsHandler.js +27 -5
- package/esm/model/store/dashboardStore.d.ts +2 -0
- package/esm/model/store/dashboardStore.d.ts.map +1 -1
- package/esm/model/store/dashboardStore.js +2 -0
- package/esm/model/store/executionResults/index.js +1 -1
- package/esm/model/store/filtering/dashboardFilterSelectors.d.ts.map +1 -1
- package/esm/model/store/filtering/dashboardFilterSelectors.js +1 -0
- package/esm/model/store/filtering/types.d.ts +5 -0
- package/esm/model/store/filtering/types.d.ts.map +1 -1
- package/esm/model/store/restrictedData/index.d.ts +9 -0
- package/esm/model/store/restrictedData/index.d.ts.map +1 -0
- package/esm/model/store/restrictedData/index.js +24 -0
- package/esm/model/store/restrictedData/restrictedDataSelectors.d.ts +19 -0
- package/esm/model/store/restrictedData/restrictedDataSelectors.d.ts.map +1 -0
- package/esm/model/store/restrictedData/restrictedDataSelectors.js +56 -0
- package/esm/model/store/restrictedData/restrictedDataState.d.ts +35 -0
- package/esm/model/store/restrictedData/restrictedDataState.d.ts.map +1 -0
- package/esm/model/store/restrictedData/restrictedDataState.js +4 -0
- package/esm/model/store/types.d.ts +7 -0
- package/esm/model/store/types.d.ts.map +1 -1
- package/esm/model/store/unavailableObjects/copyBlockingReferences.d.ts +4 -5
- package/esm/model/store/unavailableObjects/copyBlockingReferences.d.ts.map +1 -1
- package/esm/model/store/unavailableObjects/copyBlockingReferences.js +16 -9
- package/esm/model/store/unavailableObjects/unavailableObjectsSelectors.d.ts +16 -0
- package/esm/model/store/unavailableObjects/unavailableObjectsSelectors.d.ts.map +1 -1
- package/esm/model/store/unavailableObjects/unavailableObjectsSelectors.js +18 -0
- package/esm/model/store/widgetDrills/widgetDrillSelectors.d.ts.map +1 -1
- package/esm/model/store/widgetDrills/widgetDrillSelectors.js +5 -3
- package/esm/model/utils/widgetFilters.d.ts +45 -2
- package/esm/model/utils/widgetFilters.d.ts.map +1 -1
- package/esm/model/utils/widgetFilters.js +89 -1
- package/esm/presentation/automations/shared/automationFilters/hooks/useValidateExistingAutomationFilters.d.ts +7 -1
- package/esm/presentation/automations/shared/automationFilters/hooks/useValidateExistingAutomationFilters.d.ts.map +1 -1
- package/esm/presentation/automations/shared/automationFilters/hooks/useValidateExistingAutomationFilters.js +4 -2
- package/esm/presentation/filterBar/attributeFilter/DefaultDashboardAttributeFilter.d.ts.map +1 -1
- package/esm/presentation/filterBar/attributeFilter/DefaultDashboardAttributeFilter.js +4 -1
- package/esm/presentation/filterBar/attributeFilter/dashboardDropdownBody/configuration/hooks/useLimitingItemsConfiguration.d.ts.map +1 -1
- package/esm/presentation/filterBar/attributeFilter/dashboardDropdownBody/configuration/hooks/useLimitingItemsConfiguration.js +17 -4
- package/esm/presentation/localization/bundles/de-DE.localization-bundle.d.ts +0 -2
- package/esm/presentation/localization/bundles/de-DE.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/de-DE.localization-bundle.js +2 -4
- package/esm/presentation/localization/bundles/en-AU.localization-bundle.d.ts +0 -2
- package/esm/presentation/localization/bundles/en-AU.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/en-AU.localization-bundle.js +0 -2
- package/esm/presentation/localization/bundles/en-GB.localization-bundle.d.ts +0 -2
- package/esm/presentation/localization/bundles/en-GB.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/en-GB.localization-bundle.js +0 -2
- package/esm/presentation/localization/bundles/es-419.localization-bundle.d.ts +0 -2
- package/esm/presentation/localization/bundles/es-419.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/es-419.localization-bundle.js +0 -2
- package/esm/presentation/localization/bundles/es-ES.localization-bundle.d.ts +0 -2
- package/esm/presentation/localization/bundles/es-ES.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/es-ES.localization-bundle.js +0 -2
- package/esm/presentation/localization/bundles/fi-FI.localization-bundle.d.ts +0 -2
- package/esm/presentation/localization/bundles/fi-FI.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/fi-FI.localization-bundle.js +0 -2
- package/esm/presentation/localization/bundles/fr-CA.localization-bundle.d.ts +0 -2
- package/esm/presentation/localization/bundles/fr-CA.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/fr-CA.localization-bundle.js +0 -2
- package/esm/presentation/localization/bundles/fr-FR.localization-bundle.d.ts +0 -2
- package/esm/presentation/localization/bundles/fr-FR.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/fr-FR.localization-bundle.js +0 -2
- package/esm/presentation/localization/bundles/id-ID.localization-bundle.d.ts +0 -2
- package/esm/presentation/localization/bundles/id-ID.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/id-ID.localization-bundle.js +0 -2
- package/esm/presentation/localization/bundles/it-IT.localization-bundle.d.ts +0 -2
- package/esm/presentation/localization/bundles/it-IT.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/it-IT.localization-bundle.js +0 -2
- package/esm/presentation/localization/bundles/ja-JP.localization-bundle.d.ts +0 -2
- package/esm/presentation/localization/bundles/ja-JP.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/ja-JP.localization-bundle.js +0 -2
- package/esm/presentation/localization/bundles/ko-KR.localization-bundle.d.ts +0 -2
- package/esm/presentation/localization/bundles/ko-KR.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/ko-KR.localization-bundle.js +0 -2
- package/esm/presentation/localization/bundles/nl-NL.localization-bundle.d.ts +0 -2
- package/esm/presentation/localization/bundles/nl-NL.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/nl-NL.localization-bundle.js +0 -2
- package/esm/presentation/localization/bundles/pl-PL.localization-bundle.d.ts +0 -2
- package/esm/presentation/localization/bundles/pl-PL.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/pl-PL.localization-bundle.js +0 -2
- package/esm/presentation/localization/bundles/pt-BR.localization-bundle.d.ts +0 -2
- package/esm/presentation/localization/bundles/pt-BR.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/pt-BR.localization-bundle.js +0 -2
- package/esm/presentation/localization/bundles/pt-PT.localization-bundle.d.ts +0 -2
- package/esm/presentation/localization/bundles/pt-PT.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/pt-PT.localization-bundle.js +0 -2
- package/esm/presentation/localization/bundles/ru-RU.localization-bundle.d.ts +0 -2
- package/esm/presentation/localization/bundles/ru-RU.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/ru-RU.localization-bundle.js +0 -2
- package/esm/presentation/localization/bundles/sl-SI.localization-bundle.d.ts +0 -2
- package/esm/presentation/localization/bundles/sl-SI.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/sl-SI.localization-bundle.js +0 -2
- package/esm/presentation/localization/bundles/th-TH.localization-bundle.d.ts +0 -2
- package/esm/presentation/localization/bundles/th-TH.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/th-TH.localization-bundle.js +0 -2
- package/esm/presentation/localization/bundles/tr-TR.localization-bundle.d.ts +0 -2
- package/esm/presentation/localization/bundles/tr-TR.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/tr-TR.localization-bundle.js +0 -2
- package/esm/presentation/localization/bundles/uk-UA.localization-bundle.d.ts +0 -2
- package/esm/presentation/localization/bundles/uk-UA.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/uk-UA.localization-bundle.js +0 -2
- package/esm/presentation/localization/bundles/vi-VN.localization-bundle.d.ts +0 -2
- package/esm/presentation/localization/bundles/vi-VN.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/vi-VN.localization-bundle.js +0 -2
- package/esm/presentation/localization/bundles/zh-HK.localization-bundle.d.ts +0 -2
- package/esm/presentation/localization/bundles/zh-HK.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/zh-HK.localization-bundle.js +0 -2
- package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.d.ts +0 -2
- package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.js +0 -2
- package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.d.ts +0 -2
- package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.js +0 -2
- package/esm/presentation/widget/insight/ViewModeDashboardInsight/InsightDrillDialog/InsightDrillDialog.d.ts.map +1 -1
- package/esm/presentation/widget/insight/ViewModeDashboardInsight/InsightDrillDialog/InsightDrillDialog.js +2 -0
- package/esm/presentation/widget/insight/ViewModeDashboardInsight/InsightDrillDialog/useDrillDialogTooltipsOverride.d.ts +4 -0
- package/esm/presentation/widget/insight/ViewModeDashboardInsight/InsightDrillDialog/useDrillDialogTooltipsOverride.d.ts.map +1 -0
- package/esm/presentation/widget/insight/ViewModeDashboardInsight/InsightDrillDialog/useDrillDialogTooltipsOverride.js +26 -0
- package/esm/presentation/widget/visualizationSwitcher/EditModeDashboardVisualizationSwitcher.js +3 -3
- package/esm/presentation/widget/visualizationSwitcher/ViewModeDashboardVisualizationSwitcher.js +3 -3
- package/esm/presentation/widget/visualizationSwitcher/configuration/VisualizationConfig.d.ts.map +1 -1
- package/esm/presentation/widget/visualizationSwitcher/configuration/VisualizationConfig.js +3 -1
- package/esm/presentation/widget/widget/VisualizationSwitcherWidget/VisualizationSwitcherNavigationHeader.d.ts.map +1 -1
- package/esm/presentation/widget/widget/VisualizationSwitcherWidget/VisualizationSwitcherNavigationHeader.js +5 -6
- package/esm/sdk-ui-dashboard.d.ts +45 -0
- package/package.json +21 -21
- package/styles/css/drillDialog.css +1 -1
- package/styles/css/main.css +87 -5
- package/styles/css/main.css.map +1 -1
- package/styles/scss/drillDialog.scss +1 -1
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// (C) 2026 GoodData Corporation
|
|
2
|
-
import {
|
|
2
|
+
import { useCallback } from "react";
|
|
3
|
+
import { areObjRefsEqual, isInsightWidget, isRichTextWidget, isVisualizationSwitcherWidget, serializeObjRef, } from "@gooddata/sdk-model";
|
|
3
4
|
import { collectReferences } from "@gooddata/sdk-ui-kit";
|
|
5
|
+
import { selectWidgetsWithRestrictedData } from "../store/restrictedData/restrictedDataSelectors.js";
|
|
4
6
|
import { selectRestrictedInsightsMap, selectRestrictedRichTextReferences, } from "../store/unavailableObjects/unavailableObjectsSelectors.js";
|
|
5
7
|
import { isExtendedDashboardLayoutWidget } from "../types/layoutTypes.js";
|
|
6
8
|
import { useDashboardSelector } from "./DashboardStoreProvider.js";
|
|
@@ -10,12 +12,12 @@ import { useDashboardSelector } from "./DashboardStoreProvider.js";
|
|
|
10
12
|
* rich text widget counts once its text references an object that is withheld, and a container once
|
|
11
13
|
* anything inside it does, because its own resize reaches every descendant.
|
|
12
14
|
*/
|
|
13
|
-
function isWidgetRestricted(widget,
|
|
15
|
+
function isWidgetRestricted(widget, isInsightWidgetRestricted, restrictedReferences) {
|
|
14
16
|
if (isInsightWidget(widget)) {
|
|
15
|
-
return
|
|
17
|
+
return isInsightWidgetRestricted(widget);
|
|
16
18
|
}
|
|
17
19
|
if (isVisualizationSwitcherWidget(widget)) {
|
|
18
|
-
return widget.visualizations.some(
|
|
20
|
+
return widget.visualizations.some(isInsightWidgetRestricted);
|
|
19
21
|
}
|
|
20
22
|
if (isRichTextWidget(widget)) {
|
|
21
23
|
return Object.values(collectReferences(widget.content)).some((reference) => restrictedReferences.some((restricted) => areObjRefsEqual(restricted, reference.ref)));
|
|
@@ -23,10 +25,25 @@ function isWidgetRestricted(widget, restrictedInsights, restrictedReferences) {
|
|
|
23
25
|
if (isExtendedDashboardLayoutWidget(widget)) {
|
|
24
26
|
// resizing a container writes its new width to every widget inside it, so a container holding
|
|
25
27
|
// a restricted widget cannot be resized either
|
|
26
|
-
return widget.sections.some((section) => section.items.some((item) => item.widget &&
|
|
28
|
+
return widget.sections.some((section) => section.items.some((item) => item.widget &&
|
|
29
|
+
isWidgetRestricted(item.widget, isInsightWidgetRestricted, restrictedReferences)));
|
|
27
30
|
}
|
|
28
31
|
return false;
|
|
29
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* Returns the check whether an insight widget renders as restricted: its insight is one the current
|
|
35
|
+
* user is not allowed to read, or its execution was refused because the user may not read some of
|
|
36
|
+
* the data. The design makes no difference between the two; the second is known only once the
|
|
37
|
+
* widget has executed.
|
|
38
|
+
*
|
|
39
|
+
* @internal
|
|
40
|
+
*/
|
|
41
|
+
export function useIsInsightWidgetRestricted() {
|
|
42
|
+
const restrictedInsights = useDashboardSelector(selectRestrictedInsightsMap);
|
|
43
|
+
const widgetsWithRestrictedData = useDashboardSelector(selectWidgetsWithRestrictedData);
|
|
44
|
+
return useCallback((widget) => restrictedInsights.has(widget.insight) ||
|
|
45
|
+
widgetsWithRestrictedData.has(serializeObjRef(widget.ref)), [restrictedInsights, widgetsWithRestrictedData]);
|
|
46
|
+
}
|
|
30
47
|
/**
|
|
31
48
|
* Tells whether the widget renders something the current user is not allowed to see. A widget whose
|
|
32
49
|
* insight is merely deleted is not restricted — that one keeps rendering the missing-visualization tile.
|
|
@@ -34,9 +51,9 @@ function isWidgetRestricted(widget, restrictedInsights, restrictedReferences) {
|
|
|
34
51
|
* @alpha
|
|
35
52
|
*/
|
|
36
53
|
export function useIsWidgetRestricted(widget) {
|
|
37
|
-
const
|
|
54
|
+
const isInsightWidgetRestricted = useIsInsightWidgetRestricted();
|
|
38
55
|
const restrictedReferences = useDashboardSelector(selectRestrictedRichTextReferences);
|
|
39
|
-
return isWidgetRestricted(widget,
|
|
56
|
+
return isWidgetRestricted(widget, isInsightWidgetRestricted, restrictedReferences);
|
|
40
57
|
}
|
|
41
58
|
/**
|
|
42
59
|
* Tells whether any of the widgets is restricted. Used where an action covers several widgets at once,
|
|
@@ -45,7 +62,7 @@ export function useIsWidgetRestricted(widget) {
|
|
|
45
62
|
* @internal
|
|
46
63
|
*/
|
|
47
64
|
export function useIsAnyWidgetRestricted(widgets) {
|
|
48
|
-
const
|
|
65
|
+
const isInsightWidgetRestricted = useIsInsightWidgetRestricted();
|
|
49
66
|
const restrictedReferences = useDashboardSelector(selectRestrictedRichTextReferences);
|
|
50
|
-
return widgets.some((widget) => isWidgetRestricted(widget,
|
|
67
|
+
return widgets.some((widget) => isWidgetRestricted(widget, isInsightWidgetRestricted, restrictedReferences));
|
|
51
68
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useWidgetExecutionsHandler.d.ts","sourceRoot":"","sources":["../../../src/model/react/useWidgetExecutionsHandler.ts"],"names":[],"mappings":"AAIA,OAAO,EAAkB,KAAK,gBAAgB,EAAiB,MAAM,2BAA2B,CAAC;AACjG,OAAO,
|
|
1
|
+
{"version":3,"file":"useWidgetExecutionsHandler.d.ts","sourceRoot":"","sources":["../../../src/model/react/useWidgetExecutionsHandler.ts"],"names":[],"mappings":"AAIA,OAAO,EAAkB,KAAK,gBAAgB,EAAiB,MAAM,2BAA2B,CAAC;AACjG,OAAO,EACH,KAAK,0BAA0B,EAC/B,KAAK,cAAc,EACnB,KAAK,MAAM,EAEd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACH,KAAK,SAAS,EACd,KAAK,OAAO,EACZ,KAAK,gBAAgB,EAGxB,MAAM,kBAAkB,CAAC;AAmB1B;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM;;;iCAiD/B,gBAAgB,YACvB,cAAc,EAAE,GAAG,SAAS,gBACxB,0BAA0B,EAAE;uBASvC,SAAS,KAAG,IAAI;EAyB9B"}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
// (C) 2021-2026 GoodData Corporation
|
|
2
|
-
import { useCallback } from "react";
|
|
2
|
+
import { useCallback, useRef } from "react";
|
|
3
3
|
import { isNoDataError } from "@gooddata/sdk-backend-spi";
|
|
4
|
-
import {
|
|
4
|
+
import { serializeObjRef, } from "@gooddata/sdk-model";
|
|
5
|
+
import { isNoDataSdkError, isProtectedReport, } from "@gooddata/sdk-ui";
|
|
5
6
|
import { setExecutionResultData, setExecutionResultError, setExecutionResultErrorWithResult, setExecutionResultLoading, } from "../commands/executionResults.js";
|
|
7
|
+
import { restrictedDataActions } from "../store/restrictedData/index.js";
|
|
8
|
+
import { selectWidgetExecutionInputsKey } from "../store/restrictedData/restrictedDataSelectors.js";
|
|
9
|
+
import { useDashboardDispatch, useDashboardSelector } from "./DashboardStoreProvider.js";
|
|
6
10
|
import { useDispatchDashboardCommand } from "./useDispatchDashboardCommand.js";
|
|
7
11
|
function getLimitBreaks(dataView) {
|
|
8
12
|
const limitBreaks = dataView.metadata?.limitBreaks;
|
|
@@ -13,11 +17,27 @@ function getLimitBreaks(dataView) {
|
|
|
13
17
|
* @internal
|
|
14
18
|
*/
|
|
15
19
|
export function useWidgetExecutionsHandler(widgetRef) {
|
|
20
|
+
const dispatch = useDashboardDispatch();
|
|
21
|
+
const inputsKey = useDashboardSelector(selectWidgetExecutionInputsKey(widgetRef));
|
|
22
|
+
// the inputs of the running execution; the loader drops the outcome of an execution it replaced, so
|
|
23
|
+
// an outcome reported here always belongs to them
|
|
24
|
+
const executionInputsKey = useRef(undefined);
|
|
16
25
|
const startLoading = useDispatchDashboardCommand(setExecutionResultLoading);
|
|
17
26
|
const setData = useDispatchDashboardCommand(setExecutionResultData);
|
|
18
27
|
const setError = useDispatchDashboardCommand(setExecutionResultError);
|
|
19
28
|
const setErrorWithResult = useDispatchDashboardCommand(setExecutionResultErrorWithResult);
|
|
29
|
+
// Restrictions are recorded right away rather than through the command queue, so they keep the order
|
|
30
|
+
// in which executions start and finish even when the queue is busy.
|
|
31
|
+
const recordOutcome = useCallback((isRefused) => {
|
|
32
|
+
dispatch(isRefused
|
|
33
|
+
? restrictedDataActions.executionRefused({
|
|
34
|
+
ref: widgetRef,
|
|
35
|
+
inputsKey: executionInputsKey.current ?? inputsKey,
|
|
36
|
+
})
|
|
37
|
+
: restrictedDataActions.clearRefusal(serializeObjRef(widgetRef)));
|
|
38
|
+
}, [dispatch, inputsKey, widgetRef]);
|
|
20
39
|
const onError = useCallback((error) => {
|
|
40
|
+
recordOutcome(isProtectedReport(error));
|
|
21
41
|
// A no-data error may carry the computed (empty) result, which has a valid resultId
|
|
22
42
|
// (a result computed to emptiness, as opposed to e.g. an unsatisfiable filter that
|
|
23
43
|
// never executes). When present, record both so consumers can reference the result
|
|
@@ -31,10 +51,11 @@ export function useWidgetExecutionsHandler(widgetRef) {
|
|
|
31
51
|
else {
|
|
32
52
|
setError(widgetRef, error);
|
|
33
53
|
}
|
|
34
|
-
}, [setError, setErrorWithResult, widgetRef]);
|
|
54
|
+
}, [recordOutcome, setError, setErrorWithResult, widgetRef]);
|
|
35
55
|
const onSuccess = useCallback((executionResult, warnings, limitBreaks) => {
|
|
56
|
+
recordOutcome(false);
|
|
36
57
|
setData(widgetRef, executionResult, warnings, limitBreaks);
|
|
37
|
-
}, [setData, widgetRef]);
|
|
58
|
+
}, [recordOutcome, setData, widgetRef]);
|
|
38
59
|
const onPushData = useCallback((data) => {
|
|
39
60
|
if (data.dataView) {
|
|
40
61
|
const limitBreaks = getLimitBreaks(data.dataView);
|
|
@@ -43,9 +64,10 @@ export function useWidgetExecutionsHandler(widgetRef) {
|
|
|
43
64
|
}, [onSuccess]);
|
|
44
65
|
const onLoadingChanged = useCallback(({ isLoading }) => {
|
|
45
66
|
if (isLoading) {
|
|
67
|
+
executionInputsKey.current = inputsKey;
|
|
46
68
|
startLoading(widgetRef);
|
|
47
69
|
}
|
|
48
|
-
}, [startLoading, widgetRef]);
|
|
70
|
+
}, [inputsKey, startLoading, widgetRef]);
|
|
49
71
|
return {
|
|
50
72
|
onLoadingChanged,
|
|
51
73
|
onError,
|
|
@@ -123,6 +123,7 @@ export declare function createDashboardRootReducer({ queryCache, }?: {
|
|
|
123
123
|
inaccessibleDashboards: import("@reduxjs/toolkit").EntityState<import("../types/inaccessibleDashboardTypes.js").IInaccessibleDashboard, import("@reduxjs/toolkit").EntityId> & object;
|
|
124
124
|
unavailableObjects: import("@reduxjs/toolkit").EntityState<import("@gooddata/sdk-model").IUnavailableReference, import("@reduxjs/toolkit").EntityId> & object;
|
|
125
125
|
executionResults: import("@reduxjs/toolkit").EntityState<import("./executionResults/types.js").IExecutionResultEnvelope, import("@reduxjs/toolkit").EntityId> & object;
|
|
126
|
+
restrictedData: import("./restrictedData/restrictedDataState.js").IRestrictedDataState;
|
|
126
127
|
renderMode: import("./renderMode/renderModeState.js").IRenderModeState;
|
|
127
128
|
ui: import("./ui/uiState.js").IUiState;
|
|
128
129
|
dashboardPermissions: import("./dashboardPermissions/dashboardPermissionsState.js").DashboardPermissionsState;
|
|
@@ -152,6 +153,7 @@ export declare function createDashboardRootReducer({ queryCache, }?: {
|
|
|
152
153
|
inaccessibleDashboards: (import("@reduxjs/toolkit").EntityState<import("../types/inaccessibleDashboardTypes.js").IInaccessibleDashboard, import("@reduxjs/toolkit").EntityId> & object) | undefined;
|
|
153
154
|
unavailableObjects: (import("@reduxjs/toolkit").EntityState<import("@gooddata/sdk-model").IUnavailableReference, import("@reduxjs/toolkit").EntityId> & object) | undefined;
|
|
154
155
|
executionResults: (import("@reduxjs/toolkit").EntityState<import("./executionResults/types.js").IExecutionResultEnvelope, import("@reduxjs/toolkit").EntityId> & object) | undefined;
|
|
156
|
+
restrictedData: import("./restrictedData/restrictedDataState.js").IRestrictedDataState | undefined;
|
|
155
157
|
renderMode: import("./renderMode/renderModeState.js").IRenderModeState | undefined;
|
|
156
158
|
ui: import("./ui/uiState.js").IUiState | undefined;
|
|
157
159
|
dashboardPermissions: import("./dashboardPermissions/dashboardPermissionsState.js").DashboardPermissionsState | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dashboardStore.d.ts","sourceRoot":"","sources":["../../../src/model/store/dashboardStore.ts"],"names":[],"mappings":"AAEA,OAAO,EACH,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,OAAO,EAGf,MAAM,kBAAkB,CAAC;AAI1B,OAAyB,EAAa,KAAK,YAAY,EAAE,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AAMvF,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AAG9E,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAI9F,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"dashboardStore.d.ts","sourceRoot":"","sources":["../../../src/model/store/dashboardStore.ts"],"names":[],"mappings":"AAEA,OAAO,EACH,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,OAAO,EAGf,MAAM,kBAAkB,CAAC;AAI1B,OAAyB,EAAa,KAAK,YAAY,EAAE,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AAMvF,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AAG9E,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAI9F,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AA4BvE,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAwEzE;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,aAAa,CAAC,cAAc,CAAC,CAAC;AAE3D,MAAM,WAAW,uBAAuB;IACpC;;OAEG;IACH,oBAAoB,CAAC,EAAE,qBAAqB,EAAE,CAAC;IAE/C;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAE7E;;;;;;;;OAQG;IACH,qBAAqB,CAAC,EAAE,CACpB,oBAAoB,EAAE,CAAC,OAAO,EAAE,qBAAqB,KAAK,IAAI,EAC9D,sBAAsB,EAAE,CAAC,OAAO,EAAE,qBAAqB,KAAK,IAAI,KAC/D,IAAI,CAAC;CACb;AAED,MAAM,WAAW,qBAAqB;IAClC;;;;;;;;;;;OAWG;IACH,gBAAgB,EAAE,gBAAgB,CAAC;IAEnC;;;;;;;;;OASG;IACH,cAAc,CAAC,EAAE,uBAAuB,CAAC;IAEzC;;OAEG;IACH,oBAAoB,CAAC,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC;IAEvC;;OAEG;IACH,QAAQ,CAAC,EAAE,uBAAuB,CAAC;IAEnC;;;;;OAKG;IACH,aAAa,CAAC,EAAE,sBAAsB,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;IAEnD;;;;;;;OAOG;IACH,iBAAiB,EAAE,CAAC,CAAC,OAAO,EAAE,gBAAgB,KAAK,YAAY,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;IAEzE;;;;;;;OAOG;IACH,iBAAiB,EAAE,UAAU,CAAC;IAE9B;;OAEG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;CACnC;AAsBD;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACnC,KAAK,EAAE,cAAc,CAAC;IACtB,oBAAoB,EAAE,CAAC,OAAO,EAAE,qBAAqB,KAAK,IAAI,CAAC;IAC/D,sBAAsB,EAAE,CAAC,OAAO,EAAE,qBAAqB,KAAK,IAAI,CAAC;IACjE,YAAY,EAAE,IAAI,CAAC;CACtB;AA2CD,wBAAgB,0BAA0B,CAAC,EACvC,UAAkC,GACrC,GAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAA;CAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAgC/B;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,qBAAqB,GAAG,sBAAsB,CAuF1F"}
|
|
@@ -33,6 +33,7 @@ import { metaSliceReducer } from "./meta/index.js";
|
|
|
33
33
|
import { notificationChannelsSliceReducer } from "./notificationChannels/index.js";
|
|
34
34
|
import { permissionsSliceReducer } from "./permissions/index.js";
|
|
35
35
|
import { renderModeSliceReducer } from "./renderMode/index.js";
|
|
36
|
+
import { restrictedDataSliceReducer } from "./restrictedData/index.js";
|
|
36
37
|
import { savingSliceReducer } from "./saving/index.js";
|
|
37
38
|
import { showWidgetAsTableSliceReducer } from "./showWidgetAsTable/index.js";
|
|
38
39
|
import { tabsSliceReducer } from "./tabs/index.js";
|
|
@@ -158,6 +159,7 @@ export function createDashboardRootReducer({ queryCache = (state = {}) => state,
|
|
|
158
159
|
inaccessibleDashboards: inaccessibleDashboardsSliceReducer,
|
|
159
160
|
unavailableObjects: unavailableObjectsSliceReducer,
|
|
160
161
|
executionResults: executionResultsSliceReducer,
|
|
162
|
+
restrictedData: restrictedDataSliceReducer,
|
|
161
163
|
renderMode: renderModeSliceReducer,
|
|
162
164
|
ui: uiSliceReducer,
|
|
163
165
|
dashboardPermissions: dashboardPermissionsSliceReducer,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dashboardFilterSelectors.d.ts","sourceRoot":"","sources":["../../../../src/model/store/filtering/dashboardFilterSelectors.ts"],"names":[],"mappings":"AAMA,OAAO,EACH,KAAK,iBAAiB,EACtB,KAAK,+BAA+B,EACpC,KAAK,0BAA0B,EAC/B,KAAK,8BAA8B,EAYtC,MAAM,qBAAqB,CAAC;AAuB7B,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAIrD,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAOxD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,iBAAiB,EAAE,GAAG,WAAW,CAAC,MAAM,CAAC,CAMxF;AASD;;;;GAIG;AACH,eAAO,MAAM,+CAA+C,EAAE,iBAAiB,CAAC,WAAW,CAAC,MAAM,CAAC,CACvB,CAAC;AAE7E;;;GAGG;AACH,eAAO,MAAM,wCAAwC,EAAE,iBAAiB,CAAC,iBAAiB,EAAE,CA0BvF,CAAC;AAEN;;;;GAIG;AACH,eAAO,MAAM,oCAAoC,EAAE,iBAAiB,CAAC,MAAM,CAG1E,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,gCAAgC,EAAE,iBAAiB,CAAC,iBAAiB,EAAE,CAKnF,CAAC;AAYF;;;GAGG;AACH,eAAO,MAAM,mCAAmC,EAAE,iBAAiB,CAAC,OAAO,CAI1E,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,qDAAqD,EAAE,CAChE,kBAAkB,EAAE,MAAM,KACzB,iBAAiB,CAAC,WAAW,CAAC,MAAM,CAAC,CAIzC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,qCAAqC,EAAE,iBAAiB,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC,CAQpG,CAAC;AAaN;;;;GAIG;AACH,eAAO,MAAM,qDAAqD,EAAE,iBAAiB,CAAC,iBAAiB,EAAE,CAKpG,CAAC;AAEN;;;GAGG;AACH,eAAO,MAAM,8CAA8C,EAAE,iBAAiB,CAAC,iBAAiB,EAAE,CAK7F,CAAC;AAEN;;GAEG;AACH,eAAO,MAAM,4BAA4B,EAAE,iBAAiB,CAAC,iBAAiB,EAAE,CAmB/E,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,4BAA4B,EAAE,iBAAiB,CAAC,iBAAiB,EAAE,CAmB/E,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,yCAAyC,EAAE,iBAAiB,CAAC,iBAAiB,EAAE,CAwBxF,CAAC;AAEN;;GAEG;AACH,eAAO,MAAM,sCAAsC,EAAE,iBAAiB,CAAC,iBAAiB,EAAE,CAIzF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,kCAAkC,EAAE,iBAAiB,CAAC,MAAM,GAAG,SAAS,CAMpF,CAAC;AAoEF,eAAO,MAAM,yBAAyB,WAC1B,iBAAiB,wBACH;IAClB,sBAAsB,CAAC,EAAE,0BAA0B,CAAC;IACpD,8BAA8B,EAAE,8BAA8B,EAAE,CAAC;IACjE,sBAAsB,EAAE,+BAA+B,EAAE,CAAC;CAC7D,KACF,OAyBF,CAAC;AAEF,eAAO,MAAM,yBAAyB,WAC1B,iBAAiB,wBACH;IAClB,sBAAsB,CAAC,EAAE,0BAA0B,CAAC;IACpD,8BAA8B,EAAE,8BAA8B,EAAE,CAAC;IACjE,sBAAsB,EAAE,+BAA+B,EAAE,CAAC;CAC7D,KACF,OAyBF,CAAC;AAMF;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,EAAE,iBAAiB,CAAC,qBAAqB,EAAE,
|
|
1
|
+
{"version":3,"file":"dashboardFilterSelectors.d.ts","sourceRoot":"","sources":["../../../../src/model/store/filtering/dashboardFilterSelectors.ts"],"names":[],"mappings":"AAMA,OAAO,EACH,KAAK,iBAAiB,EACtB,KAAK,+BAA+B,EACpC,KAAK,0BAA0B,EAC/B,KAAK,8BAA8B,EAYtC,MAAM,qBAAqB,CAAC;AAuB7B,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAIrD,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAOxD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,iBAAiB,EAAE,GAAG,WAAW,CAAC,MAAM,CAAC,CAMxF;AASD;;;;GAIG;AACH,eAAO,MAAM,+CAA+C,EAAE,iBAAiB,CAAC,WAAW,CAAC,MAAM,CAAC,CACvB,CAAC;AAE7E;;;GAGG;AACH,eAAO,MAAM,wCAAwC,EAAE,iBAAiB,CAAC,iBAAiB,EAAE,CA0BvF,CAAC;AAEN;;;;GAIG;AACH,eAAO,MAAM,oCAAoC,EAAE,iBAAiB,CAAC,MAAM,CAG1E,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,gCAAgC,EAAE,iBAAiB,CAAC,iBAAiB,EAAE,CAKnF,CAAC;AAYF;;;GAGG;AACH,eAAO,MAAM,mCAAmC,EAAE,iBAAiB,CAAC,OAAO,CAI1E,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,qDAAqD,EAAE,CAChE,kBAAkB,EAAE,MAAM,KACzB,iBAAiB,CAAC,WAAW,CAAC,MAAM,CAAC,CAIzC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,qCAAqC,EAAE,iBAAiB,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC,CAQpG,CAAC;AAaN;;;;GAIG;AACH,eAAO,MAAM,qDAAqD,EAAE,iBAAiB,CAAC,iBAAiB,EAAE,CAKpG,CAAC;AAEN;;;GAGG;AACH,eAAO,MAAM,8CAA8C,EAAE,iBAAiB,CAAC,iBAAiB,EAAE,CAK7F,CAAC;AAEN;;GAEG;AACH,eAAO,MAAM,4BAA4B,EAAE,iBAAiB,CAAC,iBAAiB,EAAE,CAmB/E,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,4BAA4B,EAAE,iBAAiB,CAAC,iBAAiB,EAAE,CAmB/E,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,yCAAyC,EAAE,iBAAiB,CAAC,iBAAiB,EAAE,CAwBxF,CAAC;AAEN;;GAEG;AACH,eAAO,MAAM,sCAAsC,EAAE,iBAAiB,CAAC,iBAAiB,EAAE,CAIzF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,kCAAkC,EAAE,iBAAiB,CAAC,MAAM,GAAG,SAAS,CAMpF,CAAC;AAoEF,eAAO,MAAM,yBAAyB,WAC1B,iBAAiB,wBACH;IAClB,sBAAsB,CAAC,EAAE,0BAA0B,CAAC;IACpD,8BAA8B,EAAE,8BAA8B,EAAE,CAAC;IACjE,sBAAsB,EAAE,+BAA+B,EAAE,CAAC;CAC7D,KACF,OAyBF,CAAC;AAEF,eAAO,MAAM,yBAAyB,WAC1B,iBAAiB,wBACH;IAClB,sBAAsB,CAAC,EAAE,0BAA0B,CAAC;IACpD,8BAA8B,EAAE,8BAA8B,EAAE,CAAC;IACjE,sBAAsB,EAAE,+BAA+B,EAAE,CAAC;CAC7D,KACF,OAyBF,CAAC;AAMF;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,EAAE,iBAAiB,CAAC,qBAAqB,EAAE,CAyFnF,CAAC"}
|
|
@@ -34,5 +34,10 @@ export interface IAutomationFiltersTab {
|
|
|
34
34
|
* Hidden filters for the tab.
|
|
35
35
|
*/
|
|
36
36
|
hiddenFilters: FilterContextItem[];
|
|
37
|
+
/**
|
|
38
|
+
* Every filter of the tab except cross-filtering ones, hidden and restricted ones included.
|
|
39
|
+
* A filter stored in an automation but missing here was removed from the dashboard.
|
|
40
|
+
*/
|
|
41
|
+
allFilters: FilterContextItem[];
|
|
37
42
|
}
|
|
38
43
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/model/store/filtering/types.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IAClC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;OAEG;IACH,gBAAgB,EAAE,iBAAiB,EAAE,CAAC;IACtC;;;OAGG;IACH,iBAAiB,EAAE,iBAAiB,EAAE,CAAC;IACvC;;;OAGG;IACH,sBAAsB,EAAE,iBAAiB,EAAE,CAAC;IAC5C;;OAEG;IACH,aAAa,EAAE,iBAAiB,EAAE,CAAC;IACnC;;OAEG;IACH,aAAa,EAAE,iBAAiB,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/model/store/filtering/types.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IAClC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;OAEG;IACH,gBAAgB,EAAE,iBAAiB,EAAE,CAAC;IACtC;;;OAGG;IACH,iBAAiB,EAAE,iBAAiB,EAAE,CAAC;IACvC;;;OAGG;IACH,sBAAsB,EAAE,iBAAiB,EAAE,CAAC;IAC5C;;OAEG;IACH,aAAa,EAAE,iBAAiB,EAAE,CAAC;IACnC;;OAEG;IACH,aAAa,EAAE,iBAAiB,EAAE,CAAC;IACnC;;;OAGG;IACH,UAAU,EAAE,iBAAiB,EAAE,CAAC;CACnC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type Reducer } from "@reduxjs/toolkit";
|
|
2
|
+
import { type IRefusedExecution, type IRestrictedDataState } from "./restrictedDataState.js";
|
|
3
|
+
export declare const restrictedDataSliceReducer: Reducer<IRestrictedDataState>;
|
|
4
|
+
export declare const restrictedDataActions: {
|
|
5
|
+
executionRefused: import("@reduxjs/toolkit").ActionCreatorWithPayload<IRefusedExecution, "restrictedData/executionRefused">;
|
|
6
|
+
clearRefusal: import("@reduxjs/toolkit").ActionCreatorWithPayload<string, "restrictedData/clearRefusal">;
|
|
7
|
+
clearRestrictedData: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"restrictedData/clearRestrictedData">;
|
|
8
|
+
};
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/model/store/restrictedData/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAsB,KAAK,OAAO,EAAe,MAAM,kBAAkB,CAAC;AAIjF,OAAO,EACH,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EAE5B,MAAM,0BAA0B,CAAC;AAoBlC,eAAO,MAAM,0BAA0B,EAAE,OAAO,CAAC,oBAAoB,CAA+B,CAAC;AAGrG,eAAO,MAAM,qBAAqB;;;;CAAqC,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// (C) 2026 GoodData Corporation
|
|
2
|
+
import { createSlice } from "@reduxjs/toolkit";
|
|
3
|
+
import { serializeObjRef } from "@gooddata/sdk-model";
|
|
4
|
+
import { restrictedDataInitialState, } from "./restrictedDataState.js";
|
|
5
|
+
const restrictedDataSlice = createSlice({
|
|
6
|
+
name: "restrictedData",
|
|
7
|
+
initialState: restrictedDataInitialState,
|
|
8
|
+
reducers: {
|
|
9
|
+
executionRefused: (state, action) => {
|
|
10
|
+
state.refusedExecutions[serializeObjRef(action.payload.ref)] = action.payload;
|
|
11
|
+
},
|
|
12
|
+
// the widget's execution finished otherwise, or the widget was refreshed
|
|
13
|
+
clearRefusal: (state, action) => {
|
|
14
|
+
// only touch the map when needed, so its reference stays the same for unrestricted widgets
|
|
15
|
+
if (action.payload in state.refusedExecutions) {
|
|
16
|
+
delete state.refusedExecutions[action.payload];
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
clearRestrictedData: () => restrictedDataInitialState,
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
export const restrictedDataSliceReducer = restrictedDataSlice.reducer;
|
|
23
|
+
// Spread "fixes" TS2742 error
|
|
24
|
+
export const restrictedDataActions = { ...restrictedDataSlice.actions };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type ObjRef } from "@gooddata/sdk-model";
|
|
2
|
+
import { type DashboardSelector } from "../types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Identifies what the widget with the given ref executes: its insight with the widget's own
|
|
5
|
+
* visualization properties, the dashboard filters it does not ignore and the parameter values its
|
|
6
|
+
* insight depends on, resolved the same way as for its execution.
|
|
7
|
+
*
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
10
|
+
export declare const selectWidgetExecutionInputsKey: (ref: ObjRef) => DashboardSelector<string>;
|
|
11
|
+
/**
|
|
12
|
+
* Selects the widgets whose execution was refused because the current user may not read some of
|
|
13
|
+
* the data, as serialized widget refs. A widget stays in it while its insight, its own filters and its
|
|
14
|
+
* parameters are the ones it was refused with; once any of them changes, it executes again.
|
|
15
|
+
*
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
export declare const selectWidgetsWithRestrictedData: DashboardSelector<ReadonlySet<string>>;
|
|
19
|
+
//# sourceMappingURL=restrictedDataSelectors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restrictedDataSelectors.d.ts","sourceRoot":"","sources":["../../../../src/model/store/restrictedData/restrictedDataSelectors.ts"],"names":[],"mappings":"AAKA,OAAO,EAIH,KAAK,MAAM,EAId,MAAM,qBAAqB,CAAC;AAa7B,OAAO,EAAE,KAAK,iBAAiB,EAAuB,MAAM,aAAa,CAAC;AAqB1E;;;;;;GAMG;AACH,eAAO,MAAM,8BAA8B,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,iBAAiB,CAAC,MAAM,CAuBjF,CAAC;AAkBN;;;;;;GAMG;AACH,eAAO,MAAM,+BAA+B,EAAE,iBAAiB,CAAC,WAAW,CAAC,MAAM,CAAC,CAKlF,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// (C) 2026 GoodData Corporation
|
|
2
|
+
import { createSelector, lruMemoize } from "@reduxjs/toolkit";
|
|
3
|
+
import stringify from "json-stable-stringify";
|
|
4
|
+
import { insightFilters, insightRef, isInsightWidget, } from "@gooddata/sdk-model";
|
|
5
|
+
import { resolveWidgetDashboardFilters } from "../../utils/widgetFilters.js";
|
|
6
|
+
import { createMemoizedSelector } from "../_infra/selectors.js";
|
|
7
|
+
import { selectInsightByWidgetRef } from "../insights/insightsSelectors.js";
|
|
8
|
+
import { selectAttributeFilterConfigsDisplayAsLabelMap } from "../tabs/attributeFilterConfigs/attributeFilterConfigsSelectors.js";
|
|
9
|
+
import { selectAllFiltersForWidgetByRefAcrossTabs, selectFilterableWidgetByRef, } from "../tabs/layout/layoutSelectors.js";
|
|
10
|
+
import { resolveEffectiveParameterValuesForRoots } from "../tabs/parameters/parametersHelpers.js";
|
|
11
|
+
import { selectWidgetParameterContext } from "../tabs/parameters/parametersSelectors.js";
|
|
12
|
+
// the dashboard filters the widget's execution applies
|
|
13
|
+
function resolveExecutedDashboardFilters(widgetAwareFilters, widget, displayAsLabelMap, insight) {
|
|
14
|
+
if (!widget) {
|
|
15
|
+
return widgetAwareFilters.flat();
|
|
16
|
+
}
|
|
17
|
+
const { dateFilters, attributeFilters, measureValueFilters } = resolveWidgetDashboardFilters(widget, widgetAwareFilters, displayAsLabelMap, insight ? insightFilters(insight) : []);
|
|
18
|
+
return [...dateFilters.map(({ filter }) => filter), ...attributeFilters, ...measureValueFilters];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Identifies what the widget with the given ref executes: its insight with the widget's own
|
|
22
|
+
* visualization properties, the dashboard filters it does not ignore and the parameter values its
|
|
23
|
+
* insight depends on, resolved the same way as for its execution.
|
|
24
|
+
*
|
|
25
|
+
* @internal
|
|
26
|
+
*/
|
|
27
|
+
export const selectWidgetExecutionInputsKey = createMemoizedSelector((ref) => createSelector(selectAllFiltersForWidgetByRefAcrossTabs(ref), selectFilterableWidgetByRef(ref), selectAttributeFilterConfigsDisplayAsLabelMap, selectWidgetParameterContext(ref), selectInsightByWidgetRef(ref), (filters, widget, displayAsLabelMap, parameterContext, insight) => stringify({
|
|
28
|
+
// a replaced or updated visualization executes again, even under the same ref
|
|
29
|
+
insight: insight?.insight,
|
|
30
|
+
widgetProperties: isInsightWidget(widget) ? widget.properties : undefined,
|
|
31
|
+
filters: resolveExecutedDashboardFilters(filters, widget, displayAsLabelMap, insight),
|
|
32
|
+
parameters: insight
|
|
33
|
+
? resolveEffectiveParameterValuesForRoots(parameterContext, [insightRef(insight)], insight)
|
|
34
|
+
: [],
|
|
35
|
+
}) ?? ""));
|
|
36
|
+
const NO_WIDGET_IDS = [];
|
|
37
|
+
const selectRefusedExecutions = (state) => state.restrictedData.refusedExecutions;
|
|
38
|
+
const selectWidgetIdsRefusedWithCurrentInputs = (state) => {
|
|
39
|
+
const refusedExecutions = Object.entries(selectRefusedExecutions(state));
|
|
40
|
+
return refusedExecutions.length === 0
|
|
41
|
+
? NO_WIDGET_IDS
|
|
42
|
+
: refusedExecutions
|
|
43
|
+
.filter(([, { ref, inputsKey }]) => selectWidgetExecutionInputsKey(ref)(state) === inputsKey)
|
|
44
|
+
.map(([id]) => id);
|
|
45
|
+
};
|
|
46
|
+
const haveSameWidgetIds = (first, second) => first.length === second.length && first.every((id, index) => id === second[index]);
|
|
47
|
+
/**
|
|
48
|
+
* Selects the widgets whose execution was refused because the current user may not read some of
|
|
49
|
+
* the data, as serialized widget refs. A widget stays in it while its insight, its own filters and its
|
|
50
|
+
* parameters are the ones it was refused with; once any of them changes, it executes again.
|
|
51
|
+
*
|
|
52
|
+
* @internal
|
|
53
|
+
*/
|
|
54
|
+
export const selectWidgetsWithRestrictedData = createSelector(selectWidgetIdsRefusedWithCurrentInputs, (ids) => new Set(ids),
|
|
55
|
+
// the same set while the restricted widgets stay the same, so other updates do not re-render its users
|
|
56
|
+
{ memoize: lruMemoize, memoizeOptions: { equalityCheck: haveSameWidgetIds } });
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { type ObjRef } from "@gooddata/sdk-model";
|
|
2
|
+
/**
|
|
3
|
+
* An execution of a widget that was refused because the current user may not read some of the data.
|
|
4
|
+
*
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
export interface IRefusedExecution {
|
|
8
|
+
/**
|
|
9
|
+
* Ref of the widget.
|
|
10
|
+
*/
|
|
11
|
+
ref: ObjRef;
|
|
12
|
+
/**
|
|
13
|
+
* What the refused execution ran: the widget's insight, its own filters and its parameters, as
|
|
14
|
+
* produced by `selectWidgetExecutionInputsKey`.
|
|
15
|
+
*/
|
|
16
|
+
inputsKey: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Widgets whose execution was refused because the current user may not read some of the data.
|
|
20
|
+
*
|
|
21
|
+
* @internal
|
|
22
|
+
*/
|
|
23
|
+
export interface IRestrictedDataState {
|
|
24
|
+
/**
|
|
25
|
+
* The refused executions, keyed by serialized widget ref.
|
|
26
|
+
*
|
|
27
|
+
* @remarks
|
|
28
|
+
* A widget renders as restricted while its insight, its own filters and its parameters are the ones
|
|
29
|
+
* it was refused with. A later execution leaves the entry in place until it finishes, so the widget does not show
|
|
30
|
+
* its content between attempts.
|
|
31
|
+
*/
|
|
32
|
+
refusedExecutions: Record<string, IRefusedExecution>;
|
|
33
|
+
}
|
|
34
|
+
export declare const restrictedDataInitialState: IRestrictedDataState;
|
|
35
|
+
//# sourceMappingURL=restrictedDataState.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restrictedDataState.d.ts","sourceRoot":"","sources":["../../../../src/model/store/restrictedData/restrictedDataState.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAElD;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAC9B;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;CACrB;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACjC;;;;;;;OAOG;IACH,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;CACxD;AAED,eAAO,MAAM,0BAA0B,EAAE,oBAExC,CAAC"}
|
|
@@ -20,6 +20,7 @@ import { type IDashboardMetaState } from "./meta/metaState.js";
|
|
|
20
20
|
import { type INotificationChannelsState } from "./notificationChannels/notificationChannelsState.js";
|
|
21
21
|
import { type PermissionsState } from "./permissions/permissionsState.js";
|
|
22
22
|
import { type IRenderModeState } from "./renderMode/renderModeState.js";
|
|
23
|
+
import { type IRestrictedDataState } from "./restrictedData/restrictedDataState.js";
|
|
23
24
|
import { type SavingState } from "./saving/savingState.js";
|
|
24
25
|
import { type IShowWidgetAsTableState } from "./showWidgetAsTable/showWidgetAsTableState.js";
|
|
25
26
|
import { type ITabsState } from "./tabs/tabsState.js";
|
|
@@ -95,6 +96,12 @@ export type DashboardState = {
|
|
|
95
96
|
* @beta
|
|
96
97
|
*/
|
|
97
98
|
executionResults: EntityState<IExecutionResultEnvelope, EntityId>;
|
|
99
|
+
/**
|
|
100
|
+
* Widgets whose execution was refused because the current user may not read some of the data.
|
|
101
|
+
*
|
|
102
|
+
* @internal
|
|
103
|
+
*/
|
|
104
|
+
restrictedData: IRestrictedDataState;
|
|
98
105
|
/**
|
|
99
106
|
* Part of state where the different dashboard component queries may cache their results.
|
|
100
107
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/model/store/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/model/store/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -17,11 +17,10 @@ export interface IDashboardCopySourceTab {
|
|
|
17
17
|
* place the backend checks when it creates the copy, so it would refuse the copy.
|
|
18
18
|
*
|
|
19
19
|
* @remarks
|
|
20
|
-
* The backend accepts a copy that keeps a drill to a dashboard the user cannot open
|
|
21
|
-
* drill-down hierarchy,
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* A merely deleted object does not count either.
|
|
20
|
+
* The backend accepts a copy that keeps a drill to a dashboard the user cannot open or an ignored
|
|
21
|
+
* drill-down hierarchy, so neither counts. It refuses a copy whose filters use a label, metric or fact
|
|
22
|
+
* the user may not read: an attribute filter's label, a measure value filter's metric, or a metric or
|
|
23
|
+
* fact limiting a filter's values. A merely deleted object does not count.
|
|
25
24
|
*
|
|
26
25
|
* @internal
|
|
27
26
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"copyBlockingReferences.d.ts","sourceRoot":"","sources":["../../../../src/model/store/unavailableObjects/copyBlockingReferences.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,2BAA2B,CAAC;AAChF,OAAO,EACH,KAAK,iBAAiB,EAEtB,KAAK,+BAA+B,EACpC,KAAK,gBAAgB,EAErB,KAAK,QAAQ,
|
|
1
|
+
{"version":3,"file":"copyBlockingReferences.d.ts","sourceRoot":"","sources":["../../../../src/model/store/unavailableObjects/copyBlockingReferences.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,2BAA2B,CAAC;AAChF,OAAO,EACH,KAAK,iBAAiB,EAEtB,KAAK,+BAA+B,EACpC,KAAK,gBAAgB,EAErB,KAAK,QAAQ,EAkBhB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,KAAK,uBAAuB,EAAmC,MAAM,4BAA4B,CAAC;AAK3G,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAKrD;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACpC,MAAM,CAAC,EAAE,gBAAgB,CAAC,uBAAuB,CAAC,CAAC;IACnD,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAC7B,sBAAsB,EAAE,+BAA+B,EAAE,CAAC;CAC7D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CACpC,IAAI,EAAE,uBAAuB,EAAE,EAC/B,QAAQ,EAAE,QAAQ,EAAE,EACpB,kBAAkB,EAAE,8BAA8B,EAAE,GACrD,OAAO,CA8ET;AAED;;;;;;GAMG;AACH,eAAO,MAAM,+BAA+B,EAAE,iBAAiB,CAAC,OAAO,CAqBtE,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// (C) 2026 GoodData Corporation
|
|
2
2
|
import { createSelector } from "@reduxjs/toolkit";
|
|
3
|
-
import { areObjRefsEqual, dashboardAttributeFilterItemDisplayForm, insightRef, isComputedAttributeRef, isDashboardAttributeFilterItem, isDashboardAttributeFilterReference, isDashboardMeasureValueFilterReference, isDrillToDashboard, isInsightWidget, isKpiWidget, isRichTextWidget, isVisualizationSwitcherWidget, } from "@gooddata/sdk-model";
|
|
3
|
+
import { areObjRefsEqual, dashboardAttributeFilterItemDisplayForm, dashboardAttributeFilterItemValidateElementsBy, insightRef, isComputedAttributeRef, isDashboardAttributeFilterItem, isDashboardAttributeFilterReference, isDashboardMeasureValueFilter, isDashboardMeasureValueFilterReference, isDrillToDashboard, isInsightWidget, isKpiWidget, isRichTextWidget, isVisualizationSwitcherWidget, } from "@gooddata/sdk-model";
|
|
4
4
|
import { collectReferences } from "@gooddata/sdk-ui-kit";
|
|
5
5
|
import { isExtendedDashboardLayoutWidget } from "../../types/layoutTypes.js";
|
|
6
6
|
import { isDashboardObjectRestricted } from "../filtering/restrictedFilterUtils.js";
|
|
@@ -8,17 +8,16 @@ import { selectInsights } from "../insights/insightsSelectors.js";
|
|
|
8
8
|
import { selectIsInViewMode } from "../renderMode/renderModeSelectors.js";
|
|
9
9
|
import { selectTabs } from "../tabs/tabsSelectors.js";
|
|
10
10
|
import { isDrillRestricted } from "../widgetDrills/drillRestrictionUtils.js";
|
|
11
|
-
import { selectUnavailableObjects } from "./unavailableObjectsSelectors.js";
|
|
11
|
+
import { newRestrictedLimitingItemsMap, selectUnavailableObjects } from "./unavailableObjectsSelectors.js";
|
|
12
12
|
/**
|
|
13
13
|
* Tells whether a copy of the dashboard would reference an object the current user may not read in a
|
|
14
14
|
* place the backend checks when it creates the copy, so it would refuse the copy.
|
|
15
15
|
*
|
|
16
16
|
* @remarks
|
|
17
|
-
* The backend accepts a copy that keeps a drill to a dashboard the user cannot open
|
|
18
|
-
* drill-down hierarchy,
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* A merely deleted object does not count either.
|
|
17
|
+
* The backend accepts a copy that keeps a drill to a dashboard the user cannot open or an ignored
|
|
18
|
+
* drill-down hierarchy, so neither counts. It refuses a copy whose filters use a label, metric or fact
|
|
19
|
+
* the user may not read: an attribute filter's label, a measure value filter's metric, or a metric or
|
|
20
|
+
* fact limiting a filter's values. A merely deleted object does not count.
|
|
22
21
|
*
|
|
23
22
|
* @internal
|
|
24
23
|
*/
|
|
@@ -56,12 +55,20 @@ export function hasCopyBlockingReference(tabs, insights, unavailableObjects) {
|
|
|
56
55
|
}
|
|
57
56
|
return false;
|
|
58
57
|
};
|
|
58
|
+
const restrictedLimitingItems = newRestrictedLimitingItemsMap(unavailableObjects);
|
|
59
|
+
const isFilterForbidden = (filter) => {
|
|
60
|
+
if (isDashboardMeasureValueFilter(filter)) {
|
|
61
|
+
return isForbidden(filter.dashboardMeasureValueFilter.measure, "measure");
|
|
62
|
+
}
|
|
63
|
+
return (isDashboardAttributeFilterItem(filter) &&
|
|
64
|
+
(isLabelForbidden(dashboardAttributeFilterItemDisplayForm(filter)) ||
|
|
65
|
+
(dashboardAttributeFilterItemValidateElementsBy(filter) ?? []).some((item) => restrictedLimitingItems.has(item))));
|
|
66
|
+
};
|
|
59
67
|
const isSectionForbidden = (section) => isTextForbidden(section.header?.description) ||
|
|
60
68
|
section.items.some((item) => item.widget !== undefined && isWidgetForbidden(item.widget));
|
|
61
69
|
return tabs.some((tab) => (tab.layout?.sections ?? []).some(isSectionForbidden) ||
|
|
62
70
|
tab.attributeFilterConfigs.some((config) => isLabelForbidden(config.displayAsLabel)) ||
|
|
63
|
-
tab.filters.some(
|
|
64
|
-
isLabelForbidden(dashboardAttributeFilterItemDisplayForm(filter))));
|
|
71
|
+
tab.filters.some(isFilterForbidden));
|
|
65
72
|
}
|
|
66
73
|
/**
|
|
67
74
|
* Selects whether "Save as new" would fail because the dashboard, as it stands now, references objects
|
|
@@ -23,6 +23,22 @@ export declare const selectUnavailableObjectsMapByType: (type: ObjectType) => Da
|
|
|
23
23
|
* @alpha
|
|
24
24
|
*/
|
|
25
25
|
export declare const selectRestrictedInsightsMap: DashboardSelector<ObjRefMap<IUnavailableDashboardReference>>;
|
|
26
|
+
/**
|
|
27
|
+
* Maps the metrics and facts the current user is not allowed to read: the items limiting an attribute
|
|
28
|
+
* filter's values ("Filter values by") that drop out of its values request and of its configuration
|
|
29
|
+
* panel. Merely deleted ones are not included. Lookups match the type too, as a metric and a fact may
|
|
30
|
+
* share an identifier.
|
|
31
|
+
*
|
|
32
|
+
* @internal
|
|
33
|
+
*/
|
|
34
|
+
export declare function newRestrictedLimitingItemsMap(objects: ReadonlyArray<IUnavailableDashboardReference>): ObjRefMap<IUnavailableDashboardReference>;
|
|
35
|
+
/**
|
|
36
|
+
* Selects the metrics and facts limiting attribute filter values that the current user is not allowed to
|
|
37
|
+
* read, see {@link newRestrictedLimitingItemsMap}.
|
|
38
|
+
*
|
|
39
|
+
* @internal
|
|
40
|
+
*/
|
|
41
|
+
export declare const selectRestrictedLimitingItemsMap: DashboardSelector<ObjRefMap<IUnavailableDashboardReference>>;
|
|
26
42
|
/**
|
|
27
43
|
* Selects the refs a rich text widget references but the current user is not allowed to read. A
|
|
28
44
|
* reference that is merely deleted is not included — that keeps rendering today's error value,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unavailableObjectsSelectors.d.ts","sourceRoot":"","sources":["../../../../src/model/store/unavailableObjects/unavailableObjectsSelectors.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,2BAA2B,CAAC;AAChF,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAE9D,OAAO,EAAE,KAAK,SAAS,EAA0B,MAAM,yCAAyC,CAAC;AAEjG,OAAO,EAAE,KAAK,iBAAiB,EAAuB,MAAM,aAAa,CAAC;AAW1E;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,EAAE,iBAAiB,CAAC,8BAA8B,EAAE,CAC3D,CAAC;AAE/B;;;;;GAKG;AACH,eAAO,MAAM,iCAAiC,EAAE,CAC5C,IAAI,EAAE,UAAU,KACf,iBAAiB,CAAC,SAAS,CAAC,8BAA8B,CAAC,CAQ/D,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,2BAA2B,EAAE,iBAAiB,CAAC,SAAS,CAAC,8BAA8B,CAAC,CAMhG,CAAC;
|
|
1
|
+
{"version":3,"file":"unavailableObjectsSelectors.d.ts","sourceRoot":"","sources":["../../../../src/model/store/unavailableObjects/unavailableObjectsSelectors.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,2BAA2B,CAAC;AAChF,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAE9D,OAAO,EAAE,KAAK,SAAS,EAA0B,MAAM,yCAAyC,CAAC;AAEjG,OAAO,EAAE,KAAK,iBAAiB,EAAuB,MAAM,aAAa,CAAC;AAW1E;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,EAAE,iBAAiB,CAAC,8BAA8B,EAAE,CAC3D,CAAC;AAE/B;;;;;GAKG;AACH,eAAO,MAAM,iCAAiC,EAAE,CAC5C,IAAI,EAAE,UAAU,KACf,iBAAiB,CAAC,SAAS,CAAC,8BAA8B,CAAC,CAQ/D,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,2BAA2B,EAAE,iBAAiB,CAAC,SAAS,CAAC,8BAA8B,CAAC,CAMhG,CAAC;AAEN;;;;;;;GAOG;AACH,wBAAgB,6BAA6B,CACzC,OAAO,EAAE,aAAa,CAAC,8BAA8B,CAAC,GACvD,SAAS,CAAC,8BAA8B,CAAC,CAS3C;AAED;;;;;GAKG;AACH,eAAO,MAAM,gCAAgC,EAAE,iBAAiB,CAAC,SAAS,CAAC,8BAA8B,CAAC,CAC/B,CAAC;AAQ5E;;;;;;GAMG;AACH,eAAO,MAAM,kCAAkC,EAAE,iBAAiB,CAAC,MAAM,EAAE,CAQ1E,CAAC"}
|
|
@@ -26,6 +26,24 @@ export const selectUnavailableObjectsMapByType = createMemoizedSelector((type) =
|
|
|
26
26
|
* @alpha
|
|
27
27
|
*/
|
|
28
28
|
export const selectRestrictedInsightsMap = createSelector(selectUnavailableObjects, (objects) => newMapForObjectWithRef(objects.filter((object) => object.type === "insight" && object.reason === "forbidden"), "insight"));
|
|
29
|
+
/**
|
|
30
|
+
* Maps the metrics and facts the current user is not allowed to read: the items limiting an attribute
|
|
31
|
+
* filter's values ("Filter values by") that drop out of its values request and of its configuration
|
|
32
|
+
* panel. Merely deleted ones are not included. Lookups match the type too, as a metric and a fact may
|
|
33
|
+
* share an identifier.
|
|
34
|
+
*
|
|
35
|
+
* @internal
|
|
36
|
+
*/
|
|
37
|
+
export function newRestrictedLimitingItemsMap(objects) {
|
|
38
|
+
return newMapForObjectWithRef(objects.filter((object) => object.reason === "forbidden" && (object.type === "measure" || object.type === "fact")), undefined, true);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Selects the metrics and facts limiting attribute filter values that the current user is not allowed to
|
|
42
|
+
* read, see {@link newRestrictedLimitingItemsMap}.
|
|
43
|
+
*
|
|
44
|
+
* @internal
|
|
45
|
+
*/
|
|
46
|
+
export const selectRestrictedLimitingItemsMap = createSelector(selectUnavailableObjects, newRestrictedLimitingItemsMap);
|
|
29
47
|
/**
|
|
30
48
|
* Object types a rich text widget can reference: `{metric/id}`, `{label/id}` and
|
|
31
49
|
* `{computed_attribute/id}`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"widgetDrillSelectors.d.ts","sourceRoot":"","sources":["../../../../src/model/store/widgetDrills/widgetDrillSelectors.ts"],"names":[],"mappings":"AAMA,OAAO,EAIH,KAAK,oBAAoB,EAEzB,KAAK,iBAAiB,EAEtB,KAAK,qBAAqB,EAE1B,KAAK,mBAAmB,EAGxB,KAAK,MAAM,EAcd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACH,KAAK,aAAa,EAGlB,KAAK,sBAAsB,EAC3B,KAAK,gBAAgB,EACxB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EACH,KAAK,wBAAwB,EAC7B,KAAK,8BAA8B,EACnC,KAAK,4CAA4C,EACpD,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"widgetDrillSelectors.d.ts","sourceRoot":"","sources":["../../../../src/model/store/widgetDrills/widgetDrillSelectors.ts"],"names":[],"mappings":"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"}
|