@gooddata/sdk-ui-dashboard 11.44.0-alpha.3 → 11.45.0-alpha.0

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.
Files changed (83) hide show
  1. package/esm/__version.d.ts +1 -1
  2. package/esm/__version.js +1 -1
  3. package/esm/index.d.ts +1 -1
  4. package/esm/index.d.ts.map +1 -1
  5. package/esm/index.js +1 -1
  6. package/esm/model/commandHandlers/drill/crossFilteringHandler.d.ts.map +1 -1
  7. package/esm/model/commandHandlers/drill/crossFilteringHandler.js +2 -3
  8. package/esm/model/commandHandlers/drill/drillToDashboardHandler.d.ts.map +1 -1
  9. package/esm/model/commandHandlers/drill/drillToDashboardHandler.js +1 -3
  10. package/esm/model/store/config/configSelectors.d.ts +0 -42
  11. package/esm/model/store/config/configSelectors.d.ts.map +1 -1
  12. package/esm/model/store/config/configSelectors.js +0 -56
  13. package/esm/model/store/tabs/layout/layoutSelectors.d.ts.map +1 -1
  14. package/esm/model/store/tabs/layout/layoutSelectors.js +2 -3
  15. package/esm/presentation/automations/alerting/DefaultAlertingDialog/hooks/useEditAlert.d.ts.map +1 -1
  16. package/esm/presentation/automations/alerting/DefaultAlertingDialog/hooks/useEditAlert.js +2 -2
  17. package/esm/presentation/automations/connectors/ScheduledEmailConnector.d.ts.map +1 -1
  18. package/esm/presentation/automations/connectors/ScheduledEmailConnector.js +49 -6
  19. package/esm/presentation/automations/connectors/ScheduledEmailConnector.test.d.ts +2 -0
  20. package/esm/presentation/automations/connectors/ScheduledEmailConnector.test.d.ts.map +1 -0
  21. package/esm/presentation/automations/connectors/ScheduledEmailConnector.test.js +165 -0
  22. package/esm/presentation/automations/connectors/hooks/useBuildAutomationsContext.d.ts.map +1 -1
  23. package/esm/presentation/automations/connectors/hooks/useBuildAutomationsContext.js +10 -5
  24. package/esm/presentation/automations/connectors/hooks/useBuildAutomationsContext.test.js +1 -1
  25. package/esm/presentation/automations/connectors/hooks/useBuildScheduledEmailDialogContext.d.ts.map +1 -1
  26. package/esm/presentation/automations/connectors/hooks/useBuildScheduledEmailDialogContext.js +2 -8
  27. package/esm/presentation/automations/connectors/hooks/useBuildScheduledEmailDialogContext.test.js +0 -1
  28. package/esm/presentation/automations/connectors/hooks/useBuildScheduledEmailManagementDialogContext.d.ts +3 -0
  29. package/esm/presentation/automations/connectors/hooks/useBuildScheduledEmailManagementDialogContext.d.ts.map +1 -0
  30. package/esm/presentation/automations/connectors/hooks/useBuildScheduledEmailManagementDialogContext.js +38 -0
  31. package/esm/presentation/automations/connectors/hooks/useBuildScheduledEmailManagementDialogContext.test.d.ts +2 -0
  32. package/esm/presentation/automations/connectors/hooks/useBuildScheduledEmailManagementDialogContext.test.d.ts.map +1 -0
  33. package/esm/presentation/automations/connectors/hooks/useBuildScheduledEmailManagementDialogContext.test.js +42 -0
  34. package/esm/presentation/automations/contexts/AutomationsContext.d.ts +12 -1
  35. package/esm/presentation/automations/contexts/AutomationsContext.d.ts.map +1 -1
  36. package/esm/presentation/automations/contexts/ScheduledEmailDialogContext.d.ts +1 -6
  37. package/esm/presentation/automations/contexts/ScheduledEmailDialogContext.d.ts.map +1 -1
  38. package/esm/presentation/automations/contexts/ScheduledEmailManagementDialogContext.d.ts +54 -0
  39. package/esm/presentation/automations/contexts/ScheduledEmailManagementDialogContext.d.ts.map +1 -0
  40. package/esm/presentation/automations/contexts/ScheduledEmailManagementDialogContext.js +11 -0
  41. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useEditScheduledEmail.d.ts.map +1 -1
  42. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useEditScheduledEmail.js +2 -2
  43. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduleValidation.js +2 -2
  44. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailManagementDialog/DefaultScheduledEmailManagementDialog.d.ts.map +1 -1
  45. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailManagementDialog/DefaultScheduledEmailManagementDialog.js +5 -35
  46. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailManagementDialog/DefaultScheduledEmailManagementDialogContentBasic.d.ts.map +1 -1
  47. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailManagementDialog/DefaultScheduledEmailManagementDialogContentBasic.js +5 -15
  48. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailManagementDialog/DefaultScheduledEmailManagementDialogContentEnhanced.d.ts.map +1 -1
  49. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailManagementDialog/DefaultScheduledEmailManagementDialogContentEnhanced.js +7 -25
  50. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailManagementDialog/components/DeleteScheduleConfirmDialog.d.ts.map +1 -1
  51. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailManagementDialog/components/DeleteScheduleConfirmDialog.js +3 -5
  52. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailManagementDialog/components/ScheduledEmail.d.ts.map +1 -1
  53. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailManagementDialog/components/ScheduledEmail.js +3 -6
  54. package/esm/presentation/automations/scheduledEmail/hooks/useScheduleEmailDialogAccessibility.d.ts.map +1 -1
  55. package/esm/presentation/automations/scheduledEmail/hooks/useScheduleEmailDialogAccessibility.js +3 -4
  56. package/esm/presentation/automations/shared/automationFilters/components/AutomationDateFilter.test.js +2 -1
  57. package/esm/presentation/dashboard/DashboardSidebar/CreationPanel.d.ts.map +1 -1
  58. package/esm/presentation/dashboard/DashboardSidebar/CreationPanel.js +2 -4
  59. package/esm/presentation/dashboard/DashboardSidebar/FloatingToolbar.d.ts.map +1 -1
  60. package/esm/presentation/dashboard/DashboardSidebar/FloatingToolbar.js +2 -3
  61. package/esm/presentation/dragAndDrop/draggableFilterDropZone/DraggableFilterDropZone.d.ts.map +1 -1
  62. package/esm/presentation/dragAndDrop/draggableFilterDropZone/DraggableFilterDropZone.js +1 -3
  63. package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/AddAttributeFilterPlaceholder.d.ts.map +1 -1
  64. package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/AddAttributeFilterPlaceholder.js +1 -4
  65. package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/AttributesDropdown.d.ts.map +1 -1
  66. package/esm/presentation/filterBar/attributeFilter/addAttributeFilter/AttributesDropdown.js +11 -6
  67. package/esm/presentation/filterBar/attributeFilter/dashboardDropdownBody/configuration/hooks/useAvailableDatasetsForItems.d.ts.map +1 -1
  68. package/esm/presentation/filterBar/attributeFilter/dashboardDropdownBody/configuration/hooks/useAvailableDatasetsForItems.js +1 -4
  69. package/esm/presentation/filterBar/attributeFilter/dashboardDropdownBody/configuration/limitValues/LimitValuesConfiguration.d.ts.map +1 -1
  70. package/esm/presentation/filterBar/attributeFilter/dashboardDropdownBody/configuration/limitValues/LimitValuesConfiguration.js +1 -3
  71. package/esm/presentation/filterBar/attributeFilter/dashboardDropdownBody/configuration/limitValues/dialog/ParentFiltersPage.d.ts.map +1 -1
  72. package/esm/presentation/filterBar/attributeFilter/dashboardDropdownBody/configuration/limitValues/dialog/ParentFiltersPage.js +1 -4
  73. package/esm/presentation/filterBar/filterBar/filterViews/FilterViewsList.d.ts.map +1 -1
  74. package/esm/presentation/filterBar/filterBar/filterViews/FilterViewsList.js +9 -3
  75. package/esm/presentation/widget/insight/ViewModeDashboardInsight/DashboardInsightWithDrillDialog.d.ts.map +1 -1
  76. package/esm/presentation/widget/insight/ViewModeDashboardInsight/DashboardInsightWithDrillDialog.js +2 -3
  77. package/esm/presentation/widget/insight/configuration/InsightAlertConfig/hooks/useEditAlert.d.ts.map +1 -1
  78. package/esm/presentation/widget/insight/configuration/InsightAlertConfig/hooks/useEditAlert.js +2 -3
  79. package/esm/presentation/widget/insight/configuration/InsightCrossFiltering.d.ts +1 -1
  80. package/esm/presentation/widget/insight/configuration/InsightCrossFiltering.d.ts.map +1 -1
  81. package/esm/presentation/widget/insight/configuration/InsightCrossFiltering.js +1 -6
  82. package/esm/sdk-ui-dashboard.d.ts +0 -49
  83. package/package.json +20 -20
