@gooddata/sdk-ui-dashboard 11.36.0-alpha.3 → 11.36.0-alpha.6
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 +63 -115
- package/esm/__version.d.ts +1 -1
- package/esm/__version.js +1 -1
- package/esm/index.d.ts +5 -13
- package/esm/index.js +2 -10
- package/esm/internal.d.ts +1 -1
- package/esm/model/commandHandlers/dashboard/common/filterViews.js +24 -1
- package/esm/model/commandHandlers/dashboard/common/parameterHydration.d.ts +7 -1
- package/esm/model/commandHandlers/dashboard/common/parameterHydration.js +16 -2
- package/esm/model/commandHandlers/dashboard/common/stateInitializers.js +4 -2
- package/esm/model/commandHandlers/drill/resolveDrillToCustomUrl.d.ts +7 -1
- package/esm/model/commandHandlers/drill/resolveDrillToCustomUrl.js +80 -4
- package/esm/model/commandHandlers/filterContext/filterViewHandler.js +10 -0
- package/esm/model/commandHandlers/filterContext/filterViewParameters.d.ts +7 -0
- package/esm/model/commandHandlers/filterContext/filterViewParameters.js +11 -0
- package/esm/model/store/config/configSelectors.d.ts +0 -6
- package/esm/model/store/config/configSelectors.js +0 -8
- package/esm/model/store/tabs/index.d.ts +4 -0
- package/esm/model/store/tabs/parameters/parametersReducers.d.ts +11 -1
- package/esm/model/store/tabs/parameters/parametersReducers.js +16 -8
- package/esm/model/store/tabs/parameters/parametersSelectors.d.ts +7 -0
- package/esm/model/store/tabs/parameters/parametersSelectors.js +17 -0
- package/esm/model/types/commonTypes.d.ts +11 -2
- package/esm/model/utils/measureValueFilterUtils.d.ts +14 -0
- package/esm/model/utils/measureValueFilterUtils.js +21 -0
- package/esm/presentation/alerting/DefaultAlertingDialog/{DefaultAlertingDialogNew.d.ts → DefaultAlertingDialog.d.ts} +1 -1
- package/esm/presentation/alerting/DefaultAlertingDialog/{DefaultAlertingDialogNew.js → DefaultAlertingDialog.js} +6 -12
- package/esm/presentation/alerting/DefaultAlertingDialog/components/AlertAttributeSelect.js +43 -9
- package/esm/presentation/alerting/DefaultAlertingDialog/hooks/useSaveAlertToBackend.js +13 -25
- package/esm/presentation/alerting/types.d.ts +1 -72
- package/esm/presentation/automationFilters/hooks/useValidateExistingAutomationFilters.d.ts +1 -2
- package/esm/presentation/automationFilters/hooks/useValidateExistingAutomationFilters.js +5 -5
- package/esm/presentation/dashboard/DashboardHeader/AlertingDialogProvider.js +1 -8
- package/esm/presentation/dashboard/DashboardHeader/ScheduledEmailDialogProvider.js +17 -8
- package/esm/presentation/dashboard/DashboardHeader/ShareDialogDashboardHeader.js +5 -2
- package/esm/presentation/dashboard/components/DashboardRenderer.js +2 -2
- package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditor.js +97 -13
- package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParameters.d.ts +1 -1
- package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParameters.js +3 -3
- package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParametersSections/DashboardParametersSection.d.ts +3 -2
- package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParametersSections/DashboardParametersSection.js +17 -4
- package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParametersSections/InsightParametersSection.d.ts +4 -2
- package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParametersSections/InsightParametersSection.js +37 -4
- package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParametersSections/Parameter.d.ts +4 -3
- package/esm/presentation/drill/DrillConfigPanel/DrillToUrl/CustomUrlEditorParametersSections/Parameter.js +3 -4
- package/esm/presentation/filterBar/attributeFilter/DefaultDashboardAttributeFilter.js +4 -1
- package/esm/presentation/filterBar/filterBar/DefaultDashboardFilterGroup.js +4 -1
- package/esm/presentation/localization/bundles/de-DE.localization-bundle.d.ts +2 -9
- package/esm/presentation/localization/bundles/de-DE.localization-bundle.js +2 -9
- package/esm/presentation/localization/bundles/en-AU.localization-bundle.d.ts +2 -9
- package/esm/presentation/localization/bundles/en-AU.localization-bundle.js +2 -9
- package/esm/presentation/localization/bundles/en-GB.localization-bundle.d.ts +2 -9
- package/esm/presentation/localization/bundles/en-GB.localization-bundle.js +2 -9
- package/esm/presentation/localization/bundles/en-US.localization-bundle.d.ts +4 -36
- package/esm/presentation/localization/bundles/en-US.localization-bundle.js +4 -36
- package/esm/presentation/localization/bundles/es-419.localization-bundle.d.ts +2 -9
- package/esm/presentation/localization/bundles/es-419.localization-bundle.js +2 -9
- package/esm/presentation/localization/bundles/es-ES.localization-bundle.d.ts +2 -9
- package/esm/presentation/localization/bundles/es-ES.localization-bundle.js +2 -9
- package/esm/presentation/localization/bundles/fi-FI.localization-bundle.d.ts +2 -9
- package/esm/presentation/localization/bundles/fi-FI.localization-bundle.js +2 -9
- package/esm/presentation/localization/bundles/fr-CA.localization-bundle.d.ts +2 -9
- package/esm/presentation/localization/bundles/fr-CA.localization-bundle.js +2 -9
- package/esm/presentation/localization/bundles/fr-FR.localization-bundle.d.ts +2 -9
- package/esm/presentation/localization/bundles/fr-FR.localization-bundle.js +2 -9
- package/esm/presentation/localization/bundles/id-ID.localization-bundle.d.ts +2 -9
- package/esm/presentation/localization/bundles/id-ID.localization-bundle.js +2 -9
- package/esm/presentation/localization/bundles/it-IT.localization-bundle.d.ts +2 -9
- package/esm/presentation/localization/bundles/it-IT.localization-bundle.js +2 -9
- package/esm/presentation/localization/bundles/ja-JP.localization-bundle.d.ts +2 -9
- package/esm/presentation/localization/bundles/ja-JP.localization-bundle.js +2 -9
- package/esm/presentation/localization/bundles/ko-KR.localization-bundle.d.ts +2 -9
- package/esm/presentation/localization/bundles/ko-KR.localization-bundle.js +2 -9
- package/esm/presentation/localization/bundles/nl-NL.localization-bundle.d.ts +2 -9
- package/esm/presentation/localization/bundles/nl-NL.localization-bundle.js +2 -9
- package/esm/presentation/localization/bundles/pl-PL.localization-bundle.d.ts +2 -9
- package/esm/presentation/localization/bundles/pl-PL.localization-bundle.js +2 -9
- package/esm/presentation/localization/bundles/pt-BR.localization-bundle.d.ts +2 -9
- package/esm/presentation/localization/bundles/pt-BR.localization-bundle.js +2 -9
- package/esm/presentation/localization/bundles/pt-PT.localization-bundle.d.ts +2 -9
- package/esm/presentation/localization/bundles/pt-PT.localization-bundle.js +2 -9
- package/esm/presentation/localization/bundles/ru-RU.localization-bundle.d.ts +2 -9
- package/esm/presentation/localization/bundles/ru-RU.localization-bundle.js +2 -9
- package/esm/presentation/localization/bundles/sl-SI.localization-bundle.d.ts +2 -9
- package/esm/presentation/localization/bundles/sl-SI.localization-bundle.js +2 -9
- package/esm/presentation/localization/bundles/th-TH.localization-bundle.d.ts +2 -9
- package/esm/presentation/localization/bundles/th-TH.localization-bundle.js +2 -9
- package/esm/presentation/localization/bundles/tr-TR.localization-bundle.d.ts +2 -9
- package/esm/presentation/localization/bundles/tr-TR.localization-bundle.js +2 -9
- package/esm/presentation/localization/bundles/uk-UA.localization-bundle.d.ts +2 -9
- package/esm/presentation/localization/bundles/uk-UA.localization-bundle.js +2 -9
- package/esm/presentation/localization/bundles/vi-VN.localization-bundle.d.ts +2 -9
- package/esm/presentation/localization/bundles/vi-VN.localization-bundle.js +2 -9
- package/esm/presentation/localization/bundles/zh-HK.localization-bundle.d.ts +2 -9
- package/esm/presentation/localization/bundles/zh-HK.localization-bundle.js +2 -9
- package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.d.ts +2 -9
- package/esm/presentation/localization/bundles/zh-Hans.localization-bundle.js +2 -9
- package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.d.ts +2 -9
- package/esm/presentation/localization/bundles/zh-Hant.localization-bundle.js +2 -9
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/DefaultScheduledEmailDialog.js +26 -59
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/hooks/useEditScheduledEmail.d.ts +2 -6
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/hooks/useEditScheduledEmail.js +22 -104
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/hooks/useSaveScheduledEmailToBackend.js +12 -33
- package/esm/presentation/scheduledEmail/hooks/useWidgetAutomationFilters.d.ts +3 -0
- package/esm/presentation/scheduledEmail/hooks/useWidgetAutomationFilters.js +46 -0
- package/esm/presentation/scheduledEmail/types.d.ts +1 -7
- package/esm/presentation/scheduledEmail/utils/filters.d.ts +2 -0
- package/esm/presentation/scheduledEmail/utils/filters.js +5 -0
- package/esm/presentation/shareDialog/DefaultShareDialog.d.ts +1 -1
- package/esm/presentation/shareDialog/DefaultShareDialog.js +2 -2
- package/esm/presentation/shareDialog/types.d.ts +5 -1
- package/esm/presentation/widget/insight/configuration/DrillTargets/useInvalidFilteringParametersIdentifiers.d.ts +2 -2
- package/esm/presentation/widget/insight/configuration/DrillTargets/useInvalidFilteringParametersIdentifiers.js +36 -5
- package/esm/presentation/widget/insight/configuration/InsightAlertConfig/EditAlert.js +2 -2
- package/esm/presentation/widget/insight/configuration/InsightAlertConfig/hooks/useInsightWidgetAlerting.js +3 -6
- package/esm/presentation/widget/insight/configuration/InsightAlerts.js +1 -9
- package/esm/sdk-ui-dashboard.d.ts +28 -240
- package/package.json +20 -20
- package/esm/model/react/filtering/shared.d.ts +0 -6
- package/esm/model/react/filtering/shared.js +0 -38
- package/esm/model/react/filtering/useAutomationAvailableDashboardFilters.d.ts +0 -13
- package/esm/model/react/filtering/useAutomationAvailableDashboardFilters.js +0 -54
- package/esm/model/react/filtering/useDashboardScheduledExportFilters.d.ts +0 -19
- package/esm/model/react/filtering/useDashboardScheduledExportFilters.js +0 -18
- package/esm/model/react/filtering/useScheduledExportFilters.d.ts +0 -26
- package/esm/model/react/filtering/useScheduledExportFilters.js +0 -23
- package/esm/model/react/filtering/useWidgetAlertFilters.d.ts +0 -33
- package/esm/model/react/filtering/useWidgetAlertFilters.js +0 -48
- package/esm/model/react/filtering/useWidgetScheduledExportFilters.d.ts +0 -33
- package/esm/model/react/filtering/useWidgetScheduledExportFilters.js +0 -48
- package/esm/model/react/useDashboardAlerting/useEnableAutomationFilterContext.d.ts +0 -4
- package/esm/model/react/useDashboardAlerting/useEnableAutomationFilterContext.js +0 -20
- package/esm/model/react/useDashboardAlertsOld.d.ts +0 -32
- package/esm/model/react/useDashboardAlertsOld.js +0 -141
- package/esm/presentation/alerting/DefaultAlertingDialog/DefaultAlertingDialogOld.d.ts +0 -5
- package/esm/presentation/alerting/DefaultAlertingDialog/DefaultAlertingDialogOld.js +0 -36
- package/esm/presentation/alerting/DefaultAlertingDialog/components/AlertAttributeSelectOld.d.ts +0 -17
- package/esm/presentation/alerting/DefaultAlertingDialog/components/AlertAttributeSelectOld.js +0 -103
- package/esm/presentation/alerting/DefaultAlertingManagementDialog/DefaultAlertingManagementDialogOld.d.ts +0 -5
- package/esm/presentation/alerting/DefaultAlertingManagementDialog/DefaultAlertingManagementDialogOld.js +0 -53
- package/esm/presentation/alerting/DefaultAlertingManagementDialog/components/AlertOld.d.ts +0 -9
- package/esm/presentation/alerting/DefaultAlertingManagementDialog/components/AlertOld.js +0 -84
- package/esm/presentation/alerting/DefaultAlertingManagementDialog/components/AlertsListOld.d.ts +0 -11
- package/esm/presentation/alerting/DefaultAlertingManagementDialog/components/AlertsListOld.js +0 -16
- package/esm/presentation/dashboard/DashboardHeader/AlertingDialogProviderOld.d.ts +0 -1
- package/esm/presentation/dashboard/DashboardHeader/AlertingDialogProviderOld.js +0 -12
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentFilters.d.ts +0 -29
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentFilters.js +0 -61
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentFiltersList.d.ts +0 -6
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentFiltersList.js +0 -12
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentItems.d.ts +0 -17
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentItems.js +0 -68
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentsWrapper.d.ts +0 -4
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/AttachmentsWrapper.js +0 -6
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/DashboardAttachments.d.ts +0 -15
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/DashboardAttachments.js +0 -42
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/WidgetAttachments.d.ts +0 -18
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/components/AttachmentsOld/WidgetAttachments.js +0 -25
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/types.d.ts +0 -2
- package/esm/presentation/scheduledEmail/DefaultScheduledEmailDialog/types.js +0 -2
- package/esm/presentation/widget/insight/configuration/InsightAlertsOld.d.ts +0 -2
- package/esm/presentation/widget/insight/configuration/InsightAlertsOld.js +0 -43
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
// (C) 2019-2026 GoodData Corporation
|
|
2
2
|
import { useCallback } from "react";
|
|
3
3
|
import { omit } from "lodash-es";
|
|
4
|
-
import { isAllValuesAttributeFilter,
|
|
5
|
-
import { useDashboardSelector } from "../../../../model/react/DashboardStoreProvider.js";
|
|
6
|
-
import { selectEnableAutomationFilterContext } from "../../../../model/store/config/configSelectors.js";
|
|
4
|
+
import { isAllValuesAttributeFilter, } from "@gooddata/sdk-model";
|
|
7
5
|
import { useCreateAlert } from "./useCreateAlert.js";
|
|
8
6
|
import { useUpdateAlert } from "./useUpdateAlert.js";
|
|
9
7
|
/**
|
|
@@ -18,44 +16,43 @@ import { useUpdateAlert } from "./useUpdateAlert.js";
|
|
|
18
16
|
* @param onResumeError - callback to be called when alert resuming fails
|
|
19
17
|
*/
|
|
20
18
|
export function useSaveAlertToBackend({ onCreateSuccess, onCreateError, onUpdateSuccess, onUpdateError, onPauseSuccess, onPauseError, onResumeSuccess, onResumeError, }) {
|
|
21
|
-
const enableAutomationFilterContext = useDashboardSelector(selectEnableAutomationFilterContext);
|
|
22
19
|
const alertCreator = useCreateAlert({
|
|
23
20
|
onSuccess: (alert) => onCreateSuccess?.(alert),
|
|
24
21
|
onError: onCreateError,
|
|
25
22
|
});
|
|
26
23
|
const handleCreateAlert = useCallback((alert) => {
|
|
27
|
-
const sanitizedAlert = sanitizeAutomation(alert
|
|
24
|
+
const sanitizedAlert = sanitizeAutomation(alert);
|
|
28
25
|
alertCreator.create(sanitizedAlert);
|
|
29
|
-
}, [alertCreator
|
|
26
|
+
}, [alertCreator]);
|
|
30
27
|
const alertUpdater = useUpdateAlert({
|
|
31
28
|
onSuccess: onUpdateSuccess,
|
|
32
29
|
onError: onUpdateError,
|
|
33
30
|
});
|
|
34
31
|
const handleUpdateAlert = useCallback((alert) => {
|
|
35
|
-
const sanitizedAlert = sanitizeAutomation(alert
|
|
32
|
+
const sanitizedAlert = sanitizeAutomation(alert);
|
|
36
33
|
alertUpdater.save(sanitizedAlert);
|
|
37
|
-
}, [alertUpdater
|
|
34
|
+
}, [alertUpdater]);
|
|
38
35
|
const alertPauser = useUpdateAlert({
|
|
39
36
|
onSuccess: onPauseSuccess,
|
|
40
37
|
onError: onPauseError,
|
|
41
38
|
});
|
|
42
39
|
const handlePauseAlert = useCallback((alert) => {
|
|
43
|
-
alertPauser.save(sanitizeAutomation(alert
|
|
44
|
-
}, [alertPauser
|
|
40
|
+
alertPauser.save(sanitizeAutomation(alert));
|
|
41
|
+
}, [alertPauser]);
|
|
45
42
|
const alertResumer = useUpdateAlert({
|
|
46
43
|
onSuccess: onResumeSuccess,
|
|
47
44
|
onError: onResumeError,
|
|
48
45
|
});
|
|
49
46
|
const handleResumeAlert = useCallback((alert) => {
|
|
50
|
-
alertResumer.save(sanitizeAutomation(alert
|
|
51
|
-
}, [alertResumer
|
|
47
|
+
alertResumer.save(sanitizeAutomation(alert));
|
|
48
|
+
}, [alertResumer]);
|
|
52
49
|
const isSavingAlert = alertCreator.creationStatus === "running" ||
|
|
53
50
|
alertUpdater.savingStatus === "running" ||
|
|
54
51
|
alertPauser.savingStatus === "running" ||
|
|
55
52
|
alertResumer.savingStatus === "running";
|
|
56
53
|
return { handleCreateAlert, handleUpdateAlert, handlePauseAlert, handleResumeAlert, isSavingAlert };
|
|
57
54
|
}
|
|
58
|
-
function sanitizeAutomation(automationToSave
|
|
55
|
+
function sanitizeAutomation(automationToSave) {
|
|
59
56
|
let automation = {
|
|
60
57
|
...automationToSave,
|
|
61
58
|
};
|
|
@@ -71,7 +68,7 @@ function sanitizeAutomation(automationToSave, enableAutomationFilterContext) {
|
|
|
71
68
|
...automation.alert,
|
|
72
69
|
execution: {
|
|
73
70
|
...automation.alert.execution,
|
|
74
|
-
filters: removeNoopFiltersFromAlertFilters(automation.alert.execution.filters
|
|
71
|
+
filters: removeNoopFiltersFromAlertFilters(automation.alert.execution.filters),
|
|
75
72
|
},
|
|
76
73
|
},
|
|
77
74
|
};
|
|
@@ -81,16 +78,7 @@ function sanitizeAutomation(automationToSave, enableAutomationFilterContext) {
|
|
|
81
78
|
/**
|
|
82
79
|
* Strip noop filters that have no effect on execution and should not appear in alert email notifications.
|
|
83
80
|
* - "All values" attribute filters are always stripped.
|
|
84
|
-
* - "All time" date filters are stripped only for the legacy path (new path handles this in getAppliedWidgetFilters).
|
|
85
81
|
*/
|
|
86
|
-
function removeNoopFiltersFromAlertFilters(filters
|
|
87
|
-
return filters.filter((filter) =>
|
|
88
|
-
if (isAllValuesAttributeFilter(filter)) {
|
|
89
|
-
return false;
|
|
90
|
-
}
|
|
91
|
-
if (!enableAutomationFilterContext && isNoopAllTimeDateFilter(filter)) {
|
|
92
|
-
return false;
|
|
93
|
-
}
|
|
94
|
-
return true;
|
|
95
|
-
});
|
|
82
|
+
function removeNoopFiltersFromAlertFilters(filters) {
|
|
83
|
+
return filters.filter((filter) => !isAllValuesAttributeFilter(filter));
|
|
96
84
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ComponentType } from "react";
|
|
2
|
-
import { type DateAttributeGranularity, type IAttribute, type IAutomationMetadataObject, type IDataSetMetadataObject, type IInsight, type
|
|
2
|
+
import { type DateAttributeGranularity, type IAttribute, type IAutomationMetadataObject, type IDataSetMetadataObject, type IInsight, type IMeasure, type INotificationChannelIdentifier, type INotificationChannelMetadataObject, type IWorkspaceUser } from "@gooddata/sdk-model";
|
|
3
3
|
import { type GoodDataSdkError } from "@gooddata/sdk-ui";
|
|
4
4
|
import type { ExtendedDashboardWidget } from "../../model/types/layoutTypes.js";
|
|
5
5
|
/**
|
|
@@ -67,31 +67,6 @@ export interface IAlertingDialogProps {
|
|
|
67
67
|
*/
|
|
68
68
|
onDeleteError?: (error: GoodDataSdkError) => void;
|
|
69
69
|
}
|
|
70
|
-
/**
|
|
71
|
-
* @alpha
|
|
72
|
-
*/
|
|
73
|
-
export interface IAlertingDialogOldProps {
|
|
74
|
-
/**
|
|
75
|
-
* Alert to be edited in the dialog.
|
|
76
|
-
*/
|
|
77
|
-
editAlert?: IAutomationMetadataObject;
|
|
78
|
-
/**
|
|
79
|
-
* Callback to be called, when user save the existing alert.
|
|
80
|
-
*/
|
|
81
|
-
onUpdate?: (alertingDefinition: IAutomationMetadataObject) => void;
|
|
82
|
-
/**
|
|
83
|
-
* Callback to be called, when user closes the alerting dialog.
|
|
84
|
-
*/
|
|
85
|
-
onCancel?: () => void;
|
|
86
|
-
/**
|
|
87
|
-
* Widget to be edited in the dialog.
|
|
88
|
-
*/
|
|
89
|
-
editWidget?: IInsightWidget;
|
|
90
|
-
/**
|
|
91
|
-
* Anchor element for the dialog.
|
|
92
|
-
*/
|
|
93
|
-
anchorEl?: HTMLElement | null;
|
|
94
|
-
}
|
|
95
70
|
/**
|
|
96
71
|
* @alpha
|
|
97
72
|
*/
|
|
@@ -146,52 +121,6 @@ export interface IAlertingManagementDialogProps {
|
|
|
146
121
|
*/
|
|
147
122
|
onPauseError: (error: GoodDataSdkError, pause: boolean) => void;
|
|
148
123
|
}
|
|
149
|
-
/**
|
|
150
|
-
* @alpha
|
|
151
|
-
*/
|
|
152
|
-
export interface IAlertingManagementDialogOldProps {
|
|
153
|
-
/**
|
|
154
|
-
* Callback to be called, when user clicks alert item for editing.
|
|
155
|
-
*/
|
|
156
|
-
onEdit?: (alertingDefinition: IAutomationMetadataObject, widget: IInsightWidget | undefined, anchor: HTMLElement | null, onClosed: () => void) => void;
|
|
157
|
-
/**
|
|
158
|
-
* Callback to be called, when user closes the alert management dialog.
|
|
159
|
-
*/
|
|
160
|
-
onClose?: () => void;
|
|
161
|
-
/**
|
|
162
|
-
* Is loading alert data?
|
|
163
|
-
*/
|
|
164
|
-
isLoadingAlertingData: boolean;
|
|
165
|
-
/**
|
|
166
|
-
* Error occurred while loading alert data?
|
|
167
|
-
*/
|
|
168
|
-
alertingDataError?: GoodDataSdkError;
|
|
169
|
-
/**
|
|
170
|
-
* Automations in workspace
|
|
171
|
-
*/
|
|
172
|
-
automations: IAutomationMetadataObject[];
|
|
173
|
-
/**
|
|
174
|
-
* Callback to be called, when alert is deleted.
|
|
175
|
-
* @param alert - alert that was deleted
|
|
176
|
-
*/
|
|
177
|
-
onDeleteSuccess?: (alert: IAutomationMetadataObject) => void;
|
|
178
|
-
/**
|
|
179
|
-
* Callback to be called, when alert fails to delete.
|
|
180
|
-
*/
|
|
181
|
-
onDeleteError?: (error: GoodDataSdkError) => void;
|
|
182
|
-
/**
|
|
183
|
-
* Callback to be called, when alert is paused.
|
|
184
|
-
* @param alert - alert that was paused
|
|
185
|
-
* @param pause - true if alert was paused, false if it was resumed
|
|
186
|
-
*/
|
|
187
|
-
onPauseSuccess: (alert: IAutomationMetadataObject, pause: boolean) => void;
|
|
188
|
-
/**
|
|
189
|
-
* Callback to be called, when alert fails to pause.
|
|
190
|
-
* @param error - error that occurred
|
|
191
|
-
* @param pause - true if alert was paused, false if it was resumed
|
|
192
|
-
*/
|
|
193
|
-
onPauseError: (error: GoodDataSdkError, pause: boolean) => void;
|
|
194
|
-
}
|
|
195
124
|
/**
|
|
196
125
|
* @alpha
|
|
197
126
|
*/
|
|
@@ -13,11 +13,10 @@ export interface IAutomationValidationResult {
|
|
|
13
13
|
visibleFiltersAreMissing: boolean;
|
|
14
14
|
incompatibleSelectionTypeIsAppliedInSavedFilters: boolean;
|
|
15
15
|
}
|
|
16
|
-
export declare function useValidateExistingAutomationFilters({ automationToEdit, widget, insight
|
|
16
|
+
export declare function useValidateExistingAutomationFilters({ automationToEdit, widget, insight }: {
|
|
17
17
|
automationToEdit?: IAutomationMetadataObject;
|
|
18
18
|
widget?: ExtendedDashboardWidget;
|
|
19
19
|
insight?: IInsight;
|
|
20
|
-
enableAutomationFilterContext?: boolean;
|
|
21
20
|
}): IAutomationValidationResult;
|
|
22
21
|
/**
|
|
23
22
|
* Validate existing automation filters against current dashboard filter context and optionally saved widget / insight.
|
|
@@ -17,8 +17,8 @@ function sanitizeCommonDateFilter(filter, commonDateFilterId) {
|
|
|
17
17
|
}
|
|
18
18
|
return filter;
|
|
19
19
|
}
|
|
20
|
-
function shouldSkipValidation(
|
|
21
|
-
if (!
|
|
20
|
+
function shouldSkipValidation(automationToEdit, widget, savedDashboardFilters, savedDashboardFiltersByTab) {
|
|
21
|
+
if (!automationToEdit) {
|
|
22
22
|
return true;
|
|
23
23
|
}
|
|
24
24
|
// Handle case, when dashboard scheduled export filters are not saved (undefined === always use latest dashboard filters in the scheduled export)
|
|
@@ -26,7 +26,7 @@ function shouldSkipValidation(enableAutomationFilterContext, automationToEdit, w
|
|
|
26
26
|
if (widget) {
|
|
27
27
|
return !isInsightWidget(widget);
|
|
28
28
|
}
|
|
29
|
-
return typeof savedDashboardFilters === "undefined";
|
|
29
|
+
return typeof savedDashboardFilters === "undefined" && typeof savedDashboardFiltersByTab === "undefined";
|
|
30
30
|
}
|
|
31
31
|
function hasMatchingPerTabFormat(widget, dashboardFiltersByTab, savedAutomationVisibleFiltersByTab, savedDashboardFiltersByTab) {
|
|
32
32
|
return (!widget &&
|
|
@@ -52,7 +52,7 @@ const defaultValidState = {
|
|
|
52
52
|
visibleFiltersAreMissing: false,
|
|
53
53
|
incompatibleSelectionTypeIsAppliedInSavedFilters: false,
|
|
54
54
|
};
|
|
55
|
-
export function useValidateExistingAutomationFilters({ automationToEdit, widget, insight,
|
|
55
|
+
export function useValidateExistingAutomationFilters({ automationToEdit, widget, insight, }) {
|
|
56
56
|
const lockedFilters = useDashboardSelector(selectDashboardLockedFilters);
|
|
57
57
|
const hiddenFilters = useDashboardSelector(selectDashboardHiddenFilters);
|
|
58
58
|
const dashboardFilters = useDashboardSelector(selectDashboardFiltersWithoutCrossFiltering);
|
|
@@ -67,7 +67,7 @@ export function useValidateExistingAutomationFilters({ automationToEdit, widget,
|
|
|
67
67
|
const savedAlertFilters = getAutomationAlertFilters(automationToEdit);
|
|
68
68
|
const savedDashboardFilters = getAutomationDashboardFilters(automationToEdit);
|
|
69
69
|
const savedDashboardFiltersByTab = getAutomationDashboardFiltersByTab(automationToEdit);
|
|
70
|
-
if (shouldSkipValidation(
|
|
70
|
+
if (shouldSkipValidation(automationToEdit, widget, savedDashboardFilters, savedDashboardFiltersByTab)) {
|
|
71
71
|
return defaultValidState;
|
|
72
72
|
}
|
|
73
73
|
// Check for matching format scenario: both automation and dashboard have per-tab structure
|
|
@@ -1,13 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
// (C) 2022-2026 GoodData Corporation
|
|
3
|
-
import { useDashboardSelector } from "../../../model/react/DashboardStoreProvider.js";
|
|
4
|
-
import { selectEnableAutomationFilterContext } from "../../../model/store/config/configSelectors.js";
|
|
5
3
|
import { AlertingDialogProviderNew } from "./AlertingDialogProviderNew.js";
|
|
6
|
-
import { AlertingDialogProviderOld } from "./AlertingDialogProviderOld.js";
|
|
7
4
|
export function AlertingDialogProvider() {
|
|
8
|
-
|
|
9
|
-
if (enableAutomationFilters) {
|
|
10
|
-
return _jsx(AlertingDialogProviderNew, {});
|
|
11
|
-
}
|
|
12
|
-
return _jsx(AlertingDialogProviderOld, {});
|
|
5
|
+
return _jsx(AlertingDialogProviderNew, {});
|
|
13
6
|
}
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
// (C) 2022-2026 GoodData Corporation
|
|
3
|
-
import {
|
|
3
|
+
import { getAutomationDashboardFilters, getAutomationVisualizationFilters, } from "../../../_staging/automation/index.js";
|
|
4
|
+
import { useDashboardSelector } from "../../../model/react/DashboardStoreProvider.js";
|
|
4
5
|
import { useDashboardScheduledEmails } from "../../../model/react/useDasboardScheduledEmails/useDashboardScheduledEmails.js";
|
|
5
6
|
import { useWorkspaceUsers } from "../../../model/react/useWorkspaceUsers.js";
|
|
7
|
+
import { selectAutomationDefaultSelectedFilters, selectDashboardHiddenFilters, } from "../../../model/store/filtering/dashboardFilterSelectors.js";
|
|
8
|
+
import { useWidgetAutomationFilters } from "../../scheduledEmail/hooks/useWidgetAutomationFilters.js";
|
|
6
9
|
import { ScheduledEmailDialog } from "../../scheduledEmail/ScheduledEmailDialog.js";
|
|
7
10
|
import { ScheduledEmailManagementDialog } from "../../scheduledEmail/ScheduledEmailManagementDialog.js";
|
|
11
|
+
import { getAppliedDashboardFilters } from "../../scheduledEmail/utils/filters.js";
|
|
8
12
|
export function ScheduledEmailDialogProvider() {
|
|
9
13
|
const {
|
|
10
14
|
// Shared Local State
|
|
@@ -15,13 +19,18 @@ export function ScheduledEmailDialogProvider() {
|
|
|
15
19
|
isScheduleEmailingDialogOpen, onScheduleEmailingCancel, onScheduleEmailingBack, onScheduleEmailingCreateSuccess, onScheduleEmailingCreateError, onScheduleEmailingSaveSuccess, onScheduleEmailingSaveError,
|
|
16
20
|
// Management / List Dialog
|
|
17
21
|
isScheduleEmailingManagementDialogOpen, onScheduleEmailingManagementClose, onScheduleEmailingManagementAdd, onScheduleEmailingManagementEdit, onScheduleEmailingManagementDeleteSuccess, onScheduleEmailingManagementDeleteError, } = useDashboardScheduledEmails();
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
});
|
|
23
|
-
const
|
|
24
|
-
const
|
|
22
|
+
const automationDefaultSelectedFilters = useDashboardSelector(selectAutomationDefaultSelectedFilters);
|
|
23
|
+
const dashboardHiddenFilters = useDashboardSelector(selectDashboardHiddenFilters);
|
|
24
|
+
const { executionFilters: savedWidgetFilters } = getAutomationVisualizationFilters(scheduledExportToEdit);
|
|
25
|
+
const savedDashboardFilters = getAutomationDashboardFilters(scheduledExportToEdit);
|
|
26
|
+
const { result: liveWidgetFilters, status: widgetFiltersStatus, error: widgetFiltersError, } = useWidgetAutomationFilters(widget, insight);
|
|
27
|
+
const widgetFilters = savedWidgetFilters ?? liveWidgetFilters;
|
|
28
|
+
const shouldLoadWidgetFilters = !!widget && !savedWidgetFilters;
|
|
29
|
+
const dashboardFilters = savedDashboardFilters ??
|
|
30
|
+
getAppliedDashboardFilters(automationDefaultSelectedFilters, dashboardHiddenFilters, true);
|
|
31
|
+
const isLoading = automationsLoading ||
|
|
32
|
+
(shouldLoadWidgetFilters && (widgetFiltersStatus === "pending" || widgetFiltersStatus === "running"));
|
|
33
|
+
const loadingError = (shouldLoadWidgetFilters ? widgetFiltersError : undefined) ?? automationsError;
|
|
25
34
|
if (!isInitialized) {
|
|
26
35
|
return null;
|
|
27
36
|
}
|
|
@@ -13,6 +13,7 @@ import { selectDashboardPermissions } from "../../../model/store/dashboardPermis
|
|
|
13
13
|
import { selectPersistedDashboard } from "../../../model/store/meta/metaSelectors.js";
|
|
14
14
|
import { selectCanManageWorkspace } from "../../../model/store/permissions/permissionsSelectors.js";
|
|
15
15
|
import { selectFilterContextFilters } from "../../../model/store/tabs/filterContext/filterContextSelectors.js";
|
|
16
|
+
import { selectFilterViewParameters } from "../../../model/store/tabs/parameters/parametersSelectors.js";
|
|
16
17
|
import { selectIsDashboardShareLinkVisible, selectIsShareGrantVisible, } from "../../../model/store/topBar/topBarSelectors.js";
|
|
17
18
|
import { uiActions } from "../../../model/store/ui/index.js";
|
|
18
19
|
import { selectIsShareDialogOpen } from "../../../model/store/ui/uiSelectors.js";
|
|
@@ -28,6 +29,7 @@ const useShareDialogDashboardHeader = () => {
|
|
|
28
29
|
const isWorkspaceManager = useDashboardSelector(selectCanManageWorkspace);
|
|
29
30
|
const dashboardPermissions = useDashboardSelector(selectDashboardPermissions);
|
|
30
31
|
const dashboardFilters = useDashboardSelector(selectFilterContextFilters);
|
|
32
|
+
const dashboardParameters = useDashboardSelector(selectFilterViewParameters);
|
|
31
33
|
const isShareGrantHidden = !useDashboardSelector(selectIsShareGrantVisible);
|
|
32
34
|
const isDashboardShareDialogLinkEnabled = useDashboardSelector(selectEnableDashboardShareDialogLink);
|
|
33
35
|
const showDashboardShareLink = useDashboardSelector(selectIsDashboardShareLinkVisible);
|
|
@@ -78,6 +80,7 @@ const useShareDialogDashboardHeader = () => {
|
|
|
78
80
|
isCurrentUserWorkspaceManager: isWorkspaceManager,
|
|
79
81
|
dashboardPermissions,
|
|
80
82
|
dashboardFilters,
|
|
83
|
+
dashboardParameters,
|
|
81
84
|
isShareGrantHidden,
|
|
82
85
|
applyShareGrantOnSelect,
|
|
83
86
|
showDashboardShareLink,
|
|
@@ -89,7 +92,7 @@ const useShareDialogDashboardHeader = () => {
|
|
|
89
92
|
* @internal
|
|
90
93
|
*/
|
|
91
94
|
export function ShareDialogDashboardHeader() {
|
|
92
|
-
const { backend, workspace, isShareDialogOpen, persistedDashboard, currentUser, onCloseShareDialog, onApplyShareDialog, onErrorShareDialog, onInteractionShareDialog, isLockingSupported, isCurrentUserWorkspaceManager, dashboardPermissions, dashboardFilters, isShareGrantHidden, applyShareGrantOnSelect, showDashboardShareLink, onShareLinkCopy, isGranteeShareLoading, } = useShareDialogDashboardHeader();
|
|
95
|
+
const { backend, workspace, isShareDialogOpen, persistedDashboard, currentUser, onCloseShareDialog, onApplyShareDialog, onErrorShareDialog, onInteractionShareDialog, isLockingSupported, isCurrentUserWorkspaceManager, dashboardPermissions, dashboardFilters, dashboardParameters, isShareGrantHidden, applyShareGrantOnSelect, showDashboardShareLink, onShareLinkCopy, isGranteeShareLoading, } = useShareDialogDashboardHeader();
|
|
93
96
|
if (!isShareDialogOpen) {
|
|
94
97
|
return null;
|
|
95
98
|
}
|
|
@@ -100,5 +103,5 @@ export function ShareDialogDashboardHeader() {
|
|
|
100
103
|
canShareLockedAffectedObject: dashboardPermissions.canShareLockedDashboard,
|
|
101
104
|
canViewAffectedObject: dashboardPermissions.canViewDashboard,
|
|
102
105
|
};
|
|
103
|
-
return (_jsx(ShareDialog, { backend: backend, workspace: workspace, isVisible: isShareDialogOpen, currentUser: currentUser, sharedObject: persistedDashboard, onCancel: onCloseShareDialog, onApply: onApplyShareDialog, onError: onErrorShareDialog, isLockingSupported: isLockingSupported, isCurrentUserWorkspaceManager: isCurrentUserWorkspaceManager, currentUserPermissions: currentUserPermissions, dashboardFilters: dashboardFilters, onInteraction: onInteractionShareDialog, isShareGrantHidden: isShareGrantHidden, applyShareGrantOnSelect: applyShareGrantOnSelect, showDashboardShareLink: showDashboardShareLink, onShareLinkCopy: onShareLinkCopy, isGranteeShareLoading: isGranteeShareLoading }));
|
|
106
|
+
return (_jsx(ShareDialog, { backend: backend, workspace: workspace, isVisible: isShareDialogOpen, currentUser: currentUser, sharedObject: persistedDashboard, onCancel: onCloseShareDialog, onApply: onApplyShareDialog, onError: onErrorShareDialog, isLockingSupported: isLockingSupported, isCurrentUserWorkspaceManager: isCurrentUserWorkspaceManager, currentUserPermissions: currentUserPermissions, dashboardFilters: dashboardFilters, dashboardParameters: dashboardParameters, onInteraction: onInteractionShareDialog, isShareGrantHidden: isShareGrantHidden, applyShareGrantOnSelect: applyShareGrantOnSelect, showDashboardShareLink: showDashboardShareLink, onShareLinkCopy: onShareLinkCopy, isGranteeShareLoading: isGranteeShareLoading }));
|
|
104
107
|
}
|
|
@@ -6,7 +6,7 @@ import { BackendProvider, ErrorComponent as DefaultError, LoadingComponent as De
|
|
|
6
6
|
import { OverlayController, OverlayControllerProvider } from "@gooddata/sdk-ui-kit";
|
|
7
7
|
import { ThemeProvider } from "@gooddata/sdk-ui-theme-provider";
|
|
8
8
|
import { DashboardStoreProvider } from "../../../model/react/DashboardStoreProvider.js";
|
|
9
|
-
import {
|
|
9
|
+
import { DefaultAlertingDialog } from "../../alerting/DefaultAlertingDialog/DefaultAlertingDialog.js";
|
|
10
10
|
import { DefaultAlertingManagementDialogNew } from "../../alerting/DefaultAlertingManagementDialog/DefaultAlertingManagementDialogNew.js";
|
|
11
11
|
import { DASHBOARD_OVERLAYS_Z_INDEX } from "../../constants/zIndex.js";
|
|
12
12
|
import { DashboardComponentsProvider } from "../../dashboardContexts/DashboardComponentsContext.js";
|
|
@@ -58,7 +58,7 @@ function resolveDialogComponents(props) {
|
|
|
58
58
|
ScheduledEmailManagementDialogComponent: props.ScheduledEmailManagementDialogComponent ?? DefaultScheduledEmailManagementDialog,
|
|
59
59
|
ShareDialogComponent: props.ShareDialogComponent ?? DefaultShareDialog,
|
|
60
60
|
AlertingManagementDialogComponent: props.AlertingManagementDialogComponent ?? DefaultAlertingManagementDialogNew,
|
|
61
|
-
AlertingDialogComponent: props.AlertingDialogComponent ??
|
|
61
|
+
AlertingDialogComponent: props.AlertingDialogComponent ?? DefaultAlertingDialog,
|
|
62
62
|
SaveAsDialogComponent: props.SaveAsDialogComponent ?? DefaultSaveAsDialog,
|
|
63
63
|
DashboardSettingsDialogComponent: props.DashboardSettingsDialogComponent ?? DefaultDashboardSettingsDialog,
|
|
64
64
|
};
|
|
@@ -5,15 +5,16 @@ import { HighlightStyle, StreamLanguage, syntaxHighlighting } from "@codemirror/
|
|
|
5
5
|
import { Tag } from "@lezer/highlight";
|
|
6
6
|
import { compact, uniqBy } from "lodash-es";
|
|
7
7
|
import { FormattedMessage, useIntl } from "react-intl";
|
|
8
|
-
import { filterObjRef, idRef, isArbitraryAttributeFilter, isAttributeFilter, isMatchAttributeFilter, isNegativeAttributeFilter, isPositiveAttributeFilter, isUriRef, objRefToString, serializeObjRef, } from "@gooddata/sdk-model";
|
|
8
|
+
import { filterObjRef, idRef, insightFilters as insightDefinitionFilters, isArbitraryAttributeFilter, isAttributeFilter, isMatchAttributeFilter, isMeasureValueFilter, isNegativeAttributeFilter, isPositiveAttributeFilter, isUriRef, objRefToString, serializeObjRef, } from "@gooddata/sdk-model";
|
|
9
9
|
import { ConfirmDialogBase, FullScreenOverlay, Overlay, OverlayController, OverlayControllerProvider, SyntaxHighlightingInput, useMediaQuery, } from "@gooddata/sdk-ui-kit";
|
|
10
10
|
import { dashboardAttributeFilterItemToAttributeFilter } from "../../../../converters/filterConverters.js";
|
|
11
11
|
import { useDashboardSelector } from "../../../../model/react/DashboardStoreProvider.js";
|
|
12
12
|
import { useWidgetFilters } from "../../../../model/react/useWidgetFilters.js";
|
|
13
|
-
import { selectAllCatalogDisplayFormsMap } from "../../../../model/store/catalog/catalogSelectors.js";
|
|
14
|
-
import { selectIsWhiteLabeled } from "../../../../model/store/config/configSelectors.js";
|
|
13
|
+
import { selectAllCatalogDisplayFormsMap, selectAllCatalogMeasuresMap, } from "../../../../model/store/catalog/catalogSelectors.js";
|
|
14
|
+
import { selectEnableMeasureValueFilterKD, selectIsWhiteLabeled, } from "../../../../model/store/config/configSelectors.js";
|
|
15
|
+
import { selectInsightByWidgetRef } from "../../../../model/store/insights/insightsSelectors.js";
|
|
15
16
|
import { selectAttributeFilterConfigsOverrides } from "../../../../model/store/tabs/attributeFilterConfigs/attributeFilterConfigsSelectors.js";
|
|
16
|
-
import { selectFilterContextAttributeFilterItems } from "../../../../model/store/tabs/filterContext/filterContextSelectors.js";
|
|
17
|
+
import { selectFilterContextAttributeFilterItems, selectFilterContextMeasureValueFilters, } from "../../../../model/store/tabs/filterContext/filterContextSelectors.js";
|
|
17
18
|
import { selectFilterableWidgetByRef } from "../../../../model/store/tabs/layout/layoutSelectors.js";
|
|
18
19
|
import { DASHBOARD_HEADER_OVERLAYS_Z_INDEX } from "../../../constants/zIndex.js";
|
|
19
20
|
import { useInvalidFilteringParametersIdentifiers } from "../../../widget/insight/configuration/DrillTargets/useInvalidFilteringParametersIdentifiers.js";
|
|
@@ -114,6 +115,30 @@ const buildValidDashboardFiltersFormattingRule = (attributeFilters, attributeFil
|
|
|
114
115
|
token: customTags.filter.toString(),
|
|
115
116
|
};
|
|
116
117
|
};
|
|
118
|
+
const buildValidDashboardMvfFormattingRule = (measureIdentifiers) => {
|
|
119
|
+
if (measureIdentifiers.length === 0) {
|
|
120
|
+
return undefined;
|
|
121
|
+
}
|
|
122
|
+
const validDashboardMvfPlaceholders = measureIdentifiers
|
|
123
|
+
.map((id) => `{dash_mvf_condition\\(${id}\\)}`)
|
|
124
|
+
.join("|");
|
|
125
|
+
return {
|
|
126
|
+
regex: new RegExp(`^${validDashboardMvfPlaceholders}`),
|
|
127
|
+
token: customTags.filter.toString(),
|
|
128
|
+
};
|
|
129
|
+
};
|
|
130
|
+
const buildValidInsightMvfFormattingRule = (measureIdentifiers) => {
|
|
131
|
+
if (measureIdentifiers.length === 0) {
|
|
132
|
+
return undefined;
|
|
133
|
+
}
|
|
134
|
+
const validInsightMvfPlaceholders = measureIdentifiers
|
|
135
|
+
.map((id) => `{mvf_condition\\(${id}\\)}`)
|
|
136
|
+
.join("|");
|
|
137
|
+
return {
|
|
138
|
+
regex: new RegExp(`^${validInsightMvfPlaceholders}`),
|
|
139
|
+
token: customTags.filter.toString(),
|
|
140
|
+
};
|
|
141
|
+
};
|
|
117
142
|
const IDENTIFIER_RULE = {
|
|
118
143
|
regex: /^\{workspace_id\}|\{project_id\}|\{visualization_id\}|\{widget_id\}|\{dashboard_id\}|\{client_id\}|\{data_product_id\}/,
|
|
119
144
|
token: customTags.identifier.toString(),
|
|
@@ -127,6 +152,14 @@ const INVALID_DASHBOARD_ATTRIBUTE_FILTER_RULE = {
|
|
|
127
152
|
regex: /^\{dash_attribute_filter_selection\(.*?\)\}/,
|
|
128
153
|
token: customTags.invalidFilter.toString(),
|
|
129
154
|
};
|
|
155
|
+
const INVALID_DASHBOARD_MVF_RULE = {
|
|
156
|
+
regex: /^\{dash_mvf_condition\(.*?\)\}/,
|
|
157
|
+
token: customTags.invalidFilter.toString(),
|
|
158
|
+
};
|
|
159
|
+
const INVALID_INSIGHT_MVF_RULE = {
|
|
160
|
+
regex: /^\{mvf_condition\(.*?\)\}/,
|
|
161
|
+
token: customTags.invalidFilter.toString(),
|
|
162
|
+
};
|
|
130
163
|
const INVALID_INSIGHT_ATTRIBUTE_FILTER_RULE = {
|
|
131
164
|
regex: /^\{attribute_filter_selection\(.*?\)\}/,
|
|
132
165
|
token: customTags.invalidFilter.toString(),
|
|
@@ -134,27 +167,55 @@ const INVALID_INSIGHT_ATTRIBUTE_FILTER_RULE = {
|
|
|
134
167
|
const DEFAULT_RULES = [
|
|
135
168
|
INVALID_DISPLAY_FORMS_RULE,
|
|
136
169
|
INVALID_DASHBOARD_ATTRIBUTE_FILTER_RULE,
|
|
170
|
+
INVALID_DASHBOARD_MVF_RULE,
|
|
171
|
+
INVALID_INSIGHT_MVF_RULE,
|
|
137
172
|
INVALID_INSIGHT_ATTRIBUTE_FILTER_RULE,
|
|
138
173
|
IDENTIFIER_RULE,
|
|
139
174
|
INVALID_IDENTIFIER_RULE,
|
|
140
175
|
];
|
|
141
|
-
const buildFormattingRules = (attributeDisplayForms, dashboardFilters, insightFilters, attributeFilterConfigs) => {
|
|
176
|
+
const buildFormattingRules = (attributeDisplayForms, dashboardFilters, insightFilters, dashboardMeasureIdentifiers, insightMeasureIdentifiers, attributeFilterConfigs) => {
|
|
142
177
|
const validDisplayFormsRule = buildValidDisplayFormsFormattingRule(attributeDisplayForms);
|
|
143
178
|
const validInsightFiltersRule = buildValidInsightFiltersFormattingRule(insightFilters);
|
|
144
179
|
const validDashboardFiltersRule = buildValidDashboardFiltersFormattingRule(dashboardFilters, attributeFilterConfigs);
|
|
180
|
+
const validDashboardMvfRule = buildValidDashboardMvfFormattingRule(dashboardMeasureIdentifiers);
|
|
181
|
+
const validInsightMvfRule = buildValidInsightMvfFormattingRule(insightMeasureIdentifiers);
|
|
145
182
|
return compact([
|
|
146
183
|
validDisplayFormsRule,
|
|
147
184
|
validDashboardFiltersRule,
|
|
185
|
+
validDashboardMvfRule,
|
|
148
186
|
validInsightFiltersRule,
|
|
187
|
+
validInsightMvfRule,
|
|
149
188
|
...DEFAULT_RULES,
|
|
150
189
|
]);
|
|
151
190
|
};
|
|
152
|
-
function UrlInputPanel({ currentUrlValue, onChange, onCursor, documentationLink, attributeDisplayForms, intl, insightFilters, dashboardFilters, attributeFilterConfigs, }) {
|
|
191
|
+
function UrlInputPanel({ currentUrlValue, onChange, onCursor, documentationLink, attributeDisplayForms, intl, insightFilters, dashboardFilters, dashboardMeasureValueFilters, insightMeasureValueFilters, enableInsightMeasureValueFilters, attributeFilterConfigs, }) {
|
|
153
192
|
const isWhiteLabeled = useDashboardSelector(selectIsWhiteLabeled);
|
|
193
|
+
const catalogMeasuresMap = useDashboardSelector(selectAllCatalogMeasuresMap);
|
|
194
|
+
const dashboardMeasureIdentifiers = useMemo(() => {
|
|
195
|
+
return (dashboardMeasureValueFilters ?? []).map((filter) => {
|
|
196
|
+
const measureRef = filter.dashboardMeasureValueFilter.measure;
|
|
197
|
+
return catalogMeasuresMap.get(measureRef)?.measure.id ?? objRefToString(measureRef);
|
|
198
|
+
});
|
|
199
|
+
}, [catalogMeasuresMap, dashboardMeasureValueFilters]);
|
|
200
|
+
const insightMeasureIdentifiers = useMemo(() => enableInsightMeasureValueFilters
|
|
201
|
+
? (insightMeasureValueFilters ?? []).map((filter) => {
|
|
202
|
+
const measureRef = filter.measureValueFilter.measure;
|
|
203
|
+
return objRefToString(measureRef);
|
|
204
|
+
})
|
|
205
|
+
: [], [enableInsightMeasureValueFilters, insightMeasureValueFilters]);
|
|
154
206
|
const syntaxHighlightingRules = useMemo(() => attributeDisplayForms &&
|
|
155
207
|
insightFilters &&
|
|
156
208
|
dashboardFilters &&
|
|
157
|
-
|
|
209
|
+
dashboardMeasureValueFilters &&
|
|
210
|
+
buildFormattingRules(attributeDisplayForms, dashboardFilters, insightFilters, dashboardMeasureIdentifiers, insightMeasureIdentifiers, attributeFilterConfigs), [
|
|
211
|
+
attributeDisplayForms,
|
|
212
|
+
insightFilters,
|
|
213
|
+
dashboardFilters,
|
|
214
|
+
dashboardMeasureValueFilters,
|
|
215
|
+
dashboardMeasureIdentifiers,
|
|
216
|
+
insightMeasureIdentifiers,
|
|
217
|
+
attributeFilterConfigs,
|
|
218
|
+
]);
|
|
158
219
|
return (_jsxs("div", { children: [
|
|
159
220
|
_jsx("label", { className: "gd-label", children: _jsx(FormattedMessage, { id: "configurationPanel.drillIntoUrl.editor.textAreaLabel" }) }), _jsx(UrlInput, { onChange: onChange, onCursor: onCursor, currentUrlValue: currentUrlValue, syntaxHighlightingRules: syntaxHighlightingRules, intl: intl }), !isWhiteLabeled && documentationLink ? _jsx(HelpLink, { link: documentationLink }) : null] }));
|
|
160
221
|
}
|
|
@@ -163,19 +224,33 @@ const initialCursorPosition = {
|
|
|
163
224
|
to: 0,
|
|
164
225
|
};
|
|
165
226
|
const insertPlaceholderAtCursor = (text, placeholder, cursor) => `${text.substring(0, cursor.from)}${placeholder}${text.substring(cursor.to)}`;
|
|
166
|
-
const
|
|
167
|
-
|
|
168
|
-
|
|
227
|
+
const URL_START_RULES = [
|
|
228
|
+
/^[A-Za-z0-9.\-+]+:/,
|
|
229
|
+
/^\{attribute_title\(/,
|
|
230
|
+
/^\{attribute_filter_selection\(/,
|
|
231
|
+
/^\{dash_attribute_filter_selection\(/,
|
|
232
|
+
/^\{dash_mvf_condition\(/,
|
|
233
|
+
];
|
|
234
|
+
const INSIGHT_MVF_URL_START_RULE = /^\{mvf_condition\(/;
|
|
235
|
+
const assertValidUrl = (url, enableInsightMeasureValueFilters) => {
|
|
236
|
+
const rules = enableInsightMeasureValueFilters
|
|
237
|
+
? [...URL_START_RULES, INSIGHT_MVF_URL_START_RULE]
|
|
238
|
+
: URL_START_RULES;
|
|
239
|
+
return rules.some((rule) => rule.test(url)) ? url : `https://${url}`;
|
|
240
|
+
};
|
|
169
241
|
const getWarningTextForInvalidParameters = (parameters) => {
|
|
170
242
|
const invalidParameters = parameters.map((parameter) => `"${parameter}"`).join(", ");
|
|
171
243
|
return (_jsx(FormattedMessage, { id: "configurationPanel.drillIntoUrl.editor.invalidAttributeDisplayForms", values: { invalidParameters } }));
|
|
172
244
|
};
|
|
173
245
|
function CustomUrlEditorDialog({ urlDrillTarget, documentationLink, onSelect, onClose, attributeDisplayForms, loadingAttributeDisplayForms = false, invalidAttributeDisplayFormIdentifiers, enableClientIdParameter, enableDataProductIdParameter, enableWidgetIdParameter, widgetRef, }) {
|
|
174
246
|
const intl = useIntl();
|
|
247
|
+
const enableInsightMeasureValueFilters = useDashboardSelector(selectEnableMeasureValueFilterKD);
|
|
175
248
|
const insightFilters = useSanitizedInsightFilters(widgetRef);
|
|
249
|
+
const insightMeasureValueFilters = useInsightMeasureValueFilters(widgetRef, enableInsightMeasureValueFilters);
|
|
176
250
|
const dashboardFilters = useSanitizedDashboardFilters();
|
|
251
|
+
const dashboardMeasureValueFilters = useDashboardSelector(selectFilterContextMeasureValueFilters);
|
|
177
252
|
const attributeFilterConfigs = useDashboardSelector(selectAttributeFilterConfigsOverrides);
|
|
178
|
-
const invalidFilteringParametersIdentifiers = useInvalidFilteringParametersIdentifiers(urlDrillTarget, insightFilters, dashboardFilters, attributeFilterConfigs);
|
|
253
|
+
const invalidFilteringParametersIdentifiers = useInvalidFilteringParametersIdentifiers(urlDrillTarget, insightFilters, dashboardFilters, dashboardMeasureValueFilters, enableInsightMeasureValueFilters ? insightMeasureValueFilters : undefined, enableInsightMeasureValueFilters, attributeFilterConfigs);
|
|
179
254
|
const invalidParameters = useMemo(() => {
|
|
180
255
|
return [...invalidAttributeDisplayFormIdentifiers, ...invalidFilteringParametersIdentifiers];
|
|
181
256
|
}, [invalidAttributeDisplayFormIdentifiers, invalidFilteringParametersIdentifiers]);
|
|
@@ -183,7 +258,7 @@ function CustomUrlEditorDialog({ urlDrillTarget, documentationLink, onSelect, on
|
|
|
183
258
|
? (isDrillToCustomUrlConfig(urlDrillTarget) && urlDrillTarget.customUrl) || ""
|
|
184
259
|
: "";
|
|
185
260
|
const [currentValue, setCurrentValue] = useState(previousValue);
|
|
186
|
-
const apply = () => onSelect(assertValidUrl(currentValue));
|
|
261
|
+
const apply = () => onSelect(assertValidUrl(currentValue, enableInsightMeasureValueFilters));
|
|
187
262
|
const handleOnChange = (value) => setCurrentValue(value);
|
|
188
263
|
const isApplyEnabled = currentValue && currentValue.localeCompare(previousValue) !== 0;
|
|
189
264
|
const [cursorPosition, setCursorPosition] = useState(initialCursorPosition);
|
|
@@ -197,7 +272,7 @@ function CustomUrlEditorDialog({ urlDrillTarget, documentationLink, onSelect, on
|
|
|
197
272
|
}), submitButtonText: intl.formatMessage({
|
|
198
273
|
id: "configurationPanel.drillIntoUrl.editor.applyButtonLabel",
|
|
199
274
|
}), isSubmitDisabled: !isApplyEnabled, submitOnEnterKey: false, onCancel: onClose, onSubmit: apply, warning: editorWarningText, children: [
|
|
200
|
-
_jsx(UrlInputPanel, { onChange: handleOnChange, onCursor: handleCursorPosition, documentationLink: documentationLink, currentUrlValue: currentValue, attributeDisplayForms: attributeDisplayForms, insightFilters: insightFilters, dashboardFilters: dashboardFilters, attributeFilterConfigs: attributeFilterConfigs, intl: intl }), _jsx(ParametersPanel, { insightFilters: insightFilters, dashboardFilters: dashboardFilters, attributeFilterConfigs: attributeFilterConfigs, attributeDisplayForms: attributeDisplayForms, loadingAttributeDisplayForms: loadingAttributeDisplayForms, enableClientIdParameter: enableClientIdParameter, enableDataProductIdParameter: enableDataProductIdParameter, enableWidgetIdParameter: enableWidgetIdParameter, onAdd: handleOnAdd, intl: intl, widgetRef: widgetRef })
|
|
275
|
+
_jsx(UrlInputPanel, { onChange: handleOnChange, onCursor: handleCursorPosition, documentationLink: documentationLink, currentUrlValue: currentValue, attributeDisplayForms: attributeDisplayForms, insightFilters: insightFilters, dashboardFilters: dashboardFilters, dashboardMeasureValueFilters: dashboardMeasureValueFilters, insightMeasureValueFilters: insightMeasureValueFilters, enableInsightMeasureValueFilters: enableInsightMeasureValueFilters, attributeFilterConfigs: attributeFilterConfigs, intl: intl }), _jsx(ParametersPanel, { insightFilters: insightFilters, dashboardFilters: dashboardFilters, dashboardMeasureValueFilters: dashboardMeasureValueFilters, insightMeasureValueFilters: insightMeasureValueFilters, attributeFilterConfigs: attributeFilterConfigs, attributeDisplayForms: attributeDisplayForms, loadingAttributeDisplayForms: loadingAttributeDisplayForms, enableClientIdParameter: enableClientIdParameter, enableDataProductIdParameter: enableDataProductIdParameter, enableWidgetIdParameter: enableWidgetIdParameter, onAdd: handleOnAdd, intl: intl, widgetRef: widgetRef })
|
|
201
276
|
] }));
|
|
202
277
|
}
|
|
203
278
|
const overlayController = OverlayController.getInstance(DASHBOARD_HEADER_OVERLAYS_Z_INDEX);
|
|
@@ -206,6 +281,15 @@ export function CustomUrlEditor(props) {
|
|
|
206
281
|
const SelectedOverlay = isMobileDevice ? FullScreenOverlay : Overlay;
|
|
207
282
|
return (_jsx(OverlayControllerProvider, { overlayController: overlayController, children: _jsx(SelectedOverlay, { onClose: props.onClose, isModal: true, closeOnOutsideClick: false, closeOnEscape: true, positionType: "fixed", className: "gd-modal-overlay", children: _jsx(CustomUrlEditorDialog, { ...props }) }) }));
|
|
208
283
|
}
|
|
284
|
+
function useInsightMeasureValueFilters(widgetRef, enabled) {
|
|
285
|
+
const insight = useDashboardSelector(selectInsightByWidgetRef(widgetRef));
|
|
286
|
+
return useMemo(() => {
|
|
287
|
+
if (!enabled || !insight) {
|
|
288
|
+
return [];
|
|
289
|
+
}
|
|
290
|
+
return insightDefinitionFilters(insight).filter(isMeasureValueFilter);
|
|
291
|
+
}, [enabled, insight]);
|
|
292
|
+
}
|
|
209
293
|
function useSanitizedInsightFilters(widgetRef) {
|
|
210
294
|
const widget = useDashboardSelector(selectFilterableWidgetByRef(widgetRef));
|
|
211
295
|
const widgetFiltersResult = useWidgetFilters(widget);
|
|
@@ -2,5 +2,5 @@ import { type IDashboardParametersSectionProps } from "./CustomUrlEditorParamete
|
|
|
2
2
|
import { type IInsightParametersSectionProps } from "./CustomUrlEditorParametersSections/InsightParametersSection.js";
|
|
3
3
|
import { type IIdentifierParametersSectionProps } from "./types.js";
|
|
4
4
|
type IParametersPanelProps = IInsightParametersSectionProps & IIdentifierParametersSectionProps & IDashboardParametersSectionProps;
|
|
5
|
-
export declare function ParametersPanel({ attributeDisplayForms, loadingAttributeDisplayForms, enableClientIdParameter, enableDataProductIdParameter, enableWidgetIdParameter, onAdd, intl, dashboardFilters, attributeFilterConfigs, insightFilters, widgetRef }: IParametersPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
export declare function ParametersPanel({ attributeDisplayForms, loadingAttributeDisplayForms, enableClientIdParameter, enableDataProductIdParameter, enableWidgetIdParameter, onAdd, intl, dashboardFilters, dashboardMeasureValueFilters, insightMeasureValueFilters, attributeFilterConfigs, insightFilters, widgetRef }: IParametersPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
6
6
|
export {};
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
// (C) 2020-
|
|
2
|
+
// (C) 2020-2026 GoodData Corporation
|
|
3
3
|
import { FormattedMessage } from "react-intl";
|
|
4
4
|
import { Bubble, BubbleHoverTrigger } from "@gooddata/sdk-ui-kit";
|
|
5
5
|
import { DashboardParametersSection, } from "./CustomUrlEditorParametersSections/DashboardParametersSection.js";
|
|
6
6
|
import { IdentifierParametersSection } from "./CustomUrlEditorParametersSections/IdentifierParametersSection.js";
|
|
7
7
|
import { InsightParametersSection, } from "./CustomUrlEditorParametersSections/InsightParametersSection.js";
|
|
8
|
-
export function ParametersPanel({ attributeDisplayForms, loadingAttributeDisplayForms, enableClientIdParameter, enableDataProductIdParameter, enableWidgetIdParameter, onAdd, intl, dashboardFilters, attributeFilterConfigs, insightFilters, widgetRef, }) {
|
|
8
|
+
export function ParametersPanel({ attributeDisplayForms, loadingAttributeDisplayForms, enableClientIdParameter, enableDataProductIdParameter, enableWidgetIdParameter, onAdd, intl, dashboardFilters, dashboardMeasureValueFilters, insightMeasureValueFilters, attributeFilterConfigs, insightFilters, widgetRef, }) {
|
|
9
9
|
return (_jsxs("div", { children: [
|
|
10
10
|
_jsxs("label", { className: "gd-label", children: [
|
|
11
11
|
_jsx(FormattedMessage, { id: "configurationPanel.drillIntoUrl.editor.parametersPanelLabel" }), _jsxs(BubbleHoverTrigger, { className: "gd-list-item-tooltip", showDelay: 0, hideDelay: 0, children: [
|
|
12
12
|
_jsx("span", { className: "gd-icon-circle-question gd-list-item-tooltip-icon" }), _jsx(Bubble, { className: "bubble-primary", alignPoints: [{ align: "cr cl" }], children: _jsx(FormattedMessage, { id: "configurationPanel.drillIntoUrl.editor.parametersPanelTooltip" }) })
|
|
13
13
|
] })
|
|
14
14
|
] }), _jsxs("div", { className: "gd-drill-to-url-parameters gd-drill-to-url-list", children: [
|
|
15
|
-
_jsx(InsightParametersSection, { attributeDisplayForms: attributeDisplayForms, loadingAttributeDisplayForms: loadingAttributeDisplayForms, onAdd: onAdd, intl: intl, insightFilters: insightFilters }), _jsx(DashboardParametersSection, { intl: intl, onAdd: onAdd, dashboardFilters: dashboardFilters, attributeFilterConfigs: attributeFilterConfigs }), _jsx(IdentifierParametersSection, { enableClientIdParameter: enableClientIdParameter, enableDataProductIdParameter: enableDataProductIdParameter, enableWidgetIdParameter: enableWidgetIdParameter, onAdd: onAdd, intl: intl, widgetRef: widgetRef })
|
|
15
|
+
_jsx(InsightParametersSection, { attributeDisplayForms: attributeDisplayForms, loadingAttributeDisplayForms: loadingAttributeDisplayForms, onAdd: onAdd, intl: intl, insightFilters: insightFilters, insightMeasureValueFilters: insightMeasureValueFilters, widgetRef: widgetRef }), _jsx(DashboardParametersSection, { intl: intl, onAdd: onAdd, dashboardFilters: dashboardFilters, dashboardMeasureValueFilters: dashboardMeasureValueFilters, attributeFilterConfigs: attributeFilterConfigs }), _jsx(IdentifierParametersSection, { enableClientIdParameter: enableClientIdParameter, enableDataProductIdParameter: enableDataProductIdParameter, enableWidgetIdParameter: enableWidgetIdParameter, onAdd: onAdd, intl: intl, widgetRef: widgetRef })
|
|
16
16
|
] })
|
|
17
17
|
] }));
|
|
18
18
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { type IAttributeFilter, type IDashboardAttributeFilterConfig } from "@gooddata/sdk-model";
|
|
1
|
+
import { type IAttributeFilter, type IDashboardAttributeFilterConfig, type IDashboardMeasureValueFilter } from "@gooddata/sdk-model";
|
|
2
2
|
import { type IParametersPanelSectionsCommonProps } from "../types.js";
|
|
3
3
|
export interface IDashboardParametersSectionProps extends IParametersPanelSectionsCommonProps {
|
|
4
4
|
dashboardFilters?: IAttributeFilter[];
|
|
5
|
+
dashboardMeasureValueFilters?: IDashboardMeasureValueFilter[];
|
|
5
6
|
attributeFilterConfigs?: IDashboardAttributeFilterConfig[];
|
|
6
7
|
}
|
|
7
|
-
export declare function DashboardParametersSection({ dashboardFilters, attributeFilterConfigs, onAdd }: IDashboardParametersSectionProps): import("react/jsx-runtime").JSX.Element | null;
|
|
8
|
+
export declare function DashboardParametersSection({ dashboardFilters, dashboardMeasureValueFilters, attributeFilterConfigs, intl, onAdd }: IDashboardParametersSectionProps): import("react/jsx-runtime").JSX.Element | null;
|