@gooddata/sdk-ui-dashboard 11.51.0-alpha.0 → 11.51.0-alpha.2
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 +4 -4
- package/esm/__version.d.ts +1 -1
- package/esm/__version.js +1 -1
- package/esm/index.d.ts +6 -1
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +6 -1
- package/esm/model/store/meta/index.d.ts +1 -0
- package/esm/model/store/meta/index.d.ts.map +1 -1
- package/esm/model/store/meta/metaReducers.d.ts +5 -1
- package/esm/model/store/meta/metaReducers.d.ts.map +1 -1
- package/esm/model/store/meta/metaReducers.js +9 -0
- package/esm/model/store/meta/metaSelectors.d.ts +23 -1
- package/esm/model/store/meta/metaSelectors.d.ts.map +1 -1
- package/esm/model/store/meta/metaSelectors.js +33 -2
- package/esm/model/store/meta/metaState.d.ts +1 -1
- package/esm/model/store/meta/metaState.d.ts.map +1 -1
- package/esm/presentation/automations/alerting/DefaultAlertingDialog/DefaultAlertingDialog.d.ts +1 -1
- package/esm/presentation/automations/alerting/DefaultAlertingDialog/DefaultAlertingDialog.d.ts.map +1 -1
- package/esm/presentation/automations/alerting/DefaultAlertingDialog/DefaultAlertingDialog.js +9 -9
- package/esm/presentation/automations/alerting/DefaultAlertingDialog/DefaultLoadingAlertingDialog.d.ts +7 -2
- package/esm/presentation/automations/alerting/DefaultAlertingDialog/DefaultLoadingAlertingDialog.d.ts.map +1 -1
- package/esm/presentation/automations/alerting/DefaultAlertingDialog/DefaultLoadingAlertingDialog.js +1 -1
- package/esm/presentation/automations/alerting/DefaultAlertingDialog/hooks/useEditAlert.d.ts +6 -8
- package/esm/presentation/automations/alerting/DefaultAlertingDialog/hooks/useEditAlert.d.ts.map +1 -1
- package/esm/presentation/automations/alerting/DefaultAlertingDialog/hooks/useEditAlert.js +5 -2
- package/esm/presentation/automations/alerting/types.d.ts +30 -5
- package/esm/presentation/automations/alerting/types.d.ts.map +1 -1
- package/esm/presentation/automations/connectors/AlertingConnector.d.ts.map +1 -1
- package/esm/presentation/automations/connectors/AlertingConnector.js +22 -25
- package/esm/presentation/automations/connectors/AlertingConnector.test.js +71 -5
- package/esm/presentation/automations/connectors/hooks/useBuildAlertingDialogContext.d.ts +7 -1
- package/esm/presentation/automations/connectors/hooks/useBuildAlertingDialogContext.d.ts.map +1 -1
- package/esm/presentation/automations/connectors/hooks/useBuildAlertingDialogContext.js +12 -2
- package/esm/presentation/automations/connectors/hooks/useBuildAlertingDialogContext.test.js +28 -2
- package/esm/presentation/automations/contexts/AlertingDialogContext.d.ts +29 -1
- package/esm/presentation/automations/contexts/AlertingDialogContext.d.ts.map +1 -1
- package/esm/presentation/automations/contexts/AlertingDialogContext.js +12 -0
- package/esm/presentation/automations/contexts/AlertingManagementDialogContext.d.ts +14 -0
- package/esm/presentation/automations/contexts/AlertingManagementDialogContext.d.ts.map +1 -1
- package/esm/presentation/automations/contexts/AlertingManagementDialogContext.js +12 -0
- package/esm/presentation/automations/contexts/AutomationsContext.d.ts +13 -0
- package/esm/presentation/automations/contexts/AutomationsContext.d.ts.map +1 -1
- package/esm/presentation/automations/contexts/AutomationsContext.js +9 -0
- package/esm/presentation/automations/contexts/ScheduledEmailDialogContext.d.ts +15 -0
- package/esm/presentation/automations/contexts/ScheduledEmailDialogContext.d.ts.map +1 -1
- package/esm/presentation/automations/contexts/ScheduledEmailDialogContext.js +13 -0
- package/esm/presentation/automations/contexts/ScheduledEmailManagementDialogContext.d.ts +13 -1
- package/esm/presentation/automations/contexts/ScheduledEmailManagementDialogContext.d.ts.map +1 -1
- package/esm/presentation/automations/contexts/ScheduledEmailManagementDialogContext.js +12 -0
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/DefaultScheduledEmailDialog.d.ts.map +1 -1
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/DefaultScheduledEmailDialog.js +11 -16
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/Attachments/DashboardAttachments.d.ts.map +1 -1
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/Attachments/DashboardAttachments.js +7 -3
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/Attachments/WidgetAttachments.d.ts +2 -1
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/Attachments/WidgetAttachments.d.ts.map +1 -1
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/Attachments/WidgetAttachments.js +12 -4
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/Attachments/attachmentFormats.d.ts +17 -7
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/Attachments/attachmentFormats.d.ts.map +1 -1
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/components/Attachments/attachmentFormats.js +18 -8
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useElementHeightSnapshot.d.ts +12 -0
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useElementHeightSnapshot.d.ts.map +1 -0
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useElementHeightSnapshot.js +41 -0
- package/esm/presentation/automations/scheduledEmail/utils/timezone.d.ts +4 -1
- package/esm/presentation/automations/scheduledEmail/utils/timezone.d.ts.map +1 -1
- package/esm/presentation/automations/scheduledEmail/utils/timezone.js +14 -138
- package/esm/presentation/dashboard/DashboardHeader/SettingsDialogProvider.d.ts.map +1 -1
- package/esm/presentation/dashboard/DashboardHeader/SettingsDialogProvider.js +1 -0
- package/esm/presentation/dashboardSettingsDialog/DefaultDashboardSettingsDialog.d.ts.map +1 -1
- package/esm/presentation/dashboardSettingsDialog/DefaultDashboardSettingsDialog.js +52 -14
- package/esm/presentation/dashboardSettingsDialog/TimezoneOption.d.ts +11 -0
- package/esm/presentation/dashboardSettingsDialog/TimezoneOption.d.ts.map +1 -0
- package/esm/presentation/dashboardSettingsDialog/TimezoneOption.js +36 -0
- package/esm/presentation/dashboardSettingsDialog/types.d.ts +2 -1
- package/esm/presentation/dashboardSettingsDialog/types.d.ts.map +1 -1
- package/esm/presentation/dashboardSettingsDialog/useDialogData.d.ts.map +1 -1
- package/esm/presentation/dashboardSettingsDialog/useDialogData.js +4 -1
- package/esm/presentation/filterBar/dateFilter/DefaultDashboardDateFilter.d.ts.map +1 -1
- package/esm/presentation/filterBar/dateFilter/DefaultDashboardDateFilter.js +30 -1
- package/esm/presentation/localization/bundles/en-US.localization-bundle.d.ts +44 -0
- package/esm/presentation/localization/bundles/en-US.localization-bundle.d.ts.map +1 -1
- package/esm/presentation/localization/bundles/en-US.localization-bundle.js +44 -0
- package/esm/presentation/widget/insight/ViewModeDashboardInsight/InsightDrillDialog/InsightDrillDialog.d.ts.map +1 -1
- package/esm/presentation/widget/insight/ViewModeDashboardInsight/InsightDrillDialog/InsightDrillDialog.js +2 -1
- package/esm/sdk-ui-dashboard.d.ts +370 -6
- package/package.json +21 -21
- package/styles/css/dashboard.css +7 -0
- package/styles/css/dashboard.css.map +1 -1
- package/styles/css/main.css +7 -0
- package/styles/css/main.css.map +1 -1
- package/styles/scss/dashboard.scss +12 -0
package/esm/presentation/automations/alerting/DefaultAlertingDialog/DefaultAlertingDialog.js
CHANGED
|
@@ -37,11 +37,15 @@ import { isMobileView } from "./utils/responsive.js";
|
|
|
37
37
|
const OVERLAY_POSITION_TYPE = "sameAsTarget";
|
|
38
38
|
const CLOSE_ON_PARENT_SCROLL = true;
|
|
39
39
|
const overlayController = OverlayController.getInstance(DASHBOARD_DIALOG_OVERS_Z_INDEX);
|
|
40
|
-
export function AlertingDialogRenderer({
|
|
40
|
+
export function AlertingDialogRenderer({ onCancel, onDeleteSuccess, onDeleteError, onError, onSuccess, onSaveError, onSaveSuccess, }) {
|
|
41
41
|
const intl = useIntl();
|
|
42
42
|
const dialogTitleRef = useRef(null);
|
|
43
43
|
const { isWhiteLabeled, isSecondaryTitleVisible, externalRecipient: externalRecipientOverride, maxAutomationsRecipients, isExecutionTimestampMode, features: { enableAlertOncePerInterval, enableAnomalyDetectionAlert, canUseAiAssistant: enableAiAssistant, }, } = useAutomationsContext();
|
|
44
|
-
|
|
44
|
+
// Read from context because this component calls useAutomationFiltersSelect and
|
|
45
|
+
// useValidateExistingAutomationFilters directly, and the filter-select call must run before
|
|
46
|
+
// useEditAlert, which consumes its output. Removed with the filter read-model consolidation
|
|
47
|
+
// (EB-867), which retires these call sites.
|
|
48
|
+
const { widgetTitle, alertToEdit, widget, insight } = useAlertingDialogContext();
|
|
45
49
|
const [alertToDelete, setAlertToDelete] = useState(null);
|
|
46
50
|
const handleAlertDeleteSuccess = (alert) => {
|
|
47
51
|
onDeleteSuccess?.(alert);
|
|
@@ -51,16 +55,11 @@ export function AlertingDialogRenderer({ alertToEdit, users, usersError, notific
|
|
|
51
55
|
automationToEdit: alertToEdit,
|
|
52
56
|
widget,
|
|
53
57
|
});
|
|
54
|
-
const { onTitleChange, onRecipientsChange, onFiltersChange, onApplyCurrentFilters, dropStaleParameters, automationParameters, availableParameters, onParameterChange, onParameterDelete, onParameterAdd, onMeasureChange, getAttributeValues, onAttributeChange, onComparisonOperatorChange, onRelativeOperatorChange, onAnomalyDetectionChange, onChange, onBlur, onComparisonTypeChange, onDestinationChange, onTriggerModeChange, onTriggerIntervalChange, selectedMeasure, canChangeMeasure, supportedMeasures, selectedAttribute, selectedValue, supportedAttributes, catalogAttributes, catalogDateDatasets, isResultLoading, selectedComparisonOperator, selectedRelativeOperator, selectedAiOperator, value, selectedComparator, selectedSensitivity, onSensitivityChange, selectedGranularity, onGranularityChange, separators, defaultUser, originalAutomation, editedAutomation, allowOnlyLoggedUserRecipients, allowExternalRecipients, warningMessage, validationErrorMessage, isInvalidConnectionToInsight, isSubmitDisabled, isParentValid, thresholdErrorMessage, allowHourlyRecurrence, } = useEditAlert({
|
|
55
|
-
insight,
|
|
56
|
-
widget,
|
|
57
|
-
alertToEdit,
|
|
58
|
-
users,
|
|
58
|
+
const { onTitleChange, onRecipientsChange, onFiltersChange, onApplyCurrentFilters, dropStaleParameters, automationParameters, availableParameters, onParameterChange, onParameterDelete, onParameterAdd, onMeasureChange, getAttributeValues, onAttributeChange, onComparisonOperatorChange, onRelativeOperatorChange, onAnomalyDetectionChange, onChange, onBlur, onComparisonTypeChange, onDestinationChange, onTriggerModeChange, onTriggerIntervalChange, selectedMeasure, canChangeMeasure, supportedMeasures, selectedAttribute, selectedValue, supportedAttributes, catalogAttributes, catalogDateDatasets, isResultLoading, selectedComparisonOperator, selectedRelativeOperator, selectedAiOperator, value, selectedComparator, selectedSensitivity, onSensitivityChange, selectedGranularity, onGranularityChange, separators, defaultUser, originalAutomation, editedAutomation, allowOnlyLoggedUserRecipients, allowExternalRecipients, warningMessage, validationErrorMessage, isInvalidConnectionToInsight, isSubmitDisabled, isParentValid, thresholdErrorMessage, allowHourlyRecurrence, users, usersError, notificationChannels, } = useEditAlert({
|
|
59
59
|
editedAutomationFilters,
|
|
60
60
|
maxAutomationsRecipients,
|
|
61
61
|
availableFiltersAsVisibleFilters,
|
|
62
62
|
setEditedAutomationFilters,
|
|
63
|
-
notificationChannels,
|
|
64
63
|
filtersForNewAutomation,
|
|
65
64
|
externalRecipientOverride,
|
|
66
65
|
});
|
|
@@ -176,8 +175,9 @@ export function AlertingDialogRenderer({ alertToEdit, users, usersError, notific
|
|
|
176
175
|
* @alpha
|
|
177
176
|
*/
|
|
178
177
|
export function DefaultAlertingDialog(props) {
|
|
179
|
-
const {
|
|
178
|
+
const { onCancel } = props;
|
|
180
179
|
const { locale } = useAutomationsContext();
|
|
180
|
+
const { isLoading, alertToEdit } = useAlertingDialogContext();
|
|
181
181
|
if (isLoading) {
|
|
182
182
|
return _jsx(DefaultLoadingAlertingDialog, { onCancel: onCancel, alertToEdit: alertToEdit });
|
|
183
183
|
}
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
|
|
1
|
+
import { type IAutomationMetadataObject } from "@gooddata/sdk-model";
|
|
2
|
+
interface IDefaultLoadingAlertingDialogProps {
|
|
3
|
+
alertToEdit?: IAutomationMetadataObject;
|
|
4
|
+
onCancel?: () => void;
|
|
5
|
+
}
|
|
6
|
+
export declare function DefaultLoadingAlertingDialog({ alertToEdit, onCancel }: IDefaultLoadingAlertingDialogProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export {};
|
|
3
8
|
//# sourceMappingURL=DefaultLoadingAlertingDialog.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DefaultLoadingAlertingDialog.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/automations/alerting/DefaultAlertingDialog/DefaultLoadingAlertingDialog.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"DefaultLoadingAlertingDialog.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/automations/alerting/DefaultAlertingDialog/DefaultLoadingAlertingDialog.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAarE,UAAU,kCAAkC;IACxC,WAAW,CAAC,EAAE,yBAAyB,CAAC;IACxC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACzB;AAED,wBAAgB,4BAA4B,CAAC,EAAE,WAAW,EAAE,QAAQ,EAAE,EAAE,kCAAkC,2CAkDzG"}
|
package/esm/presentation/automations/alerting/DefaultAlertingDialog/DefaultLoadingAlertingDialog.js
CHANGED
|
@@ -4,7 +4,7 @@ import { useIntl } from "react-intl";
|
|
|
4
4
|
import { ConfirmDialogBase, Overlay, OverlayController, OverlayControllerProvider, UiSkeleton, useId, } from "@gooddata/sdk-ui-kit";
|
|
5
5
|
import { DASHBOARD_DIALOG_OVERS_Z_INDEX } from "../../../constants/zIndex.js";
|
|
6
6
|
const overlayController = OverlayController.getInstance(DASHBOARD_DIALOG_OVERS_Z_INDEX);
|
|
7
|
-
export function DefaultLoadingAlertingDialog({ alertToEdit, onCancel
|
|
7
|
+
export function DefaultLoadingAlertingDialog({ alertToEdit, onCancel }) {
|
|
8
8
|
const intl = useIntl();
|
|
9
9
|
const titleElementId = useId();
|
|
10
10
|
return (_jsx(_Fragment, { children: _jsx(Overlay, { className: "gd-notifications-channels-dialog-overlay", isModal: true, positionType: "fixed", children: _jsx(OverlayControllerProvider, { overlayController: overlayController, children: _jsxs(ConfirmDialogBase, { className: "gd-notifications-channels-dialog s-gd-notifications-channels-dialog", isPositive: true, cancelButtonText: intl.formatMessage({ id: "cancel" }), submitButtonText: alertToEdit
|
|
@@ -1,18 +1,13 @@
|
|
|
1
|
-
import { type FilterContextItem, type
|
|
1
|
+
import { type FilterContextItem, type IAutomationVisibleFilter } from "@gooddata/sdk-model";
|
|
2
2
|
export interface IUseEditAlertProps {
|
|
3
|
-
alertToEdit?: IAutomationMetadataObject;
|
|
4
|
-
notificationChannels: INotificationChannelIdentifier[] | INotificationChannelMetadataObject[];
|
|
5
3
|
maxAutomationsRecipients: number;
|
|
6
|
-
users: IWorkspaceUser[];
|
|
7
|
-
widget?: IWidget;
|
|
8
|
-
insight?: IInsight;
|
|
9
4
|
editedAutomationFilters?: FilterContextItem[];
|
|
10
5
|
setEditedAutomationFilters: (filters: FilterContextItem[]) => void;
|
|
11
6
|
availableFiltersAsVisibleFilters?: IAutomationVisibleFilter[] | undefined;
|
|
12
7
|
filtersForNewAutomation: FilterContextItem[];
|
|
13
8
|
externalRecipientOverride?: string;
|
|
14
9
|
}
|
|
15
|
-
export declare function useEditAlert({
|
|
10
|
+
export declare function useEditAlert({ editedAutomationFilters, maxAutomationsRecipients, setEditedAutomationFilters, availableFiltersAsVisibleFilters, filtersForNewAutomation, externalRecipientOverride }: IUseEditAlertProps): {
|
|
16
11
|
onTitleChange: (value: string, isValid: boolean) => void;
|
|
17
12
|
onRecipientsChange: (updatedRecipients: import("@gooddata/sdk-model").IAutomationRecipient[]) => void;
|
|
18
13
|
onFiltersChange: (filters: FilterContextItem[]) => void;
|
|
@@ -60,9 +55,12 @@ export declare function useEditAlert({ alertToEdit, notificationChannels, insigh
|
|
|
60
55
|
selectedComparator: import("../../types.js").AlertMetricComparator | undefined;
|
|
61
56
|
separators: import("@gooddata/sdk-model").ISeparators;
|
|
62
57
|
warningMessage: string | undefined;
|
|
63
|
-
defaultUser: IWorkspaceUser;
|
|
58
|
+
defaultUser: import("@gooddata/sdk-model").IWorkspaceUser;
|
|
64
59
|
originalAutomation: import("@gooddata/sdk-model").IAutomationMetadataObjectDefinition | undefined;
|
|
65
60
|
editedAutomation: import("@gooddata/sdk-model").IAutomationMetadataObjectDefinition | undefined;
|
|
61
|
+
users: import("@gooddata/sdk-model").IWorkspaceUser[];
|
|
62
|
+
usersError: import("@gooddata/sdk-ui").GoodDataSdkError | undefined;
|
|
63
|
+
notificationChannels: import("@gooddata/sdk-model").INotificationChannelIdentifier[] | import("@gooddata/sdk-model").INotificationChannelMetadataObject[];
|
|
66
64
|
allowOnlyLoggedUserRecipients: boolean;
|
|
67
65
|
allowExternalRecipients: boolean;
|
|
68
66
|
validationErrorMessage: string | undefined;
|
package/esm/presentation/automations/alerting/DefaultAlertingDialog/hooks/useEditAlert.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useEditAlert.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/automations/alerting/DefaultAlertingDialog/hooks/useEditAlert.ts"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"useEditAlert.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/automations/alerting/DefaultAlertingDialog/hooks/useEditAlert.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAY5F,MAAM,WAAW,kBAAkB;IAC/B,wBAAwB,EAAE,MAAM,CAAC;IACjC,uBAAuB,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAE9C,0BAA0B,EAAE,CAAC,OAAO,EAAE,iBAAiB,EAAE,KAAK,IAAI,CAAC;IACnE,gCAAgC,CAAC,EAAE,wBAAwB,EAAE,GAAG,SAAS,CAAC;IAC1E,uBAAuB,EAAE,iBAAiB,EAAE,CAAC;IAC7C,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACtC;AAED,wBAAgB,YAAY,CAAC,EACzB,uBAAuB,EACvB,wBAAwB,EACxB,0BAA0B,EAC1B,gCAAgC,EAChC,uBAAuB,EACvB,yBAAyB,EAC5B,EAAE,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkMpB"}
|
|
@@ -7,10 +7,10 @@ import { useAlertFormValidation } from "./useAlertFormValidation.js";
|
|
|
7
7
|
import { useAlertSelectedValues } from "./useAlertSelectedValues.js";
|
|
8
8
|
import { useAlertSupportedMetrics } from "./useAlertSupportedMetrics.js";
|
|
9
9
|
import { useAlertThreshold } from "./useAlertThreshold.js";
|
|
10
|
-
export function useEditAlert({
|
|
10
|
+
export function useEditAlert({ editedAutomationFilters, maxAutomationsRecipients, setEditedAutomationFilters, availableFiltersAsVisibleFilters, filtersForNewAutomation, externalRecipientOverride, }) {
|
|
11
11
|
const { catalogDateDatasets, catalogAttributes, separators, weekStart, timezone, allowHourlyRecurrence } = useAutomationsContext();
|
|
12
|
+
const { hiddenFilters: dashboardHiddenFilters, commonDateFilterId, alertToEdit, users, usersError, notificationChannels, widget, insight, } = useAlertingDialogContext();
|
|
12
13
|
const isInvalidConnectionToInsight = alertToEdit?.metadata?.widget && !insight;
|
|
13
|
-
const { hiddenFilters: dashboardHiddenFilters, commonDateFilterId } = useAlertingDialogContext();
|
|
14
14
|
const { measureFormatMap, supportedMeasures, supportedAttributes, isResultLoading, getAttributeValues, getMetricValue, } = useAlertSupportedMetrics({ insight, widget, alertToEdit });
|
|
15
15
|
const { editedAutomation, setEditedAutomation, originalAutomation, defaultUser, defaultRecipient, automationParameters, availableParameters, onParameterChange, onParameterDelete, onParameterAdd, dropStaleParameters, onTitleChange, onMeasureChange, onAttributeChange, onComparisonOperatorChange, onRelativeOperatorChange, onAnomalyDetectionChange, onComparisonTypeChange, onSensitivityChange, onTriggerIntervalChange, onGranularityChange, onDestinationChange, onTriggerModeChange, onRecipientsChange, warningMessage, isTitleValid, } = useAlertFormState({
|
|
16
16
|
alertToEdit,
|
|
@@ -124,6 +124,9 @@ export function useEditAlert({ alertToEdit, notificationChannels, insight, widge
|
|
|
124
124
|
defaultUser,
|
|
125
125
|
originalAutomation,
|
|
126
126
|
editedAutomation,
|
|
127
|
+
users,
|
|
128
|
+
usersError,
|
|
129
|
+
notificationChannels,
|
|
127
130
|
allowOnlyLoggedUserRecipients,
|
|
128
131
|
allowExternalRecipients,
|
|
129
132
|
validationErrorMessage,
|
|
@@ -7,20 +7,29 @@ import { type GoodDataSdkError } from "@gooddata/sdk-ui";
|
|
|
7
7
|
export interface IAlertingDialogProps {
|
|
8
8
|
/**
|
|
9
9
|
* In case, we are not creating new alert, but editing existing one, this is the active alert to be edited.
|
|
10
|
+
*
|
|
11
|
+
* @deprecated read `alertToEdit` from `useAlertingDialogContext()` instead. Prop will be removed.
|
|
10
12
|
*/
|
|
11
13
|
alertToEdit?: IAutomationMetadataObject;
|
|
12
14
|
/**
|
|
13
15
|
* Users in workspace
|
|
16
|
+
*
|
|
17
|
+
* @deprecated read `users` from `useAlertingDialogContext()` instead. Prop will be removed.
|
|
14
18
|
*/
|
|
15
|
-
users
|
|
19
|
+
users?: IWorkspaceUser[];
|
|
16
20
|
/**
|
|
17
21
|
* Error occurred while loading users
|
|
22
|
+
*
|
|
23
|
+
* @deprecated read `usersError` from `useAlertingDialogContext()` instead. Prop will be removed.
|
|
18
24
|
*/
|
|
19
25
|
usersError?: GoodDataSdkError;
|
|
20
26
|
/**
|
|
21
27
|
* Notification channels in organization
|
|
28
|
+
*
|
|
29
|
+
* @deprecated read `notificationChannels` from `useAlertingDialogContext()` instead.
|
|
30
|
+
* Prop will be removed.
|
|
22
31
|
*/
|
|
23
|
-
notificationChannels
|
|
32
|
+
notificationChannels?: INotificationChannelIdentifier[] | INotificationChannelMetadataObject[];
|
|
24
33
|
/**
|
|
25
34
|
* Widget to be used for alert.
|
|
26
35
|
*
|
|
@@ -28,16 +37,22 @@ export interface IAlertingDialogProps {
|
|
|
28
37
|
* Typed as IWidget (not ExtendedDashboardWidget) because the dialog only
|
|
29
38
|
* supports insight widgets; custom widgets and nested layouts are not valid
|
|
30
39
|
* alert targets and were silently discarded at the connector boundary anyway.
|
|
40
|
+
*
|
|
41
|
+
* @deprecated read `widget` from `useAlertingDialogContext()` instead. Prop will be removed.
|
|
31
42
|
*/
|
|
32
43
|
widget?: IWidget;
|
|
33
44
|
/**
|
|
34
45
|
* Insight to be used for alert.
|
|
35
46
|
*
|
|
36
47
|
* Note: this is available only when alerting for widget, not dashboard.
|
|
48
|
+
*
|
|
49
|
+
* @deprecated read `insight` from `useAlertingDialogContext()` instead. Prop will be removed.
|
|
37
50
|
*/
|
|
38
51
|
insight?: IInsight;
|
|
39
52
|
/**
|
|
40
53
|
* Is alert dialog loading initial data, before it can be rendered?
|
|
54
|
+
*
|
|
55
|
+
* @deprecated read `isLoading` from `useAlertingDialogContext()` instead. Prop will be removed.
|
|
41
56
|
*/
|
|
42
57
|
isLoading?: boolean;
|
|
43
58
|
/**
|
|
@@ -75,20 +90,30 @@ export interface IAlertingDialogProps {
|
|
|
75
90
|
export interface IAlertingManagementDialogProps {
|
|
76
91
|
/**
|
|
77
92
|
* Is loading alert data?
|
|
93
|
+
*
|
|
94
|
+
* @deprecated not read by the default dialog. Prop will be removed.
|
|
78
95
|
*/
|
|
79
|
-
isLoadingAlertingData
|
|
96
|
+
isLoadingAlertingData?: boolean;
|
|
80
97
|
/**
|
|
81
98
|
* Error occurred while loading alert data?
|
|
99
|
+
*
|
|
100
|
+
* @deprecated not read by the default dialog. Prop will be removed.
|
|
82
101
|
*/
|
|
83
102
|
alertDataError?: GoodDataSdkError;
|
|
84
103
|
/**
|
|
85
104
|
* Notification channels in organization
|
|
105
|
+
*
|
|
106
|
+
* @deprecated not read by the default dialog. A replacement can read the dashboard's
|
|
107
|
+
* notification channels directly. Prop will be removed.
|
|
86
108
|
*/
|
|
87
|
-
notificationChannels
|
|
109
|
+
notificationChannels?: INotificationChannelIdentifier[] | INotificationChannelMetadataObject[];
|
|
88
110
|
/**
|
|
89
111
|
* Automations in workspace
|
|
112
|
+
*
|
|
113
|
+
* @deprecated not read by the default dialog. A replacement can read the dashboard's
|
|
114
|
+
* automations directly. Prop will be removed.
|
|
90
115
|
*/
|
|
91
|
-
automations
|
|
116
|
+
automations?: IAutomationMetadataObject[];
|
|
92
117
|
/**
|
|
93
118
|
* Callback to be called, when user adds new alert item.
|
|
94
119
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/presentation/automations/alerting/types.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAE3C,OAAO,EACH,KAAK,wBAAwB,EAC7B,KAAK,UAAU,EACf,KAAK,yBAAyB,EAC9B,KAAK,sBAAsB,EAC3B,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,KAAK,8BAA8B,EACnC,KAAK,kCAAkC,EACvC,KAAK,OAAO,EACZ,KAAK,cAAc,EACtB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAMzD;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACjC
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/presentation/automations/alerting/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AlertingConnector.d.ts","sourceRoot":"","sources":["../../../../src/presentation/automations/connectors/AlertingConnector.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"AlertingConnector.d.ts","sourceRoot":"","sources":["../../../../src/presentation/automations/connectors/AlertingConnector.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AA8B1D;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,GAAG,YAAY,CAG/F;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,IAAI,YAAY,GAAG,IAAI,CAMvD"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { isWidget } from "@gooddata/sdk-model";
|
|
2
|
+
import { isWidget, } from "@gooddata/sdk-model";
|
|
3
3
|
import { useDashboardAlerts } from "../../../model/react/useDashboardAlerting/useDashboardAlerts.js";
|
|
4
4
|
import { useWorkspaceUsers } from "../../../model/react/useWorkspaceUsers.js";
|
|
5
5
|
import { AlertingDialog } from "../alerting/AlertingDialog.js";
|
|
@@ -11,6 +11,7 @@ import { useAutomationManagementEditRouting } from "./hooks/useAutomationManagem
|
|
|
11
11
|
import { useBuildAlertingDialogContext } from "./hooks/useBuildAlertingDialogContext.js";
|
|
12
12
|
import { useBuildAlertingManagementDialogContext } from "./hooks/useBuildAlertingManagementDialogContext.js";
|
|
13
13
|
import { useBuildAutomationsContext } from "./hooks/useBuildAutomationsContext.js";
|
|
14
|
+
const EMPTY_USERS = [];
|
|
14
15
|
/**
|
|
15
16
|
* Provides AutomationsContext to its children, built from dashboard Redux state.
|
|
16
17
|
* Wraps the alerting dialog subtree (both the create/edit and management dialogs reach
|
|
@@ -57,39 +58,35 @@ function AlertingConnectorWithData({ alerts }) {
|
|
|
57
58
|
// Shared Local State
|
|
58
59
|
alertToEdit,
|
|
59
60
|
// Data
|
|
60
|
-
|
|
61
|
+
automationsLoading, notificationChannels,
|
|
61
62
|
// Single Alert Dialog
|
|
62
63
|
isAlertDialogOpen, onAlertingCancel, onAlertingCreateSuccess, onAlertingCreateError, onAlertingSaveSuccess, onAlertingSaveError,
|
|
63
64
|
// Management / List Dialog
|
|
64
65
|
isAlertManagementDialogOpen, onAlertingManagementClose, onAlertingManagementAdd, onAlertingManagementEdit, onAlertingManagementDeleteSuccess, onAlertingManagementDeleteError, onAlertingManagementPauseSuccess, onAlertingManagementPauseError, widget, insight, } = alerts;
|
|
65
66
|
const handleManagementEdit = useAutomationManagementEditRouting(onAlertingManagementEdit);
|
|
66
67
|
const insightWidget = isWidget(widget) ? widget : undefined;
|
|
67
|
-
const alertingCtx = useBuildAlertingDialogContext({
|
|
68
|
-
mode: alertToEdit ? "edit" : "create",
|
|
69
|
-
widget: insightWidget,
|
|
70
|
-
insight,
|
|
71
|
-
});
|
|
72
68
|
const managementCtx = useBuildAlertingManagementDialogContext();
|
|
73
|
-
|
|
74
|
-
return (_jsx(AlertingDialogContextProvider, { value: alertingCtx, children: _jsxs(AlertingManagementDialogContextProvider, { value: managementCtx, children: [isAlertManagementDialogOpen ? (
|
|
75
|
-
// TODO(GDP-3167 phase3): automations, notificationChannels, and alertDataError
|
|
76
|
-
// are still prop-threaded here because DefaultAlertingManagementDialog reads
|
|
77
|
-
// them from props, not from AutomationsContext. Once all dialog fields are
|
|
78
|
-
// migrated to read from context, remove these props and the corresponding prop types.
|
|
79
|
-
_jsx(AlertingManagementDialog, { automations: automations, notificationChannels: notificationChannels, alertDataError: automationsError, isLoadingAlertingData: isManagementLoading, onAdd: onAlertingManagementAdd, onEdit: handleManagementEdit, onClose: onAlertingManagementClose, onDeleteSuccess: onAlertingManagementDeleteSuccess, onDeleteError: onAlertingManagementDeleteError, onPauseSuccess: onAlertingManagementPauseSuccess, onPauseError: onAlertingManagementPauseError })) : null, isAlertDialogOpen ? (
|
|
80
|
-
// TODO(GDP-3167 phase3): notificationChannels, users, usersError, and isLoading
|
|
81
|
-
// are still prop-threaded here because DefaultAlertingDialog reads them from props,
|
|
82
|
-
// not from AutomationsContext. Once all dialog fields are migrated to read from
|
|
83
|
-
// context, remove these props and the corresponding prop types.
|
|
84
|
-
_jsx(AlertingDialogWithUsers, { alertToEdit: alertToEdit, notificationChannels: notificationChannels, widget: insightWidget, insight: insight, isLoading: automationsLoading, onCancel: onAlertingCancel, onError: onAlertingCreateError, onSuccess: onAlertingCreateSuccess, onSaveError: onAlertingSaveError, onSaveSuccess: onAlertingSaveSuccess, onDeleteSuccess: onAlertingManagementDeleteSuccess, onDeleteError: onAlertingManagementDeleteError })) : null] }) }));
|
|
69
|
+
return (_jsxs(AlertingManagementDialogContextProvider, { value: managementCtx, children: [isAlertManagementDialogOpen ? (_jsx(AlertingManagementDialog, { onAdd: onAlertingManagementAdd, onEdit: handleManagementEdit, onClose: onAlertingManagementClose, onDeleteSuccess: onAlertingManagementDeleteSuccess, onDeleteError: onAlertingManagementDeleteError, onPauseSuccess: onAlertingManagementPauseSuccess, onPauseError: onAlertingManagementPauseError })) : null, isAlertDialogOpen ? (_jsx(AlertingCreateEditConnector, { alertToEdit: alertToEdit, notificationChannels: notificationChannels, widget: insightWidget, insight: insight, automationsLoading: automationsLoading, onCancel: onAlertingCancel, onError: onAlertingCreateError, onSuccess: onAlertingCreateSuccess, onSaveError: onAlertingSaveError, onSaveSuccess: onAlertingSaveSuccess, onDeleteSuccess: onAlertingManagementDeleteSuccess, onDeleteError: onAlertingManagementDeleteError })) : null] }));
|
|
85
70
|
}
|
|
86
71
|
/**
|
|
87
|
-
* Loads workspace users
|
|
88
|
-
*
|
|
89
|
-
*
|
|
90
|
-
* workspace-users load, matching the pre-separation behavior.
|
|
72
|
+
* Loads workspace users and hydrates the alerting create/edit context. Both live here rather than in
|
|
73
|
+
* the parent so that opening only the management dialog — which consumes neither — never dispatches the
|
|
74
|
+
* workspace-users load.
|
|
91
75
|
*/
|
|
92
|
-
function
|
|
76
|
+
function AlertingCreateEditConnector(props) {
|
|
77
|
+
const { alertToEdit, notificationChannels, widget, insight, automationsLoading, onCancel, onError, onSuccess, onSaveError, onSaveSuccess, onDeleteSuccess, onDeleteError, } = props;
|
|
93
78
|
const { users, status: usersStatus, usersError } = useWorkspaceUsers();
|
|
94
|
-
|
|
79
|
+
const isLoading = automationsLoading || usersStatus === "pending" || usersStatus === "loading";
|
|
80
|
+
const effectiveUsers = users ?? EMPTY_USERS;
|
|
81
|
+
const alertingCtx = useBuildAlertingDialogContext({
|
|
82
|
+
mode: alertToEdit ? "edit" : "create",
|
|
83
|
+
widget,
|
|
84
|
+
insight,
|
|
85
|
+
alertToEdit,
|
|
86
|
+
users: effectiveUsers,
|
|
87
|
+
usersError,
|
|
88
|
+
notificationChannels,
|
|
89
|
+
isLoading,
|
|
90
|
+
});
|
|
91
|
+
return (_jsx(AlertingDialogContextProvider, { value: alertingCtx, children: _jsx(AlertingDialog, { onCancel: onCancel, onError: onError, onSuccess: onSuccess, onSaveError: onSaveError, onSaveSuccess: onSaveSuccess, onDeleteSuccess: onDeleteSuccess, onDeleteError: onDeleteError }) }));
|
|
95
92
|
}
|
|
@@ -7,16 +7,34 @@ const fixtures = vi.hoisted(() => {
|
|
|
7
7
|
const navigate = vi.fn();
|
|
8
8
|
const onAlertingManagementEdit = vi.fn();
|
|
9
9
|
let managementDialogProps;
|
|
10
|
+
let dialogProps;
|
|
11
|
+
let automationsError;
|
|
12
|
+
const useWorkspaceUsers = vi.fn(() => ({ users: [], status: "success", usersError: undefined }));
|
|
13
|
+
const alertsState = { isAlertDialogOpen: false, isAlertManagementDialogOpen: true };
|
|
10
14
|
return {
|
|
11
15
|
buildAutomationUrl,
|
|
12
16
|
navigate,
|
|
13
17
|
onAlertingManagementEdit,
|
|
18
|
+
useWorkspaceUsers,
|
|
19
|
+
alertsState,
|
|
14
20
|
get managementDialogProps() {
|
|
15
21
|
return managementDialogProps;
|
|
16
22
|
},
|
|
17
23
|
set managementDialogProps(value) {
|
|
18
24
|
managementDialogProps = value;
|
|
19
25
|
},
|
|
26
|
+
get dialogProps() {
|
|
27
|
+
return dialogProps;
|
|
28
|
+
},
|
|
29
|
+
set dialogProps(value) {
|
|
30
|
+
dialogProps = value;
|
|
31
|
+
},
|
|
32
|
+
get automationsError() {
|
|
33
|
+
return automationsError;
|
|
34
|
+
},
|
|
35
|
+
set automationsError(value) {
|
|
36
|
+
automationsError = value;
|
|
37
|
+
},
|
|
20
38
|
};
|
|
21
39
|
});
|
|
22
40
|
vi.mock("@gooddata/sdk-ui", () => ({
|
|
@@ -30,11 +48,15 @@ vi.mock("../../../model/react/DashboardStoreProvider.js", () => ({
|
|
|
30
48
|
vi.mock("../../../model/react/useDashboardAlerting/useDashboardAlerts.js", () => ({
|
|
31
49
|
useDashboardAlerts: () => ({
|
|
32
50
|
isInitialized: true,
|
|
33
|
-
isAlertDialogOpen
|
|
34
|
-
|
|
51
|
+
get isAlertDialogOpen() {
|
|
52
|
+
return fixtures.alertsState.isAlertDialogOpen;
|
|
53
|
+
},
|
|
54
|
+
get isAlertManagementDialogOpen() {
|
|
55
|
+
return fixtures.alertsState.isAlertManagementDialogOpen;
|
|
56
|
+
},
|
|
35
57
|
alertToEdit: undefined,
|
|
36
58
|
automations: [],
|
|
37
|
-
automationsError:
|
|
59
|
+
automationsError: fixtures.automationsError,
|
|
38
60
|
automationsLoading: false,
|
|
39
61
|
notificationChannels: [],
|
|
40
62
|
onAlertingCancel: vi.fn(),
|
|
@@ -54,7 +76,7 @@ vi.mock("../../../model/react/useDashboardAlerting/useDashboardAlerts.js", () =>
|
|
|
54
76
|
}),
|
|
55
77
|
}));
|
|
56
78
|
vi.mock("../../../model/react/useWorkspaceUsers.js", () => ({
|
|
57
|
-
useWorkspaceUsers:
|
|
79
|
+
useWorkspaceUsers: fixtures.useWorkspaceUsers,
|
|
58
80
|
}));
|
|
59
81
|
vi.mock("../../../model/store/config/configSelectors.js", () => ({
|
|
60
82
|
selectExternalRecipient: () => "recipient@example.com",
|
|
@@ -68,7 +90,10 @@ vi.mock("../../../model/store/meta/metaSelectors.js", () => ({
|
|
|
68
90
|
selectDashboardId: () => "current-dashboard",
|
|
69
91
|
}));
|
|
70
92
|
vi.mock("../alerting/AlertingDialog.js", () => ({
|
|
71
|
-
AlertingDialog: () =>
|
|
93
|
+
AlertingDialog: (props) => {
|
|
94
|
+
fixtures.dialogProps = props;
|
|
95
|
+
return null;
|
|
96
|
+
},
|
|
72
97
|
}));
|
|
73
98
|
vi.mock("../alerting/AlertingManagementDialog.js", () => ({
|
|
74
99
|
AlertingManagementDialog: (props) => {
|
|
@@ -114,6 +139,11 @@ describe("AlertingConnector", () => {
|
|
|
114
139
|
fixtures.navigate.mockClear();
|
|
115
140
|
fixtures.onAlertingManagementEdit.mockClear();
|
|
116
141
|
fixtures.managementDialogProps = undefined;
|
|
142
|
+
fixtures.dialogProps = undefined;
|
|
143
|
+
fixtures.automationsError = undefined;
|
|
144
|
+
fixtures.useWorkspaceUsers.mockClear();
|
|
145
|
+
fixtures.alertsState.isAlertDialogOpen = false;
|
|
146
|
+
fixtures.alertsState.isAlertManagementDialogOpen = true;
|
|
117
147
|
});
|
|
118
148
|
it("uses host routes when editing an alert on another dashboard in shell mode", () => {
|
|
119
149
|
render(_jsx(AlertingConnector, {}));
|
|
@@ -148,4 +178,40 @@ describe("AlertingConnector", () => {
|
|
|
148
178
|
dashboard: undefined,
|
|
149
179
|
});
|
|
150
180
|
});
|
|
181
|
+
it("does not load workspace users when only the management dialog is open", () => {
|
|
182
|
+
render(_jsx(AlertingConnector, {}));
|
|
183
|
+
expect(fixtures.useWorkspaceUsers).not.toHaveBeenCalled();
|
|
184
|
+
});
|
|
185
|
+
it("loads workspace users when the create/edit dialog is open", () => {
|
|
186
|
+
fixtures.alertsState.isAlertDialogOpen = true;
|
|
187
|
+
fixtures.alertsState.isAlertManagementDialogOpen = false;
|
|
188
|
+
render(_jsx(AlertingConnector, {}));
|
|
189
|
+
expect(fixtures.useWorkspaceUsers).toHaveBeenCalled();
|
|
190
|
+
});
|
|
191
|
+
it("does not supply the deprecated data props to the create/edit dialog", () => {
|
|
192
|
+
fixtures.alertsState.isAlertDialogOpen = true;
|
|
193
|
+
fixtures.alertsState.isAlertManagementDialogOpen = false;
|
|
194
|
+
render(_jsx(AlertingConnector, {}));
|
|
195
|
+
expect(fixtures.dialogProps).toBeDefined();
|
|
196
|
+
for (const prop of [
|
|
197
|
+
"alertToEdit",
|
|
198
|
+
"users",
|
|
199
|
+
"usersError",
|
|
200
|
+
"notificationChannels",
|
|
201
|
+
"widget",
|
|
202
|
+
"insight",
|
|
203
|
+
"isLoading",
|
|
204
|
+
]) {
|
|
205
|
+
expect(fixtures.dialogProps?.[prop]).toBeUndefined();
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
it("renders the management dialog without the deprecated data props", () => {
|
|
209
|
+
fixtures.automationsError = new Error("automations failed to load");
|
|
210
|
+
render(_jsx(AlertingConnector, {}));
|
|
211
|
+
expect(fixtures.managementDialogProps).toBeDefined();
|
|
212
|
+
expect(fixtures.managementDialogProps?.["automations"]).toBeUndefined();
|
|
213
|
+
expect(fixtures.managementDialogProps?.["notificationChannels"]).toBeUndefined();
|
|
214
|
+
expect(fixtures.managementDialogProps?.["alertDataError"]).toBeUndefined();
|
|
215
|
+
expect(fixtures.managementDialogProps?.["isLoadingAlertingData"]).toBeUndefined();
|
|
216
|
+
});
|
|
151
217
|
});
|
|
@@ -1,9 +1,15 @@
|
|
|
1
|
-
import { type IInsight, type IWidget } from "@gooddata/sdk-model";
|
|
1
|
+
import { type IAutomationMetadataObject, type IInsight, type INotificationChannelIdentifier, type INotificationChannelMetadataObject, type IWidget, type IWorkspaceUser } from "@gooddata/sdk-model";
|
|
2
|
+
import type { GoodDataSdkError } from "@gooddata/sdk-ui";
|
|
2
3
|
import type { IAlertingDialogContextValue } from "../../contexts/AlertingDialogContext.js";
|
|
3
4
|
export interface IUseBuildAlertingDialogContextOpts {
|
|
4
5
|
mode: "create" | "edit";
|
|
5
6
|
widget?: IWidget;
|
|
6
7
|
insight?: IInsight;
|
|
8
|
+
alertToEdit?: IAutomationMetadataObject;
|
|
9
|
+
users: IWorkspaceUser[];
|
|
10
|
+
usersError?: GoodDataSdkError;
|
|
11
|
+
notificationChannels: INotificationChannelIdentifier[] | INotificationChannelMetadataObject[];
|
|
12
|
+
isLoading: boolean;
|
|
7
13
|
}
|
|
8
14
|
export declare function useBuildAlertingDialogContext(opts: IUseBuildAlertingDialogContextOpts): IAlertingDialogContextValue;
|
|
9
15
|
//# sourceMappingURL=useBuildAlertingDialogContext.d.ts.map
|
package/esm/presentation/automations/connectors/hooks/useBuildAlertingDialogContext.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useBuildAlertingDialogContext.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/automations/connectors/hooks/useBuildAlertingDialogContext.ts"],"names":[],"mappings":"AAKA,OAAO,
|
|
1
|
+
{"version":3,"file":"useBuildAlertingDialogContext.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/automations/connectors/hooks/useBuildAlertingDialogContext.ts"],"names":[],"mappings":"AAKA,OAAO,EACH,KAAK,yBAAyB,EAC9B,KAAK,QAAQ,EACb,KAAK,8BAA8B,EACnC,KAAK,kCAAkC,EACvC,KAAK,OAAO,EACZ,KAAK,cAAc,EAEtB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAiBzD,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,yCAAyC,CAAC;AAI3F,MAAM,WAAW,kCAAkC;IAC/C,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,QAAQ,CAAC;IACnB,WAAW,CAAC,EAAE,yBAAyB,CAAC;IACxC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,oBAAoB,EAAE,8BAA8B,EAAE,GAAG,kCAAkC,EAAE,CAAC;IAC9F,SAAS,EAAE,OAAO,CAAC;CACtB;AAED,wBAAgB,6BAA6B,CACzC,IAAI,EAAE,kCAAkC,GACzC,2BAA2B,CAsG7B"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// (C) 2026 GoodData Corporation
|
|
2
2
|
import { useCallback, useMemo, useRef } from "react";
|
|
3
|
-
import { serializeObjRef } from "@gooddata/sdk-model";
|
|
3
|
+
import { serializeObjRef, } from "@gooddata/sdk-model";
|
|
4
4
|
import { createAlert as createAlertCmd, saveAlert as saveAlertCmd, } from "../../../../model/commands/alerts.js";
|
|
5
5
|
import { useDashboardSelector } from "../../../../model/react/DashboardStoreProvider.js";
|
|
6
6
|
import { selectExecutionResultEntities } from "../../../../model/store/executionResults/executionResultsSelectors.js";
|
|
@@ -11,7 +11,7 @@ import { selectEffectiveParameterValuesForWidget } from "../../../../model/store
|
|
|
11
11
|
import { getWidgetTitle } from "../../../../model/utils/dashboardItemUtils.js";
|
|
12
12
|
import { useCommandAsPromise, useDeleteAutomation } from "./useCommandAsPromise.js";
|
|
13
13
|
export function useBuildAlertingDialogContext(opts) {
|
|
14
|
-
const { mode, widget, insight } = opts;
|
|
14
|
+
const { mode, widget, insight, alertToEdit, users, usersError, notificationChannels, isLoading } = opts;
|
|
15
15
|
const dashboardFilters = useDashboardSelector(selectAutomationDefaultSelectedFilters);
|
|
16
16
|
const hiddenFilters = useDashboardSelector(selectDashboardHiddenFilters);
|
|
17
17
|
const dashboardId = useDashboardSelector(selectDashboardId);
|
|
@@ -69,6 +69,11 @@ export function useBuildAlertingDialogContext(opts) {
|
|
|
69
69
|
createAlert,
|
|
70
70
|
saveAlert,
|
|
71
71
|
deleteAlert,
|
|
72
|
+
alertToEdit,
|
|
73
|
+
users,
|
|
74
|
+
usersError,
|
|
75
|
+
notificationChannels,
|
|
76
|
+
isLoading,
|
|
72
77
|
}), [
|
|
73
78
|
mode,
|
|
74
79
|
widget,
|
|
@@ -85,5 +90,10 @@ export function useBuildAlertingDialogContext(opts) {
|
|
|
85
90
|
createAlert,
|
|
86
91
|
saveAlert,
|
|
87
92
|
deleteAlert,
|
|
93
|
+
alertToEdit,
|
|
94
|
+
users,
|
|
95
|
+
usersError,
|
|
96
|
+
notificationChannels,
|
|
97
|
+
isLoading,
|
|
88
98
|
]);
|
|
89
99
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// (C) 2026 GoodData Corporation
|
|
2
2
|
import { renderHook } from "@testing-library/react";
|
|
3
3
|
import { describe, expect, it, vi } from "vitest";
|
|
4
|
-
import { idRef } from "@gooddata/sdk-model";
|
|
4
|
+
import { idRef, } from "@gooddata/sdk-model";
|
|
5
5
|
const fixtures = vi.hoisted(() => {
|
|
6
6
|
// A single, referentially stable execution-result envelope, simulating an
|
|
7
7
|
// unchanged normalized store entity across renders.
|
|
@@ -52,7 +52,12 @@ import { useBuildAlertingDialogContext } from "./useBuildAlertingDialogContext.j
|
|
|
52
52
|
describe("useBuildAlertingDialogContext", () => {
|
|
53
53
|
it("returns a referentially stable execution-result envelope across renders (no render loop)", () => {
|
|
54
54
|
const ref = idRef("widget-1");
|
|
55
|
-
const { result, rerender } = renderHook(() => useBuildAlertingDialogContext({
|
|
55
|
+
const { result, rerender } = renderHook(() => useBuildAlertingDialogContext({
|
|
56
|
+
mode: "create",
|
|
57
|
+
users: [],
|
|
58
|
+
notificationChannels: [],
|
|
59
|
+
isLoading: false,
|
|
60
|
+
}));
|
|
56
61
|
const first = result.current.executionResultByRef(ref);
|
|
57
62
|
rerender();
|
|
58
63
|
const second = result.current.executionResultByRef(ref);
|
|
@@ -63,4 +68,25 @@ describe("useBuildAlertingDialogContext", () => {
|
|
|
63
68
|
expect(second).toBe(first);
|
|
64
69
|
expect(first?.executionResult).toBe(fixtures.stableEnvelope.executionResult);
|
|
65
70
|
});
|
|
71
|
+
it("passes the create/edit inputs through to the context unchanged", () => {
|
|
72
|
+
const alertToEdit = { id: "alert-1", title: "My alert" };
|
|
73
|
+
const users = [
|
|
74
|
+
{ ref: idRef("user-1"), uri: "/users/user-1", login: "user-1", email: "user-1@example.com" },
|
|
75
|
+
];
|
|
76
|
+
const notificationChannels = [
|
|
77
|
+
{ id: "channel-1", type: "notificationChannel" },
|
|
78
|
+
];
|
|
79
|
+
const { result } = renderHook(() => useBuildAlertingDialogContext({
|
|
80
|
+
mode: "edit",
|
|
81
|
+
alertToEdit,
|
|
82
|
+
users,
|
|
83
|
+
usersError: undefined,
|
|
84
|
+
notificationChannels,
|
|
85
|
+
isLoading: true,
|
|
86
|
+
}));
|
|
87
|
+
expect(result.current.alertToEdit).toBe(alertToEdit);
|
|
88
|
+
expect(result.current.users).toBe(users);
|
|
89
|
+
expect(result.current.notificationChannels).toBe(notificationChannels);
|
|
90
|
+
expect(result.current.isLoading).toBe(true);
|
|
91
|
+
});
|
|
66
92
|
});
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import type { IExecutionResult } from "@gooddata/sdk-backend-spi";
|
|
2
|
-
import type { FilterContextItem, IAutomationMetadataObject, IAutomationMetadataObjectDefinition, IInsight, IInsightParameterValue, IWidget, ObjRef } from "@gooddata/sdk-model";
|
|
2
|
+
import type { FilterContextItem, IAutomationMetadataObject, IAutomationMetadataObjectDefinition, IInsight, IInsightParameterValue, INotificationChannelIdentifier, INotificationChannelMetadataObject, IWidget, IWorkspaceUser, ObjRef } from "@gooddata/sdk-model";
|
|
3
|
+
import type { GoodDataSdkError } from "@gooddata/sdk-ui";
|
|
3
4
|
/**
|
|
4
5
|
* Sub-context for the alerting create/edit dialog.
|
|
5
6
|
*
|
|
6
7
|
* The connector hydrates this from dashboard state and provides the CRUD callbacks; the dialog and its
|
|
7
8
|
* hooks read it instead of reaching into the dashboard store. That direction is enforced by the
|
|
8
9
|
* `no-model-imports-in-clean-alerting` rule in `.dependency-cruiser.js`.
|
|
10
|
+
*
|
|
11
|
+
* @alpha
|
|
9
12
|
*/
|
|
10
13
|
export interface IAlertingDialogContextValue {
|
|
11
14
|
mode: "create" | "edit";
|
|
@@ -26,7 +29,32 @@ export interface IAlertingDialogContextValue {
|
|
|
26
29
|
createAlert(alert: IAutomationMetadataObjectDefinition): Promise<IAutomationMetadataObject>;
|
|
27
30
|
saveAlert(alert: IAutomationMetadataObject): Promise<IAutomationMetadataObject>;
|
|
28
31
|
deleteAlert(alert: IAutomationMetadataObject): Promise<void>;
|
|
32
|
+
/** The alert being edited; undefined when creating a new one. */
|
|
33
|
+
alertToEdit?: IAutomationMetadataObject;
|
|
34
|
+
/**
|
|
35
|
+
* Workspace users available as alert recipients. Loaded only while the create/edit dialog is
|
|
36
|
+
* mounted, so opening the management dialog alone does not trigger the load.
|
|
37
|
+
*/
|
|
38
|
+
users: IWorkspaceUser[];
|
|
39
|
+
/** Error from loading workspace users, if any. */
|
|
40
|
+
usersError?: GoodDataSdkError;
|
|
41
|
+
/** Notification channels available as alert destinations. */
|
|
42
|
+
notificationChannels: INotificationChannelIdentifier[] | INotificationChannelMetadataObject[];
|
|
43
|
+
/** True while the dialog's initial data (automations, workspace users) is still loading. */
|
|
44
|
+
isLoading: boolean;
|
|
29
45
|
}
|
|
30
46
|
export declare const AlertingDialogContextProvider: import("react").Provider<IAlertingDialogContextValue | undefined>;
|
|
47
|
+
/**
|
|
48
|
+
* Reads the alerting create/edit dialog context.
|
|
49
|
+
*
|
|
50
|
+
* A replacement for `AlertingDialogComponent` renders inside this context and reads the dialog's widget
|
|
51
|
+
* and insight, the dashboard filter context it should apply, the alert being edited, the available
|
|
52
|
+
* workspace users and notification channels, and the create/save/delete callbacks from here.
|
|
53
|
+
*
|
|
54
|
+
* Some members exist to wire internal machinery (`executionResultByRef`, `widgetLocalIdToTabIdMap`,
|
|
55
|
+
* `parameterValues`) and are not intended as a customization surface.
|
|
56
|
+
*
|
|
57
|
+
* @alpha
|
|
58
|
+
*/
|
|
31
59
|
export declare function useAlertingDialogContext(): IAlertingDialogContextValue;
|
|
32
60
|
//# sourceMappingURL=AlertingDialogContext.d.ts.map
|