@@ -21,7 +21,7 @@ import { useAttributeValuesFromExecResults } from "./useAttributeValuesFromExecR
21
21
  import { useThresholdValue } from "./useThresholdValue.js";
22
22
  export function useEditAlert({ alertToEdit, notificationChannels, insight, widget, users, editedAutomationFilters, maxAutomationsRecipients, setEditedAutomationFilters, availableFiltersAsVisibleFilters, filtersForNewAutomation, externalRecipientOverride, }) {
23
23
  const intl = useIntl();
24
- const { locale, catalogDateDatasets, catalogAttributes, currentUser, separators, weekStart, timezone, settings, allowHourlyRecurrence, features: { enableComparisonInAlerting: canManageComparison, enableExternalRecipients: enabledExternalRecipients, enableAlertAttributes: canManageAttributes, enableAlertOncePerInterval, }, } = useAutomationsContext();
24
+ const { locale, catalogDateDatasets, catalogAttributes, currentUser, separators, weekStart, timezone, settings, allowHourlyRecurrence, features: { enableComparisonInAlerting: canManageComparison, enableAlertAttributes: canManageAttributes, enableAlertOncePerInterval, }, } = useAutomationsContext();
25
25
  const isInvalidConnectionToInsight = alertToEdit?.metadata?.widget && !insight;
26
26
  const { executionResultByRef, dashboardId, hiddenFilters: dashboardHiddenFilters, commonDateFilterId, dashboardEvaluationFrequency, widgetLocalIdToTabIdMap: widgetTabMap, parameterValues, } = useAlertingDialogContext();
27
27
  const execResult = executionResultByRef(widget?.ref);
@@ -103,7 +103,7 @@ export function useEditAlert({ alertToEdit, notificationChannels, insight, widge
103
103
  const selectedGranularity = getAlertGranularity(editedAutomation?.alert);
104
104
  const [selectedAttribute, selectedValue] = getAlertAttribute(supportedAttributes, editedAutomation);
105
105
  const selectedNotificationChannel = notificationChannels.find((channel) => channel.id === editedAutomation?.notificationChannel);
106
- const allowExternalRecipients = selectedNotificationChannel?.allowedRecipients === "external" && enabledExternalRecipients;
106
+ const allowExternalRecipients = selectedNotificationChannel?.allowedRecipients === "external";
107
107
  const allowOnlyLoggedUserRecipients = selectedNotificationChannel?.allowedRecipients === "creator";
108
108
  const { isValid: isOriginalAutomationValid, invalidityReason } = useAlertValidation(originalAutomation, widget, insight, catalogDateDatasets, undefined, canManageComparison);
109
109
  const isParentValid = invalidityReason !== "missingWidget";
@@ -1 +1 @@
1
- {"version":3,"file":"ScheduledEmailConnector.d.ts","sourceRoot":"","sources":["../../../../src/presentation/automations/connectors/ScheduledEmailConnector.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AA4B1D;;;;;;GAMG;AACH,wBAAgB,iCAAiC,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,GAAG,YAAY,CAGrG;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,uBAAuB,IAAI,YAAY,GAAG,IAAI,CAM7D"}
1
+ {"version":3,"file":"ScheduledEmailConnector.d.ts","sourceRoot":"","sources":["../../../../src/presentation/automations/connectors/ScheduledEmailConnector.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,SAAS,EAAe,MAAM,OAAO,CAAC;AAsCvE;;;;;;GAMG;AACH,wBAAgB,iCAAiC,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,GAAG,YAAY,CAGrG;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,uBAAuB,IAAI,YAAY,GAAG,IAAI,CAM7D"}
@@ -1,17 +1,24 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // (C) 2026 GoodData Corporation
3
+ import { useCallback } from "react";
2
4
  import { isWidget } from "@gooddata/sdk-model";
5
+ import { buildAutomationUrl, navigate, useWorkspaceStrict } from "@gooddata/sdk-ui";
3
6
  import { getAutomationDashboardFilters, getAutomationVisualizationFilters, } from "../../../_staging/automation/index.js";
4
7
  import { useDashboardSelector } from "../../../model/react/DashboardStoreProvider.js";
5
8
  import { useDashboardScheduledEmails } from "../../../model/react/useDasboardScheduledEmails/useDashboardScheduledEmails.js";
6
9
  import { useWorkspaceUsers } from "../../../model/react/useWorkspaceUsers.js";
10
+ import { selectEnableAutomationManagement, selectExternalRecipient, selectIsEmbedded, selectSettings, } from "../../../model/store/config/configSelectors.js";
7
11
  import { selectAutomationDefaultSelectedFilters, selectDashboardHiddenFilters, } from "../../../model/store/filtering/dashboardFilterSelectors.js";
12
+ import { selectDashboardId } from "../../../model/store/meta/metaSelectors.js";
8
13
  import { AutomationsContextProvider } from "../contexts/AutomationsContext.js";
9
14
  import { ScheduledEmailDialogContextProvider } from "../contexts/ScheduledEmailDialogContext.js";
15
+ import { ScheduledEmailManagementDialogContextProvider } from "../contexts/ScheduledEmailManagementDialogContext.js";
10
16
  import { ScheduledEmailDialog } from "../scheduledEmail/ScheduledEmailDialog.js";
11
17
  import { ScheduledEmailManagementDialog } from "../scheduledEmail/ScheduledEmailManagementDialog.js";
12
18
  import { getAppliedDashboardFilters } from "../scheduledEmail/utils/filters.js";
13
19
  import { useBuildAutomationsContext } from "./hooks/useBuildAutomationsContext.js";
14
20
  import { useBuildScheduledEmailDialogContext } from "./hooks/useBuildScheduledEmailDialogContext.js";
21
+ import { useBuildScheduledEmailManagementDialogContext } from "./hooks/useBuildScheduledEmailManagementDialogContext.js";
15
22
  import { useWidgetAutomationFilters } from "./hooks/useWidgetAutomationFilters.js";
16
23
  /**
17
24
  * Provides AutomationsContext to its children, built from dashboard Redux state.
@@ -64,6 +71,40 @@ function ScheduledEmailConnectorWithData({ se }) {
64
71
  isScheduleEmailingDialogOpen, onScheduleEmailingCancel, onScheduleEmailingBack, onScheduleEmailingCreateSuccess, onScheduleEmailingCreateError, onScheduleEmailingSaveSuccess, onScheduleEmailingSaveError,
65
72
  // Management / List Dialog
66
73
  isScheduleEmailingManagementDialogOpen, onScheduleEmailingManagementClose, onScheduleEmailingManagementAdd, onScheduleEmailingManagementEdit, onScheduleEmailingManagementDeleteSuccess, onScheduleEmailingManagementDeleteError, widget, insight, } = se;
74
+ const workspace = useWorkspaceStrict();
75
+ const enableAutomationManagement = useDashboardSelector(selectEnableAutomationManagement);
76
+ const dashboardId = useDashboardSelector(selectDashboardId);
77
+ const isEmbedded = useDashboardSelector(selectIsEmbedded);
78
+ const externalRecipientOverride = useDashboardSelector(selectExternalRecipient);
79
+ const settings = useDashboardSelector(selectSettings);
80
+ const useHostRoute = Boolean(settings?.enableShellApplication) && Boolean(settings?.enableShellApplication_dashboards);
81
+ // Cross-dashboard edit routing lives in the connector (which may read router + store).
82
+ // The management dialog only invokes this injected callback.
83
+ const handleManagementEdit = useCallback((scheduledEmail) => {
84
+ const targetDashboardId = scheduledEmail.dashboard?.id;
85
+ if (enableAutomationManagement && targetDashboardId && targetDashboardId !== dashboardId) {
86
+ navigate(buildAutomationUrl({
87
+ workspaceId: workspace,
88
+ dashboardId: targetDashboardId,
89
+ automationId: scheduledEmail.id,
90
+ isEmbedded,
91
+ useHostRoute,
92
+ queryParams: externalRecipientOverride
93
+ ? { recipient: externalRecipientOverride }
94
+ : undefined,
95
+ }));
96
+ return;
97
+ }
98
+ onScheduleEmailingManagementEdit(scheduledEmail);
99
+ }, [
100
+ onScheduleEmailingManagementEdit,
101
+ enableAutomationManagement,
102
+ dashboardId,
103
+ workspace,
104
+ isEmbedded,
105
+ useHostRoute,
106
+ externalRecipientOverride,
107
+ ]);
67
108
  // Filter computation — moved verbatim from ScheduledEmailDialogProvider
68
109
  const automationDefaultSelectedFilters = useDashboardSelector(selectAutomationDefaultSelectedFilters);
69
110
  const dashboardHiddenFilters = useDashboardSelector(selectDashboardHiddenFilters);
@@ -82,12 +123,14 @@ function ScheduledEmailConnectorWithData({ se }) {
82
123
  widget: insightWidget,
83
124
  insight,
84
125
  });
85
- return (_jsxs(ScheduledEmailDialogContextProvider, { value: seCtx, children: [isScheduleEmailingManagementDialogOpen ? (
86
- // TODO(GDP-3167 phase3): automations, notificationChannels, and scheduleDataError
87
- // are still prop-threaded here because DefaultScheduledEmailManagementDialog reads
88
- // them from props, not from AutomationsContext. Once all dialog fields are migrated
89
- // to read from context, remove these props and the corresponding prop types.
90
- _jsx(ScheduledEmailManagementDialog, { automations: automations, notificationChannels: notificationChannels, scheduleDataError: loadingError, isLoadingScheduleData: isLoading, onAdd: onScheduleEmailingManagementAdd, onEdit: onScheduleEmailingManagementEdit, onClose: onScheduleEmailingManagementClose, onDeleteSuccess: onScheduleEmailingManagementDeleteSuccess, onDeleteError: onScheduleEmailingManagementDeleteError })) : null, isScheduleEmailingDialogOpen ? (
126
+ const managementCtx = useBuildScheduledEmailManagementDialogContext();
127
+ return (_jsxs(ScheduledEmailDialogContextProvider, { value: seCtx, children: [
128
+ _jsx(ScheduledEmailManagementDialogContextProvider, { value: managementCtx, children: isScheduleEmailingManagementDialogOpen ? (
129
+ // TODO(GDP-3167 phase3): automations, notificationChannels, and scheduleDataError
130
+ // are still prop-threaded here because DefaultScheduledEmailManagementDialog reads
131
+ // them from props, not from AutomationsContext. Once all dialog fields are migrated
132
+ // to read from context, remove these props and the corresponding prop types.
133
+ _jsx(ScheduledEmailManagementDialog, { automations: automations, notificationChannels: notificationChannels, scheduleDataError: loadingError, isLoadingScheduleData: isLoading, onAdd: onScheduleEmailingManagementAdd, onEdit: handleManagementEdit, onClose: onScheduleEmailingManagementClose, onDeleteSuccess: onScheduleEmailingManagementDeleteSuccess, onDeleteError: onScheduleEmailingManagementDeleteError })) : null }), isScheduleEmailingDialogOpen ? (
91
134
  // TODO(GDP-3167 phase3): notificationChannels, users, usersError, widgetFilters,
92
135
  // dashboardFilters, and isLoading are still prop-threaded here because
93
136
  // DefaultScheduledEmailDialog reads them from props, not from context.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=ScheduledEmailConnector.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ScheduledEmailConnector.test.d.ts","sourceRoot":"","sources":["../../../../src/presentation/automations/connectors/ScheduledEmailConnector.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,165 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ // (C) 2026 GoodData Corporation
3
+ import { render } from "@testing-library/react";
4
+ import { beforeEach, describe, expect, it, vi } from "vitest";
5
+ const fixtures = vi.hoisted(() => {
6
+ const buildAutomationUrl = vi.fn(() => "/target-url");
7
+ const navigate = vi.fn();
8
+ const onScheduleEmailingManagementEdit = vi.fn();
9
+ let managementDialogProps;
10
+ return {
11
+ buildAutomationUrl,
12
+ navigate,
13
+ onScheduleEmailingManagementEdit,
14
+ get managementDialogProps() {
15
+ return managementDialogProps;
16
+ },
17
+ set managementDialogProps(value) {
18
+ managementDialogProps = value;
19
+ },
20
+ };
21
+ });
22
+ vi.mock("@gooddata/sdk-ui", () => ({
23
+ buildAutomationUrl: fixtures.buildAutomationUrl,
24
+ navigate: fixtures.navigate,
25
+ useWorkspaceStrict: () => "workspace-id",
26
+ }));
27
+ vi.mock("../../../model/react/DashboardStoreProvider.js", () => ({
28
+ useDashboardSelector: vi.fn((selector) => selector()),
29
+ }));
30
+ vi.mock("../../../model/react/useDasboardScheduledEmails/useDashboardScheduledEmails.js", () => ({
31
+ useDashboardScheduledEmails: () => ({
32
+ isInitialized: true,
33
+ isScheduleEmailingDialogOpen: false,
34
+ isScheduleEmailingManagementDialogOpen: true,
35
+ scheduledExportToEdit: undefined,
36
+ automations: [],
37
+ automationsError: undefined,
38
+ automationsLoading: false,
39
+ notificationChannels: [],
40
+ onScheduleEmailingCancel: vi.fn(),
41
+ onScheduleEmailingBack: vi.fn(),
42
+ onScheduleEmailingCreateSuccess: vi.fn(),
43
+ onScheduleEmailingCreateError: vi.fn(),
44
+ onScheduleEmailingSaveSuccess: vi.fn(),
45
+ onScheduleEmailingSaveError: vi.fn(),
46
+ onScheduleEmailingManagementClose: vi.fn(),
47
+ onScheduleEmailingManagementAdd: vi.fn(),
48
+ onScheduleEmailingManagementEdit: fixtures.onScheduleEmailingManagementEdit,
49
+ onScheduleEmailingManagementDeleteSuccess: vi.fn(),
50
+ onScheduleEmailingManagementDeleteError: vi.fn(),
51
+ widget: undefined,
52
+ insight: undefined,
53
+ }),
54
+ }));
55
+ vi.mock("../../../model/react/useWorkspaceUsers.js", () => ({
56
+ useWorkspaceUsers: () => ({ users: [], status: "success", usersError: undefined }),
57
+ }));
58
+ vi.mock("../../../model/store/config/configSelectors.js", () => ({
59
+ selectEnableAutomationManagement: () => true,
60
+ selectExternalRecipient: () => "recipient@example.com",
61
+ selectIsEmbedded: () => false,
62
+ selectSettings: () => ({
63
+ enableShellApplication: true,
64
+ enableShellApplication_dashboards: true,
65
+ }),
66
+ selectEnableAccessibilityMode: () => false,
67
+ }));
68
+ vi.mock("../../../model/store/meta/metaSelectors.js", () => ({
69
+ selectDashboardId: () => "current-dashboard",
70
+ selectDashboardTitle: () => "Current Dashboard",
71
+ }));
72
+ vi.mock("../../../model/store/filtering/dashboardFilterSelectors.js", () => ({
73
+ selectAutomationDefaultSelectedFilters: () => [],
74
+ selectDashboardHiddenFilters: () => [],
75
+ }));
76
+ vi.mock("../../../model/store/insights/insightsSelectors.js", () => ({
77
+ selectInsightsMap: () => ({ get: () => undefined }),
78
+ }));
79
+ vi.mock("../../../model/store/tabs/layout/layoutSelectors.js", () => ({
80
+ selectWidgetsMap: () => ({ get: () => undefined }),
81
+ }));
82
+ vi.mock("../../../model/store/ui/uiSelectors.js", () => ({
83
+ selectIsScheduleEmailDialogOpen: () => false,
84
+ selectScheduleEmailDialogReturnFocusTo: () => undefined,
85
+ selectAutomationsInvalidationId: () => 0,
86
+ }));
87
+ vi.mock("../scheduledEmail/ScheduledEmailDialog.js", () => ({
88
+ ScheduledEmailDialog: () => null,
89
+ }));
90
+ vi.mock("../scheduledEmail/ScheduledEmailManagementDialog.js", () => ({
91
+ ScheduledEmailManagementDialog: (props) => {
92
+ fixtures.managementDialogProps = props;
93
+ return null;
94
+ },
95
+ }));
96
+ vi.mock("../contexts/AutomationsContext.js", () => ({
97
+ AutomationsContextProvider: ({ children }) => children,
98
+ }));
99
+ vi.mock("../contexts/ScheduledEmailDialogContext.js", () => ({
100
+ ScheduledEmailDialogContextProvider: ({ children }) => children,
101
+ }));
102
+ vi.mock("../contexts/ScheduledEmailManagementDialogContext.js", () => ({
103
+ ScheduledEmailManagementDialogContextProvider: ({ children }) => children,
104
+ }));
105
+ vi.mock("./hooks/useBuildAutomationsContext.js", () => ({
106
+ useBuildAutomationsContext: () => ({}),
107
+ }));
108
+ vi.mock("./hooks/useBuildScheduledEmailDialogContext.js", () => ({
109
+ useBuildScheduledEmailDialogContext: () => ({}),
110
+ }));
111
+ vi.mock("./hooks/useBuildScheduledEmailManagementDialogContext.js", () => ({
112
+ useBuildScheduledEmailManagementDialogContext: () => ({}),
113
+ }));
114
+ vi.mock("./hooks/useWidgetAutomationFilters.js", () => ({
115
+ useWidgetAutomationFilters: () => ({ result: undefined, status: "success", error: undefined }),
116
+ }));
117
+ vi.mock("../../../_staging/automation/index.js", () => ({
118
+ getAutomationDashboardFilters: () => undefined,
119
+ getAutomationVisualizationFilters: () => ({ executionFilters: undefined }),
120
+ }));
121
+ vi.mock("../scheduledEmail/utils/filters.js", () => ({
122
+ getAppliedDashboardFilters: () => [],
123
+ }));
124
+ import { ScheduledEmailConnector } from "./ScheduledEmailConnector.js";
125
+ describe("ScheduledEmailConnector", () => {
126
+ beforeEach(() => {
127
+ fixtures.buildAutomationUrl.mockClear();
128
+ fixtures.navigate.mockClear();
129
+ fixtures.onScheduleEmailingManagementEdit.mockClear();
130
+ fixtures.managementDialogProps = undefined;
131
+ });
132
+ it("navigates cross-dashboard when editing a schedule on another dashboard in shell mode", () => {
133
+ render(_jsx(ScheduledEmailConnector, {}));
134
+ const onEdit = fixtures.managementDialogProps?.["onEdit"];
135
+ expect(onEdit).toBeDefined();
136
+ onEdit?.({
137
+ id: "se-1",
138
+ dashboard: { id: "other-dashboard" },
139
+ });
140
+ expect(fixtures.buildAutomationUrl).toHaveBeenCalledWith({
141
+ workspaceId: "workspace-id",
142
+ dashboardId: "other-dashboard",
143
+ automationId: "se-1",
144
+ isEmbedded: false,
145
+ useHostRoute: true,
146
+ queryParams: { recipient: "recipient@example.com" },
147
+ });
148
+ expect(fixtures.navigate).toHaveBeenCalledWith("/target-url");
149
+ expect(fixtures.onScheduleEmailingManagementEdit).not.toHaveBeenCalled();
150
+ });
151
+ it("falls back to local edit when the target dashboard id is missing", () => {
152
+ render(_jsx(ScheduledEmailConnector, {}));
153
+ const onEdit = fixtures.managementDialogProps?.["onEdit"];
154
+ onEdit?.({
155
+ id: "se-2",
156
+ dashboard: undefined,
157
+ });
158
+ expect(fixtures.navigate).not.toHaveBeenCalled();
159
+ expect(fixtures.buildAutomationUrl).not.toHaveBeenCalled();
160
+ expect(fixtures.onScheduleEmailingManagementEdit).toHaveBeenCalledWith({
161
+ id: "se-2",
162
+ dashboard: undefined,
163
+ });
164
+ });
165
+ });
@@ -1 +1 @@
1
- {"version":3,"file":"useBuildAutomationsContext.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/automations/connectors/hooks/useBuildAutomationsContext.ts"],"names":[],"mappings":"AA4EA,OAAO,KAAK,EACR,wBAAwB,EAE3B,MAAM,sCAAsC,CAAC;AAI9C,wBAAgB,0BAA0B,IAAI,wBAAwB,CAqMrE"}
1
+ {"version":3,"file":"useBuildAutomationsContext.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/automations/connectors/hooks/useBuildAutomationsContext.ts"],"names":[],"mappings":"AA+EA,OAAO,KAAK,EACR,wBAAwB,EAE3B,MAAM,sCAAsC,CAAC;AAI9C,wBAAgB,0BAA0B,IAAI,wBAAwB,CA6MrE"}
@@ -2,7 +2,7 @@
2
2
  import { useCallback, useMemo } from "react";
3
3
  import { useDashboardSelector } from "../../../../model/react/DashboardStoreProvider.js";
4
4
  import { selectAllCatalogAttributesMap, selectAllCatalogDisplayFormsMap, selectCatalogAttributes, selectCatalogDateDatasets, selectCatalogMeasures, } from "../../../../model/store/catalog/catalogSelectors.js";
5
- import { selectEnableAlertAttributes, selectEnableAlertOncePerInterval, selectEnableAnomalyDetectionAlert, selectEnableAutomationEvaluationMode, selectEnableAutomationManagement, selectEnableComparisonInAlerting, selectEnableCustomizableCsvDelimiter, selectEnableExternalRecipients, selectEnableNewScheduledExport, selectExternalRecipient, selectIsWhiteLabeled, selectLocale, selectSeparators, selectSettings, selectTimezone, selectWeekStart, } from "../../../../model/store/config/configSelectors.js";
5
+ import { selectEnableAlertAttributes, selectEnableAlertOncePerInterval, selectEnableAnomalyDetectionAlert, selectEnableAutomationEvaluationMode, selectEnableAutomationManagement, selectEnableComparisonInAlerting, selectEnableCustomizableCsvDelimiter, selectEnableNewScheduledExport, selectExternalRecipient, selectIsWhiteLabeled, selectLocale, selectSeparators, selectSettings, selectTimezone, selectWeekStart, } from "../../../../model/store/config/configSelectors.js";
6
6
  import { selectEntitlementMinimumRecurrenceMinutes, selectMaxAutomationRecipients, } from "../../../../model/store/entitlements/entitlementsSelectors.js";
7
7
  import { selectAutomationAvailableDashboardFilters, selectAutomationCommonDateFilterId, selectAutomationDefaultSelectedFilters, selectAutomationFiltersByTab, selectDashboardFiltersWithoutCrossFiltering, selectDashboardHiddenFilters, selectDashboardLockedFilters, } from "../../../../model/store/filtering/dashboardFilterSelectors.js";
8
8
  import { selectPersistedDashboardFilterContextDateFilterConfig } from "../../../../model/store/meta/metaSelectors.js";
@@ -11,9 +11,10 @@ import { selectAttributeFilterConfigsOverrides, selectAttributeFilterConfigsOver
11
11
  import { selectDateFilterConfigOverridesByTab, selectEffectiveDateFilterAvailableGranularities, selectEffectiveDateFilterGranularitiesPerTab, selectEffectiveDateFilterOptions, selectEffectiveDateFilterOptionsPerTab, } from "../../../../model/store/tabs/dateFilterConfig/dateFilterConfigSelectors.js";
12
12
  import { selectDateFilterConfigsOverrides, selectDateFilterConfigsOverridesByTab, } from "../../../../model/store/tabs/dateFilterConfigs/dateFilterConfigsSelectors.js";
13
13
  import { selectAttributeFilterDisplayFormsMap } from "../../../../model/store/tabs/filterContext/filterContextSelectors.js";
14
+ import { selectWidgetsMap } from "../../../../model/store/tabs/layout/layoutSelectors.js";
14
15
  import { selectMeasureValueFilterConfigsOverrides, selectMeasureValueFilterConfigsOverridesByTab, } from "../../../../model/store/tabs/measureValueFilterConfigs/measureValueFilterConfigsSelectors.js";
15
16
  import { selectIsAutomationDialogSecondaryTitleVisible } from "../../../../model/store/topBar/topBarSelectors.js";
16
- import { selectExecutionTimestamp } from "../../../../model/store/ui/uiSelectors.js";
17
+ import { selectExecutionTimestamp, selectScheduleEmailDialogReturnFocusTo, } from "../../../../model/store/ui/uiSelectors.js";
17
18
  import { selectCurrentUser } from "../../../../model/store/user/userSelectors.js";
18
19
  const DEFAULT_MIN_RECURRENCE_MINUTES = "60";
19
20
  export function useBuildAutomationsContext() {
@@ -61,7 +62,6 @@ export function useBuildAutomationsContext() {
61
62
  const canUseAiAssistant = useDashboardSelector(selectCanUseAiAssistant);
62
63
  const canManageWorkspace = useDashboardSelector(selectCanManageWorkspace);
63
64
  const enableComparisonInAlerting = useDashboardSelector(selectEnableComparisonInAlerting);
64
- const enableExternalRecipients = useDashboardSelector(selectEnableExternalRecipients);
65
65
  const enableAlertAttributes = useDashboardSelector(selectEnableAlertAttributes);
66
66
  const enableCustomizableCsvDelimiter = useDashboardSelector(selectEnableCustomizableCsvDelimiter);
67
67
  const enableAutomationEvaluationMode = useDashboardSelector(selectEnableAutomationEvaluationMode);
@@ -70,8 +70,11 @@ export function useBuildAutomationsContext() {
70
70
  const allowHourlyRecurrence = parseInt(minimumRecurrenceMinutesEntitlement?.value ?? DEFAULT_MIN_RECURRENCE_MINUTES, 10) === 60;
71
71
  const executionTimestamp = useDashboardSelector(selectExecutionTimestamp);
72
72
  const isExecutionTimestampMode = !!executionTimestamp;
73
+ const scheduleEmailDialogReturnFocusTo = useDashboardSelector(selectScheduleEmailDialogReturnFocusTo);
74
+ const widgetsMap = useDashboardSelector(selectWidgetsMap);
73
75
  const getCatalogAttributeByRef = useCallback((ref) => allCatalogAttributesMap.get(ref), [allCatalogAttributesMap]);
74
76
  const getAttributeFilterDisplayForm = useCallback((displayForm) => attrFilterDisplayFormsMap.get(displayForm) ?? catalogDisplayFormsMap.get(displayForm), [attrFilterDisplayFormsMap, catalogDisplayFormsMap]);
77
+ const widgetExistsByRef = useCallback((ref) => !!ref && widgetsMap.get(ref) !== undefined, [widgetsMap]);
75
78
  const dateFilterConfig = useMemo(() => ({
76
79
  availableGranularities,
77
80
  dateFilterOptions,
@@ -85,7 +88,6 @@ export function useBuildAutomationsContext() {
85
88
  enableAutomationManagement,
86
89
  canUseAiAssistant,
87
90
  enableComparisonInAlerting,
88
- enableExternalRecipients,
89
91
  enableAlertAttributes,
90
92
  canManageWorkspace,
91
93
  enableCustomizableCsvDelimiter,
@@ -97,7 +99,6 @@ export function useBuildAutomationsContext() {
97
99
  enableAutomationManagement,
98
100
  canUseAiAssistant,
99
101
  enableComparisonInAlerting,
100
- enableExternalRecipients,
101
102
  enableAlertAttributes,
102
103
  canManageWorkspace,
103
104
  enableCustomizableCsvDelimiter,
@@ -141,6 +142,8 @@ export function useBuildAutomationsContext() {
141
142
  features,
142
143
  getCatalogAttributeByRef,
143
144
  getAttributeFilterDisplayForm,
145
+ widgetExistsByRef,
146
+ scheduleEmailDialogReturnFocusTo,
144
147
  }), [
145
148
  locale,
146
149
  separators,
@@ -179,5 +182,7 @@ export function useBuildAutomationsContext() {
179
182
  features,
180
183
  getCatalogAttributeByRef,
181
184
  getAttributeFilterDisplayForm,
185
+ widgetExistsByRef,
186
+ scheduleEmailDialogReturnFocusTo,
182
187
  ]);
183
188
  }
@@ -52,7 +52,6 @@ vi.mock("../../../../model/store/config/configSelectors.js", () => ({
52
52
  selectEnableAutomationManagement: () => false,
53
53
  selectEnableComparisonInAlerting: () => false,
54
54
  selectEnableCustomizableCsvDelimiter: () => false,
55
- selectEnableExternalRecipients: () => false,
56
55
  selectEnableNewScheduledExport: () => false,
57
56
  selectExternalRecipient: () => undefined,
58
57
  selectIsWhiteLabeled: () => false,
@@ -120,6 +119,7 @@ vi.mock("../../../../model/store/entitlements/entitlementsSelectors.js", () => (
120
119
  }));
121
120
  vi.mock("../../../../model/store/ui/uiSelectors.js", () => ({
122
121
  selectExecutionTimestamp: () => undefined,
122
+ selectScheduleEmailDialogReturnFocusTo: () => undefined,
123
123
  }));
124
124
  vi.mock("../../../../model/store/tabs/measureValueFilterConfigs/measureValueFilterConfigsSelectors.js", () => ({
125
125
  selectMeasureValueFilterConfigsOverrides: () => [],
@@ -1 +1 @@
1
- {"version":3,"file":"useBuildScheduledEmailDialogContext.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/automations/connectors/hooks/useBuildScheduledEmailDialogContext.ts"],"names":[],"mappings":"AAIA,OAAO,EAEH,KAAK,QAAQ,EACb,KAAK,OAAO,EAGf,MAAM,qBAAqB,CAAC;AA2B7B,OAAO,KAAK,EAAE,iCAAiC,EAAE,MAAM,+CAA+C,CAAC;AAIvG,MAAM,WAAW,wCAAwC;IACrD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,QAAQ,CAAC;CACtB;AAED,wBAAgB,mCAAmC,CAC/C,IAAI,EAAE,wCAAwC,GAC/C,iCAAiC,CAmGnC"}
1
+ {"version":3,"file":"useBuildScheduledEmailDialogContext.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/automations/connectors/hooks/useBuildScheduledEmailDialogContext.ts"],"names":[],"mappings":"AAIA,OAAO,EAEH,KAAK,QAAQ,EACb,KAAK,OAAO,EAEf,MAAM,qBAAqB,CAAC;AAwB7B,OAAO,KAAK,EAAE,iCAAiC,EAAE,MAAM,+CAA+C,CAAC;AAIvG,MAAM,WAAW,wCAAwC;IACrD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,QAAQ,CAAC;CACtB;AAED,wBAAgB,mCAAmC,CAC/C,IAAI,EAAE,wCAAwC,GAC/C,iCAAiC,CAyFnC"}
@@ -1,5 +1,5 @@
1
1
  // (C) 2026 GoodData Corporation
2
- import { useCallback, useMemo } from "react";
2
+ import { useMemo } from "react";
3
3
  import { objRefToString, } from "@gooddata/sdk-model";
4
4
  import { createScheduledEmail as createScheduledEmailCmd, saveScheduledEmail as saveScheduledEmailCmd, } from "../../../../model/commands/scheduledEmail.js";
5
5
  import { useDashboardSelector } from "../../../../model/react/DashboardStoreProvider.js";
@@ -11,7 +11,7 @@ import { selectDashboardId, selectDashboardTitle } from "../../../../model/store
11
11
  import { selectEffectiveAttributeFiltersModeMap } from "../../../../model/store/tabs/attributeFilterConfigs/attributeFilterConfigsSelectors.js";
12
12
  import { selectEffectiveDateFilterMode } from "../../../../model/store/tabs/dateFilterConfig/dateFilterConfigSelectors.js";
13
13
  import { selectEffectiveDateFiltersModeMap } from "../../../../model/store/tabs/dateFilterConfigs/dateFilterConfigsSelectors.js";
14
- import { selectWidgetLocalIdToTabIdMap, selectWidgetsMap, } from "../../../../model/store/tabs/layout/layoutSelectors.js";
14
+ import { selectWidgetLocalIdToTabIdMap } from "../../../../model/store/tabs/layout/layoutSelectors.js";
15
15
  import { selectExportEffectiveParameters } from "../../../../model/store/tabs/parameters/parametersSelectors.js";
16
16
  import { selectTabs } from "../../../../model/store/tabs/tabsSelectors.js";
17
17
  import { getWidgetTitle } from "../../../../model/utils/dashboardItemUtils.js";
@@ -30,7 +30,6 @@ export function useBuildScheduledEmailDialogContext(opts) {
30
30
  const isCrossFiltering = useDashboardSelector(selectIsCrossFiltering);
31
31
  const tabs = useDashboardSelector(selectTabs);
32
32
  const hasMultipleTabs = (tabs?.length ?? 0) > 1;
33
- const widgetsMap = useDashboardSelector(selectWidgetsMap);
34
33
  const commonDateFilterMode = useDashboardSelector(selectEffectiveDateFilterMode);
35
34
  const dateFiltersModeMap = useDashboardSelector(selectEffectiveDateFiltersModeMap);
36
35
  const attributeFiltersModeMap = useDashboardSelector(selectEffectiveAttributeFiltersModeMap);
@@ -40,9 +39,6 @@ export function useBuildScheduledEmailDialogContext(opts) {
40
39
  }
41
40
  return undefined;
42
41
  }, [widget]);
43
- const widgetExistsByRef = useCallback((ref) => {
44
- return !!ref && widgetsMap.get(ref) !== undefined;
45
- }, [widgetsMap]);
46
42
  const createScheduledEmail = useCommandAsPromise({
47
43
  commandCreator: createScheduledEmailCmd,
48
44
  successEvent: "GDC.DASH/EVT.SCHEDULED_EMAIL.CREATED",
@@ -69,7 +65,6 @@ export function useBuildScheduledEmailDialogContext(opts) {
69
65
  dateFormat,
70
66
  isCrossFiltering,
71
67
  hasMultipleTabs,
72
- widgetExistsByRef,
73
68
  commonDateFilterMode,
74
69
  dateFiltersModeMap,
75
70
  attributeFiltersModeMap,
@@ -91,7 +86,6 @@ export function useBuildScheduledEmailDialogContext(opts) {
91
86
  dateFormat,
92
87
  isCrossFiltering,
93
88
  hasMultipleTabs,
94
- widgetExistsByRef,
95
89
  commonDateFilterMode,
96
90
  dateFiltersModeMap,
97
91
  attributeFiltersModeMap,
@@ -46,7 +46,6 @@ vi.mock("../../../../model/store/drill/drillSelectors.js", () => ({
46
46
  }));
47
47
  vi.mock("../../../../model/store/tabs/layout/layoutSelectors.js", () => ({
48
48
  selectWidgetLocalIdToTabIdMap: () => ({ widgetId: "tab-1" }),
49
- selectWidgetsMap: () => ({ get: () => undefined }),
50
49
  }));
51
50
  vi.mock("../../../../model/store/tabs/dateFilterConfig/dateFilterConfigSelectors.js", () => ({
52
51
  selectEffectiveDateFilterMode: () => "active",
@@ -0,0 +1,3 @@
1
+ import type { IScheduledEmailManagementDialogContextValue } from "../../contexts/ScheduledEmailManagementDialogContext.js";
2
+ export declare function useBuildScheduledEmailManagementDialogContext(): IScheduledEmailManagementDialogContextValue;
3
+ //# sourceMappingURL=useBuildScheduledEmailManagementDialogContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useBuildScheduledEmailManagementDialogContext.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/automations/connectors/hooks/useBuildScheduledEmailManagementDialogContext.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,2CAA2C,EAAE,MAAM,yDAAyD,CAAC;AAE3H,wBAAgB,6CAA6C,IAAI,2CAA2C,CAkC3G"}
@@ -0,0 +1,38 @@
1
+ // (C) 2026 GoodData Corporation
2
+ import { useMemo } from "react";
3
+ import { useDashboardSelector } from "../../../../model/react/DashboardStoreProvider.js";
4
+ import { DEFAULT_MAX_AUTOMATIONS } from "../../../../model/react/useDashboardAutomations/constants.js";
5
+ import { selectEnableAccessibilityMode, selectIsEmbedded, } from "../../../../model/store/config/configSelectors.js";
6
+ import { selectEntitlementMaxAutomations, selectEntitlementUnlimitedAutomations, } from "../../../../model/store/entitlements/entitlementsSelectors.js";
7
+ import { selectDashboardId, selectDashboardTitle } from "../../../../model/store/meta/metaSelectors.js";
8
+ import { selectAutomationsInvalidationId, selectIsScheduleEmailDialogOpen, } from "../../../../model/store/ui/uiSelectors.js";
9
+ export function useBuildScheduledEmailManagementDialogContext() {
10
+ const isScheduleEmailDialogOpen = useDashboardSelector(selectIsScheduleEmailDialogOpen);
11
+ const automationsInvalidationId = useDashboardSelector(selectAutomationsInvalidationId);
12
+ const isEmbedded = useDashboardSelector(selectIsEmbedded);
13
+ const enableAccessibilityMode = useDashboardSelector(selectEnableAccessibilityMode);
14
+ const dashboardId = useDashboardSelector(selectDashboardId);
15
+ const dashboardTitle = useDashboardSelector(selectDashboardTitle);
16
+ const maxAutomationsEntitlement = useDashboardSelector(selectEntitlementMaxAutomations);
17
+ const unlimitedAutomations = !!useDashboardSelector(selectEntitlementUnlimitedAutomations);
18
+ const maxAutomations = parseInt(maxAutomationsEntitlement?.value ?? DEFAULT_MAX_AUTOMATIONS, 10);
19
+ return useMemo(() => ({
20
+ isScheduleEmailDialogOpen,
21
+ automationsInvalidationId,
22
+ isEmbedded,
23
+ enableAccessibilityMode,
24
+ dashboardId,
25
+ dashboardTitle,
26
+ maxAutomations,
27
+ unlimitedAutomations,
28
+ }), [
29
+ isScheduleEmailDialogOpen,
30
+ automationsInvalidationId,
31
+ isEmbedded,
32
+ enableAccessibilityMode,
33
+ dashboardId,
34
+ dashboardTitle,
35
+ maxAutomations,
36
+ unlimitedAutomations,
37
+ ]);
38
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=useBuildScheduledEmailManagementDialogContext.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useBuildScheduledEmailManagementDialogContext.test.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/automations/connectors/hooks/useBuildScheduledEmailManagementDialogContext.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,42 @@
1
+ // (C) 2026 GoodData Corporation
2
+ import { renderHook } from "@testing-library/react";
3
+ import { describe, expect, it, vi } from "vitest";
4
+ // ---------------------------------------------------------------------------
5
+ // Mocks
6
+ // ---------------------------------------------------------------------------
7
+ vi.mock("../../../../model/react/DashboardStoreProvider.js", () => ({
8
+ useDashboardSelector: vi.fn((selector) => selector()),
9
+ }));
10
+ vi.mock("../../../../model/store/config/configSelectors.js", () => ({
11
+ selectEnableAccessibilityMode: () => false,
12
+ selectIsEmbedded: () => false,
13
+ }));
14
+ vi.mock("../../../../model/store/meta/metaSelectors.js", () => ({
15
+ selectDashboardId: () => "dashboard-id",
16
+ selectDashboardTitle: () => "Dashboard Title",
17
+ }));
18
+ vi.mock("../../../../model/store/entitlements/entitlementsSelectors.js", () => ({
19
+ selectEntitlementMaxAutomations: () => ({ value: "10" }),
20
+ selectEntitlementUnlimitedAutomations: () => undefined,
21
+ }));
22
+ vi.mock("../../../../model/store/ui/uiSelectors.js", () => ({
23
+ selectIsScheduleEmailDialogOpen: () => false,
24
+ selectAutomationsInvalidationId: () => 42,
25
+ }));
26
+ import { useBuildScheduledEmailManagementDialogContext } from "./useBuildScheduledEmailManagementDialogContext.js";
27
+ // ---------------------------------------------------------------------------
28
+ // Tests
29
+ // ---------------------------------------------------------------------------
30
+ describe("useBuildScheduledEmailManagementDialogContext", () => {
31
+ it("returns store-derived fields correctly", () => {
32
+ const { result } = renderHook(() => useBuildScheduledEmailManagementDialogContext());
33
+ expect(result.current.isScheduleEmailDialogOpen).toBe(false);
34
+ expect(result.current.automationsInvalidationId).toBe(42);
35
+ expect(result.current.isEmbedded).toBe(false);
36
+ expect(result.current.enableAccessibilityMode).toBe(false);
37
+ expect(result.current.dashboardId).toBe("dashboard-id");
38
+ expect(result.current.dashboardTitle).toBe("Dashboard Title");
39
+ expect(result.current.maxAutomations).toBe(10);
40
+ expect(result.current.unlimitedAutomations).toBe(false);
41
+ });
42
+ });
@@ -58,7 +58,6 @@ export interface IAutomationsContextValue {
58
58
  enableAutomationManagement: boolean;
59
59
  canUseAiAssistant: boolean;
60
60
  enableComparisonInAlerting: boolean;
61
- enableExternalRecipients: boolean;
62
61
  enableAlertAttributes: boolean;
63
62
  canManageWorkspace: boolean;
64
63
  enableCustomizableCsvDelimiter: boolean;
@@ -66,6 +65,18 @@ export interface IAutomationsContextValue {
66
65
  };
67
66
  getCatalogAttributeByRef: (ref: ObjRef) => ICatalogAttribute | ICatalogDateAttribute | undefined;
68
67
  getAttributeFilterDisplayForm: (displayForm: ObjRef) => IAttributeDisplayFormMetadataObject | undefined;
68
+ /**
69
+ * Element ID to return focus to when the scheduled-email dialog closes.
70
+ * Shared by both the create/edit dialog and the management dialog tree via
71
+ * useScheduleEmailDialogAccessibility.
72
+ */
73
+ scheduleEmailDialogReturnFocusTo?: string;
74
+ /**
75
+ * Returns true when a widget with the given ref still exists on the dashboard layout.
76
+ * Bridges identifier↔URI mismatches the same way as selectWidgetByRef.
77
+ * NOTE: do NOT narrow to isWidget() here — this is a pure existence check on the ObjRefMap.
78
+ */
79
+ widgetExistsByRef: (ref: ObjRef | undefined) => boolean;
69
80
  }
70
81
  export declare const AutomationsContextProvider: import("react").Provider<IAutomationsContextValue | undefined>;
71
82
  export declare function useAutomationsContext(): IAutomationsContextValue;
@@ -1 +1 @@
1
- {"version":3,"file":"AutomationsContext.d.ts","sourceRoot":"","sources":["../../../../src/presentation/automations/contexts/AutomationsContext.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AutomationsContext.d.ts","sourceRoot":"","sources":["../../../../src/presentation/automations/contexts/AutomationsContext.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACR,qCAAqC,EACrC,qBAAqB,EACrB,iBAAiB,EACjB,mCAAmC,EACnC,iBAAiB,EACjB,qBAAqB,EACrB,mBAAmB,EACnB,eAAe,EACf,+BAA+B,EAC/B,0BAA0B,EAC1B,8BAA8B,EAC9B,kCAAkC,EAClC,WAAW,EACX,SAAS,EACT,KAAK,EACL,MAAM,EACN,SAAS,EACZ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AAEzE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AAErF;;;GAGG;AACH,MAAM,WAAW,4BAA4B;IACzC,sBAAsB,EAAE,qBAAqB,EAAE,CAAC;IAChD,iBAAiB,EAAE,wBAAwB,CAAC;IAC5C,sBAAsB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,qBAAqB,EAAE,CAAC;IACnE,gBAAgB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,wBAAwB,GAAG,SAAS,CAAC;CAC7E;AAED;;;GAGG;AACH,MAAM,WAAW,wBAAwB;IACrC,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,WAAW,CAAC;IACxB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,iBAAiB,EAAE,iBAAiB,EAAE,CAAC;IACvC,mBAAmB,EAAE,mBAAmB,EAAE,CAAC;IAC3C,eAAe,EAAE,eAAe,EAAE,CAAC;IACnC,gBAAgB,EAAE,4BAA4B,CAAC;IAC/C,uBAAuB,EAAE,0BAA0B,GAAG,SAAS,CAAC;IAChE,sBAAsB,EAAE,+BAA+B,EAAE,CAAC;IAC1D,2BAA2B,EAAE,MAAM,CAAC,MAAM,EAAE,+BAA+B,EAAE,CAAC,CAAC;IAC/E,+BAA+B,EAAE,GAAG,CAAC,MAAM,EAAE,qCAAqC,GAAG,SAAS,CAAC,CAAC;IAChG,oCAAoC,EAAE,MAAM,CACxC,MAAM,EACN,GAAG,CAAC,MAAM,EAAE,qCAAqC,GAAG,SAAS,CAAC,CACjE,CAAC;IACF,iBAAiB,EAAE,8BAA8B,EAAE,CAAC;IACpD,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,8BAA8B,EAAE,CAAC,CAAC;IACzE,8BAA8B,EAAE,MAAM,CAAC,MAAM,EAAE,0BAA0B,GAAG,SAAS,CAAC,CAAC;IACvF,yBAAyB,EAAE,kCAAkC,EAAE,CAAC;IAChE,8BAA8B,EAAE,MAAM,CAAC,MAAM,EAAE,kCAAkC,EAAE,CAAC,CAAC;IACrF,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,aAAa,EAAE,iBAAiB,EAAE,CAAC;IACnC,aAAa,EAAE,iBAAiB,EAAE,CAAC;IACnC,gBAAgB,EAAE,iBAAiB,EAAE,CAAC;IACtC,sBAAsB,EAAE,qBAAqB,EAAE,CAAC;IAChD,sBAAsB,EAAE,iBAAiB,EAAE,CAAC;IAC5C,0BAA0B,EAAE,iBAAiB,EAAE,CAAC;IAChD,wBAAwB,EAAE,OAAO,CAAC;IAClC,wBAAwB,EAAE,MAAM,CAAC;IACjC,wBAAwB,EAAE,OAAO,CAAC;IAClC,qBAAqB,EAAE,OAAO,CAAC;IAC/B,WAAW,EAAE,KAAK,CAAC;IACnB,SAAS,EAAE,SAAS,CAAC;IACrB,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,cAAc,EAAE,OAAO,CAAC;IACxB,uBAAuB,EAAE,OAAO,CAAC;IACjC,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,EAAE;QACN,mBAAmB,EAAE,OAAO,CAAC;QAC7B,0BAA0B,EAAE,OAAO,CAAC;QACpC,2BAA2B,EAAE,OAAO,CAAC;QACrC,0BAA0B,EAAE,OAAO,CAAC;QACpC,iBAAiB,EAAE,OAAO,CAAC;QAC3B,0BAA0B,EAAE,OAAO,CAAC;QACpC,qBAAqB,EAAE,OAAO,CAAC;QAC/B,kBAAkB,EAAE,OAAO,CAAC;QAC5B,8BAA8B,EAAE,OAAO,CAAC;QACxC,8BAA8B,EAAE,OAAO,CAAC;KAC3C,CAAC;IACF,wBAAwB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,iBAAiB,GAAG,qBAAqB,GAAG,SAAS,CAAC;IACjG,6BAA6B,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,mCAAmC,GAAG,SAAS,CAAC;IACxG;;;;OAIG;IACH,gCAAgC,CAAC,EAAE,MAAM,CAAC;IAC1C;;;;OAIG;IACH,iBAAiB,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,KAAK,OAAO,CAAC;CAC3D;AAID,eAAO,MAAM,0BAA0B,gEAA8B,CAAC;AAEtE,wBAAgB,qBAAqB,IAAI,wBAAwB,CAWhE"}
@@ -1,4 +1,4 @@
1
- import type { DashboardAttributeFilterConfigMode, DashboardDateFilterConfigMode, FilterContextItem, IAutomationMetadataObject, IAutomationMetadataObjectDefinition, IDashboardExportParameter, IExportTemplate, IInsight, IWidget, ObjRef } from "@gooddata/sdk-model";
1
+ import type { DashboardAttributeFilterConfigMode, DashboardDateFilterConfigMode, FilterContextItem, IAutomationMetadataObject, IAutomationMetadataObjectDefinition, IDashboardExportParameter, IExportTemplate, IInsight, IWidget } from "@gooddata/sdk-model";
2
2
  /**
3
3
  * Sub-context for the scheduled-email create/edit dialog.
4
4
  * Shape grows during Phase 2 migration as DefaultScheduledEmailDialog and its hooks are migrated.
@@ -34,11 +34,6 @@ export interface IScheduledEmailDialogContextValue {
34
34
  isCrossFiltering: boolean;
35
35
  /** Whether the dashboard has more than one tab; derived from selectTabs. */
36
36
  hasMultipleTabs: boolean;
37
- /**
38
- * Returns true when a widget with the given ref still exists on the dashboard layout.
39
- * Bridges identifier↔URI mismatches the same way as selectWidgetByRef.
40
- */
41
- widgetExistsByRef: (ref: ObjRef | undefined) => boolean;
42
37
  /** Effective mode for the common (dashboard-level) date filter. */
43
38
  commonDateFilterMode: DashboardDateFilterConfigMode;
44
39
  /** Effective mode map for per-dataset date filters (localIdentifier → mode). */
@@ -1 +1 @@
1
- {"version":3,"file":"ScheduledEmailDialogContext.d.ts","sourceRoot":"","sources":["../../../../src/presentation/automations/contexts/ScheduledEmailDialogContext.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACR,kCAAkC,EAClC,6BAA6B,EAC7B,iBAAiB,EACjB,yBAAyB,EACzB,mCAAmC,EACnC,yBAAyB,EACzB,eAAe,EACf,QAAQ,EACR,OAAO,EACP,MAAM,EACT,MAAM,qBAAqB,CAAC;AAE7B;;;;GAIG;AACH,MAAM,WAAW,iCAAiC;IAC9C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,QAAQ,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACvC;;;OAGG;IACH,aAAa,EAAE,iBAAiB,EAAE,CAAC;IACnC,uBAAuB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;OAGG;IACH,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,yBAAyB,EAAE,CAAC,CAAC;IACnE;;;OAGG;IACH,eAAe,EAAE,eAAe,EAAE,CAAC;IACnC,wEAAwE;IACxE,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,uFAAuF;IACvF,gBAAgB,EAAE,OAAO,CAAC;IAC1B,4EAA4E;IAC5E,eAAe,EAAE,OAAO,CAAC;IACzB;;;OAGG;IACH,iBAAiB,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,KAAK,OAAO,CAAC;IACxD,mEAAmE;IACnE,oBAAoB,EAAE,6BAA6B,CAAC;IACpD,kFAAgF;IAChF,kBAAkB,EAAE,GAAG,CAAC,MAAM,EAAE,6BAA6B,CAAC,CAAC;IAC/D,2EAAyE;IACzE,uBAAuB,EAAE,GAAG,CAAC,MAAM,EAAE,kCAAkC,CAAC,CAAC;IAEzE,oBAAoB,CAAC,EAAE,EAAE,mCAAmC,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAClG,kBAAkB,CAAC,EAAE,EAAE,yBAAyB,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAC;IACtF,oBAAoB,CAAC,EAAE,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACtE;AAID,eAAO,MAAM,mCAAmC,yEAAuC,CAAC;AAExF,wBAAgB,8BAA8B,IAAI,iCAAiC,CAQlF"}
1
+ {"version":3,"file":"ScheduledEmailDialogContext.d.ts","sourceRoot":"","sources":["../../../../src/presentation/automations/contexts/ScheduledEmailDialogContext.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACR,kCAAkC,EAClC,6BAA6B,EAC7B,iBAAiB,EACjB,yBAAyB,EACzB,mCAAmC,EACnC,yBAAyB,EACzB,eAAe,EACf,QAAQ,EACR,OAAO,EACV,MAAM,qBAAqB,CAAC;AAE7B;;;;GAIG;AACH,MAAM,WAAW,iCAAiC;IAC9C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,QAAQ,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACvC;;;OAGG;IACH,aAAa,EAAE,iBAAiB,EAAE,CAAC;IACnC,uBAAuB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B;;;OAGG;IACH,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,yBAAyB,EAAE,CAAC,CAAC;IACnE;;;OAGG;IACH,eAAe,EAAE,eAAe,EAAE,CAAC;IACnC,wEAAwE;IACxE,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,uFAAuF;IACvF,gBAAgB,EAAE,OAAO,CAAC;IAC1B,4EAA4E;IAC5E,eAAe,EAAE,OAAO,CAAC;IACzB,mEAAmE;IACnE,oBAAoB,EAAE,6BAA6B,CAAC;IACpD,kFAAgF;IAChF,kBAAkB,EAAE,GAAG,CAAC,MAAM,EAAE,6BAA6B,CAAC,CAAC;IAC/D,2EAAyE;IACzE,uBAAuB,EAAE,GAAG,CAAC,MAAM,EAAE,kCAAkC,CAAC,CAAC;IAEzE,oBAAoB,CAAC,EAAE,EAAE,mCAAmC,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAClG,kBAAkB,CAAC,EAAE,EAAE,yBAAyB,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAC;IACtF,oBAAoB,CAAC,EAAE,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACtE;AAID,eAAO,MAAM,mCAAmC,yEAAuC,CAAC;AAExF,wBAAgB,8BAA8B,IAAI,iCAAiC,CAQlF"}