@gooddata/sdk-ui-dashboard 11.50.0-alpha.0 → 11.50.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 +216 -203
- package/esm/__version.d.ts +1 -1
- package/esm/__version.js +1 -1
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useEditScheduledEmail.d.ts +6 -6
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useEditScheduledEmail.d.ts.map +1 -1
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useEditScheduledEmail.js +65 -534
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailEffectiveFilters.d.ts +38 -0
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailEffectiveFilters.d.ts.map +1 -0
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailEffectiveFilters.js +61 -0
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailExportSettings.d.ts +57 -0
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailExportSettings.d.ts.map +1 -0
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailExportSettings.js +241 -0
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailFormState.d.ts +55 -0
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailFormState.d.ts.map +1 -0
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailFormState.js +203 -0
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailFormValidity.d.ts +21 -0
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailFormValidity.d.ts.map +1 -0
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailFormValidity.js +52 -0
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/utils/exportDefinitions.d.ts +27 -0
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/utils/exportDefinitions.d.ts.map +1 -0
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/utils/exportDefinitions.js +95 -0
- package/esm/presentation/filterBar/filterBar/DefaultFilterBarContainer.d.ts.map +1 -1
- package/esm/presentation/filterBar/filterBar/DefaultFilterBarContainer.js +11 -5
- package/esm/tsdoc-metadata.json +1 -1
- package/package.json +21 -21
- package/styles/css/main.css +1 -1
|
@@ -1,98 +1,53 @@
|
|
|
1
1
|
// (C) 2019-2026 GoodData Corporation
|
|
2
|
-
import { useCallback,
|
|
3
|
-
import {
|
|
4
|
-
import { invariant } from "ts-invariant";
|
|
5
|
-
import { DEFAULT_CSV_DELIMITER, insightProperties, isAutomationExternalUserRecipient, isAutomationUnknownUserRecipient, isAutomationUserRecipient, isExportDefinitionDashboardRequestPayload, isExportDefinitionVisualizationObjectRequestPayload, isInsightWidget, } from "@gooddata/sdk-model";
|
|
2
|
+
import { useCallback, useRef } from "react";
|
|
3
|
+
import { DEFAULT_CSV_DELIMITER, isExportDefinitionDashboardRequestPayload, isExportDefinitionVisualizationObjectRequestPayload, isInsightWidget, } from "@gooddata/sdk-model";
|
|
6
4
|
import { getAutomationExportParametersByTab, setExportParametersByTab, } from "../../../../../_staging/automation/index.js";
|
|
7
5
|
import { useAutomationsContext } from "../../../contexts/AutomationsContext.js";
|
|
8
6
|
import { useScheduledEmailDialogContext } from "../../../contexts/ScheduledEmailDialogContext.js";
|
|
9
|
-
import { shouldStoreExportParameters } from "../../../shared/automationFilters/automationParameters.js";
|
|
10
7
|
import { getDefaultSelectedFiltersFromFiltersByTab } from "../../../shared/automationFilters/useAutomationFiltersSelect.js";
|
|
11
8
|
import { getAppliedDashboardFilters, getAppliedWidgetFilters, getVisibleFiltersByFilters, getVisibleFiltersByFiltersByTab, } from "../../../shared/automationFilters/utils.js";
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
9
|
+
import { toNormalizedStartDate } from "../../utils/date.js";
|
|
10
|
+
import { useScheduledEmailEffectiveFilters } from "./useScheduledEmailEffectiveFilters.js";
|
|
11
|
+
import { useScheduledEmailExportSettings } from "./useScheduledEmailExportSettings.js";
|
|
12
|
+
import { useScheduledEmailFormState } from "./useScheduledEmailFormState.js";
|
|
13
|
+
import { useScheduledEmailFormValidity } from "./useScheduledEmailFormValidity.js";
|
|
17
14
|
export function useEditScheduledEmail({ scheduledExportToEdit, notificationChannels, insight, widget, users, editedAutomationFilters, dashboardFilters, editedAutomationFiltersByTab, maxAutomationsRecipients, setEditedAutomationFilters, setEditedAutomationFiltersByTab, availableFiltersAsVisibleFilters, storeFilters, setStoreFilters, filtersForNewAutomation, externalRecipientOverride, defaultPdfPageSize, filtersDataByTab, availableFiltersAsVisibleFiltersByTab, }) {
|
|
18
|
-
const
|
|
19
|
-
const {
|
|
20
|
-
const { dashboardId, dashboardTitle, hiddenFilters: dashboardHiddenFilters, commonDateFilterId, widgetLocalIdToTabIdMap: widgetTabMap, exportParametersByTab: effectiveExportParametersByTab, } = useScheduledEmailDialogContext();
|
|
21
|
-
const [isCronValid, setIsCronValid] = useState(true);
|
|
22
|
-
const [isTitleValid, setIsTitleValid] = useState(true);
|
|
23
|
-
const [isSubjectValid, setIsSubjectValid] = useState(true);
|
|
24
|
-
const [isOnMessageValid, setIsOnMessageValid] = useState(true);
|
|
15
|
+
const { settings, features: { enableAutomationEvaluationMode }, } = useAutomationsContext();
|
|
16
|
+
const { dashboardId, dashboardTitle, hiddenFilters: dashboardHiddenFilters, commonDateFilterId, widgetLocalIdToTabIdMap: widgetTabMap, } = useScheduledEmailDialogContext();
|
|
25
17
|
const isWidget = !!widget && !!insight;
|
|
26
18
|
// Dashboard
|
|
27
19
|
const resolvedDefaultCsvDelimiter = settings?.exportCsvCustomDelimiter ?? DEFAULT_CSV_DELIMITER;
|
|
28
20
|
const areDashboardFiltersChanged = !!dashboardFilters;
|
|
29
|
-
const defaultUser = convertCurrentUserToWorkspaceUser(users ?? [], currentUser);
|
|
30
|
-
const defaultRecipient = externalRecipientOverride
|
|
31
|
-
? convertExternalRecipientToAutomationRecipient(externalRecipientOverride)
|
|
32
|
-
: convertCurrentUserToAutomationRecipient(users ?? [], currentUser);
|
|
33
|
-
const firstChannel = notificationChannels[0]?.id;
|
|
34
21
|
// Determine target tab ID if widget is present
|
|
35
22
|
const targetTabId = widget?.localIdentifier ? widgetTabMap[widget.localIdentifier] : undefined;
|
|
36
|
-
const effectiveWidgetFilters
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
newAutomationMetadataObjectDefinition(isWidget
|
|
65
|
-
? {
|
|
66
|
-
timezone,
|
|
67
|
-
dashboardId: dashboardId,
|
|
68
|
-
notificationChannel: firstChannel,
|
|
69
|
-
insight,
|
|
70
|
-
widget,
|
|
71
|
-
recipient: defaultRecipient,
|
|
72
|
-
widgetFilters: effectiveWidgetFilters,
|
|
73
|
-
widgetFiltersWithInsight: effectiveWidgetFiltersWithInsight,
|
|
74
|
-
dashboardFilters: effectiveDashboardFilters,
|
|
75
|
-
visibleFiltersMetadata: effectiveVisibleWidgetFilters,
|
|
76
|
-
defaultPdfPageSize,
|
|
77
|
-
evaluationMode: "PER_RECIPIENT",
|
|
78
|
-
targetTabId,
|
|
79
|
-
parametersByTab: parametersByTabForNewAutomation,
|
|
80
|
-
}
|
|
81
|
-
: {
|
|
82
|
-
timezone,
|
|
83
|
-
dashboardId: dashboardId,
|
|
84
|
-
notificationChannel: firstChannel,
|
|
85
|
-
title: dashboardTitle,
|
|
86
|
-
recipient: defaultRecipient,
|
|
87
|
-
dashboardFilters: effectiveDashboardFilters,
|
|
88
|
-
filtersByTab: effectiveDashboardFiltersByTab,
|
|
89
|
-
visibleFiltersMetadata: effectiveVisibleDashboardFilters,
|
|
90
|
-
visibleFiltersByTab: effectiveVisibleDashboardFiltersByTab,
|
|
91
|
-
defaultPdfPageSize,
|
|
92
|
-
evaluationMode: "PER_RECIPIENT",
|
|
93
|
-
parametersByTab: parametersByTabForNewAutomation,
|
|
94
|
-
}));
|
|
95
|
-
const [originalAutomation] = useState(editedAutomation);
|
|
23
|
+
const { effectiveWidgetFilters, effectiveWidgetFiltersWithInsight, effectiveVisibleWidgetFilters, effectiveDashboardFilters, effectiveDashboardFiltersByTab, effectiveVisibleDashboardFilters, effectiveVisibleDashboardFiltersByTab, parametersByTabForNewAutomation, } = useScheduledEmailEffectiveFilters({
|
|
24
|
+
widget,
|
|
25
|
+
insight,
|
|
26
|
+
editedAutomationFilters,
|
|
27
|
+
editedAutomationFiltersByTab,
|
|
28
|
+
availableFiltersAsVisibleFilters,
|
|
29
|
+
availableFiltersAsVisibleFiltersByTab,
|
|
30
|
+
filtersDataByTab,
|
|
31
|
+
storeFilters,
|
|
32
|
+
});
|
|
33
|
+
const { editedAutomation, setEditedAutomation, originalAutomation, defaultRecipient, defaultUser, onTitleChange, onRecurrenceChange, onEvaluationModeChange, onDestinationChange, onRecipientsChange, onSubjectChange, onMessageChange, isCronValid, isTitleValid, isSubjectValid, isOnMessageValid, } = useScheduledEmailFormState({
|
|
34
|
+
scheduledExportToEdit,
|
|
35
|
+
widget,
|
|
36
|
+
insight,
|
|
37
|
+
notificationChannels,
|
|
38
|
+
users,
|
|
39
|
+
externalRecipientOverride,
|
|
40
|
+
effectiveWidgetFilters,
|
|
41
|
+
effectiveWidgetFiltersWithInsight,
|
|
42
|
+
effectiveVisibleWidgetFilters,
|
|
43
|
+
effectiveDashboardFilters,
|
|
44
|
+
effectiveDashboardFiltersByTab,
|
|
45
|
+
effectiveVisibleDashboardFilters,
|
|
46
|
+
effectiveVisibleDashboardFiltersByTab,
|
|
47
|
+
parametersByTabForNewAutomation,
|
|
48
|
+
defaultPdfPageSize,
|
|
49
|
+
targetTabId,
|
|
50
|
+
});
|
|
96
51
|
// Holds the wire outside the automation so it survives a rebuild from zero export definitions —
|
|
97
52
|
// with no definitions `setExportParametersByTab` has nowhere to store it.
|
|
98
53
|
// Seeded from the stored wire.
|
|
@@ -103,213 +58,23 @@ export function useEditScheduledEmail({ scheduledExportToEdit, notificationChann
|
|
|
103
58
|
const setParametersWire = useCallback((wire) => {
|
|
104
59
|
latestParametersWireRef.current = wire;
|
|
105
60
|
setEditedAutomation((automation) => setExportParametersByTab(automation, wire));
|
|
106
|
-
}, []);
|
|
107
|
-
const selectedAttachments = useMemo(() => {
|
|
108
|
-
return (editedAutomation.exportDefinitions
|
|
109
|
-
?.map((exportDefinition) => exportDefinition.requestPayload.format)
|
|
110
|
-
.filter(Boolean) ?? []);
|
|
111
|
-
}, [editedAutomation.exportDefinitions]);
|
|
112
|
-
const onTitleChange = (value, isValid) => {
|
|
113
|
-
setIsTitleValid(isValid);
|
|
114
|
-
setEditedAutomation((s) => ({ ...s, title: value }));
|
|
115
|
-
};
|
|
116
|
-
const onRecurrenceChange = (cronExpression, startDate, isValid) => {
|
|
117
|
-
setIsCronValid(isValid);
|
|
118
|
-
setEditedAutomation((s) => ({
|
|
119
|
-
...s,
|
|
120
|
-
schedule: {
|
|
121
|
-
...s.schedule,
|
|
122
|
-
cron: cronExpression,
|
|
123
|
-
firstRun: toModifiedISOStringToTimezone(startDate ?? new Date(), timezone).iso,
|
|
124
|
-
},
|
|
125
|
-
}));
|
|
126
|
-
};
|
|
127
|
-
const onEvaluationModeChange = (isShared) => {
|
|
128
|
-
setEditedAutomation((s) => ({
|
|
129
|
-
...s,
|
|
130
|
-
evaluationMode: isShared ? "SHARED" : "PER_RECIPIENT",
|
|
131
|
-
}));
|
|
132
|
-
};
|
|
133
|
-
const onDestinationChange = (notificationChannelId) => {
|
|
134
|
-
setEditedAutomation((s) => ({
|
|
135
|
-
...s,
|
|
136
|
-
notificationChannel: notificationChannelId,
|
|
137
|
-
}));
|
|
138
|
-
};
|
|
139
|
-
const onRecipientsChange = (updatedRecipients) => {
|
|
140
|
-
setEditedAutomation((s) => ({
|
|
141
|
-
...s,
|
|
142
|
-
recipients: updatedRecipients,
|
|
143
|
-
}));
|
|
144
|
-
};
|
|
145
|
-
const onSubjectChange = (value, isValid) => {
|
|
146
|
-
setIsSubjectValid(isValid);
|
|
147
|
-
setEditedAutomation((s) => ({
|
|
148
|
-
...s,
|
|
149
|
-
details: {
|
|
150
|
-
...s.details,
|
|
151
|
-
subject: value,
|
|
152
|
-
},
|
|
153
|
-
}));
|
|
154
|
-
};
|
|
155
|
-
const onMessageChange = (value, isValid) => {
|
|
156
|
-
setIsOnMessageValid(isValid);
|
|
157
|
-
setEditedAutomation((s) => ({
|
|
158
|
-
...s,
|
|
159
|
-
details: {
|
|
160
|
-
...s.details,
|
|
161
|
-
message: value,
|
|
162
|
-
},
|
|
163
|
-
}));
|
|
164
|
-
};
|
|
165
|
-
const onDashboardAttachmentsChange = (formats) => {
|
|
166
|
-
setEditedAutomation((s) => {
|
|
167
|
-
const currentExportDefinitions = s.exportDefinitions || [];
|
|
168
|
-
const currentDashboardExportDefinitions = currentExportDefinitions.filter((exportDefinition) => isExportDefinitionDashboardRequestPayload(exportDefinition.requestPayload));
|
|
169
|
-
const currentFormats = currentDashboardExportDefinitions.map((exportDefinition) => exportDefinition.requestPayload.format);
|
|
170
|
-
const formatsToKeep = currentFormats.filter((format) => formats.includes(format));
|
|
171
|
-
const formatsToAdd = formats.filter((format) => !currentFormats.includes(format));
|
|
172
|
-
const keptExportDefinitions = currentDashboardExportDefinitions.filter((exportDefinition) => formatsToKeep.includes(exportDefinition.requestPayload.format));
|
|
173
|
-
const newExportDefinitions = formatsToAdd.map((format) => newDashboardExportDefinitionMetadataObjectDefinition({
|
|
174
|
-
dashboardId: dashboardId,
|
|
175
|
-
dashboardTitle,
|
|
176
|
-
dashboardFilters: storeFilters ? effectiveDashboardFilters : undefined,
|
|
177
|
-
filtersByTab: storeFilters ? effectiveDashboardFiltersByTab : undefined,
|
|
178
|
-
format,
|
|
179
|
-
}));
|
|
180
|
-
const updatedExportDefinitions = [...keptExportDefinitions, ...newExportDefinitions];
|
|
181
|
-
return withRebuiltExportDefinitions(s, updatedExportDefinitions, latestParametersWireRef.current);
|
|
182
|
-
});
|
|
183
|
-
};
|
|
184
|
-
const onWidgetAttachmentsChange = (formats) => {
|
|
185
|
-
invariant(isWidget, "Widget or insight is missing in scheduling dialog context.");
|
|
186
|
-
setEditedAutomation((s) => {
|
|
187
|
-
const currentExportDefinitions = s.exportDefinitions || [];
|
|
188
|
-
const currentWidgetExportDefinitions = currentExportDefinitions.filter((exportDefinition) => isExportDefinitionVisualizationObjectRequestPayload(exportDefinition.requestPayload));
|
|
189
|
-
const currentFormats = currentWidgetExportDefinitions.map((exportDefinition) => exportDefinition.requestPayload.format);
|
|
190
|
-
const formatsToKeep = currentFormats.filter((format) => formats.includes(format));
|
|
191
|
-
const formatsToAdd = formats.filter((format) => !currentFormats.includes(format));
|
|
192
|
-
const keptExportDefinitions = currentWidgetExportDefinitions.filter((exportDefinition) => formatsToKeep.includes(exportDefinition.requestPayload.format));
|
|
193
|
-
const newExportDefinitions = formatsToAdd.map((format) => newWidgetExportDefinitionMetadataObjectDefinition({
|
|
194
|
-
insight,
|
|
195
|
-
widget,
|
|
196
|
-
dashboardId: dashboardId,
|
|
197
|
-
format,
|
|
198
|
-
widgetFilters: effectiveWidgetFilters,
|
|
199
|
-
widgetFiltersWithInsight: effectiveWidgetFiltersWithInsight,
|
|
200
|
-
dashboardFilters: effectiveDashboardFilters,
|
|
201
|
-
defaultPdfPageSize,
|
|
202
|
-
}));
|
|
203
|
-
const updatedExportDefinitions = [...keptExportDefinitions, ...newExportDefinitions];
|
|
204
|
-
return withRebuiltExportDefinitions(s, updatedExportDefinitions, latestParametersWireRef.current);
|
|
205
|
-
});
|
|
206
|
-
};
|
|
207
|
-
const onXlsxSettingsChange = useCallback((settings) => {
|
|
208
|
-
setEditedAutomation((s) => ({
|
|
209
|
-
...s,
|
|
210
|
-
exportDefinitions: s.exportDefinitions?.map((exportDefinition) => {
|
|
211
|
-
if (exportDefinition.requestPayload.format !== "XLSX") {
|
|
212
|
-
return exportDefinition;
|
|
213
|
-
}
|
|
214
|
-
const nextSettings = {
|
|
215
|
-
...exportDefinition.requestPayload?.settings,
|
|
216
|
-
mergeHeaders: settings.mergeHeaders,
|
|
217
|
-
exportInfo: settings.exportInfo,
|
|
218
|
-
};
|
|
219
|
-
return {
|
|
220
|
-
...exportDefinition,
|
|
221
|
-
requestPayload: {
|
|
222
|
-
...exportDefinition.requestPayload,
|
|
223
|
-
settings: nextSettings,
|
|
224
|
-
},
|
|
225
|
-
};
|
|
226
|
-
}),
|
|
227
|
-
}));
|
|
228
|
-
}, [setEditedAutomation]);
|
|
229
|
-
const onPdfSettingsChange = useCallback((settings) => {
|
|
230
|
-
setEditedAutomation((s) => ({
|
|
231
|
-
...s,
|
|
232
|
-
exportDefinitions: s.exportDefinitions?.map((exportDefinition) => {
|
|
233
|
-
if (exportDefinition.requestPayload.format !== "PDF_TABULAR") {
|
|
234
|
-
return exportDefinition;
|
|
235
|
-
}
|
|
236
|
-
const nextSettings = {
|
|
237
|
-
...exportDefinition.requestPayload?.settings,
|
|
238
|
-
pageSize: settings.pageSize,
|
|
239
|
-
orientation: settings.orientation ?? "portrait",
|
|
240
|
-
exportInfo: settings.exportInfo,
|
|
241
|
-
};
|
|
242
|
-
return {
|
|
243
|
-
...exportDefinition,
|
|
244
|
-
requestPayload: {
|
|
245
|
-
...exportDefinition.requestPayload,
|
|
246
|
-
settings: nextSettings,
|
|
247
|
-
},
|
|
248
|
-
};
|
|
249
|
-
}),
|
|
250
|
-
}));
|
|
251
|
-
}, [setEditedAutomation]);
|
|
252
|
-
const onCsvSettingsChange = useCallback((settings) => {
|
|
253
|
-
setEditedAutomation((s) => ({
|
|
254
|
-
...s,
|
|
255
|
-
exportDefinitions: s.exportDefinitions?.map((exportDefinition) => {
|
|
256
|
-
if (exportDefinition.requestPayload.format !== "CSV") {
|
|
257
|
-
return exportDefinition;
|
|
258
|
-
}
|
|
259
|
-
return {
|
|
260
|
-
...exportDefinition,
|
|
261
|
-
requestPayload: {
|
|
262
|
-
...exportDefinition.requestPayload,
|
|
263
|
-
settings: {
|
|
264
|
-
...exportDefinition.requestPayload.settings,
|
|
265
|
-
delimiter: settings.delimiter,
|
|
266
|
-
},
|
|
267
|
-
},
|
|
268
|
-
};
|
|
269
|
-
}),
|
|
270
|
-
}));
|
|
271
61
|
}, [setEditedAutomation]);
|
|
272
|
-
const onCsvRawSettingsChange =
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
};
|
|
289
|
-
}),
|
|
290
|
-
}));
|
|
291
|
-
}, [setEditedAutomation]);
|
|
292
|
-
const onSlidesTemplateIdChange = useCallback((templateId, format) => {
|
|
293
|
-
setEditedAutomation((s) => ({
|
|
294
|
-
...s,
|
|
295
|
-
exportDefinitions: s.exportDefinitions?.map((exportDefinition) => {
|
|
296
|
-
const matchesFormat = exportDefinition.requestPayload.format === format;
|
|
297
|
-
const matchesType = isWidget
|
|
298
|
-
? isExportDefinitionVisualizationObjectRequestPayload(exportDefinition.requestPayload)
|
|
299
|
-
: isExportDefinitionDashboardRequestPayload(exportDefinition.requestPayload);
|
|
300
|
-
if (!matchesFormat || !matchesType) {
|
|
301
|
-
return exportDefinition;
|
|
302
|
-
}
|
|
303
|
-
return {
|
|
304
|
-
...exportDefinition,
|
|
305
|
-
requestPayload: {
|
|
306
|
-
...exportDefinition.requestPayload,
|
|
307
|
-
templateId,
|
|
308
|
-
},
|
|
309
|
-
};
|
|
310
|
-
}),
|
|
311
|
-
}));
|
|
312
|
-
}, [setEditedAutomation, isWidget]);
|
|
62
|
+
const { selectedAttachments, isDashboardExportSelected, isCsvExportSelected, isXlsxExportSelected, xlsxSettings, pdfSettings, csvSettings, csvRawSettings, slidesTemplateIds, onDashboardAttachmentsChange, onWidgetAttachmentsChange, onXlsxSettingsChange, onPdfSettingsChange, onCsvSettingsChange, onCsvRawSettingsChange, onSlidesTemplateIdChange, } = useScheduledEmailExportSettings({
|
|
63
|
+
editedAutomation,
|
|
64
|
+
setEditedAutomation,
|
|
65
|
+
insight,
|
|
66
|
+
widget,
|
|
67
|
+
dashboardId,
|
|
68
|
+
dashboardTitle,
|
|
69
|
+
storeFilters,
|
|
70
|
+
effectiveDashboardFilters,
|
|
71
|
+
effectiveDashboardFiltersByTab,
|
|
72
|
+
effectiveWidgetFilters,
|
|
73
|
+
effectiveWidgetFiltersWithInsight,
|
|
74
|
+
defaultPdfPageSize,
|
|
75
|
+
resolvedDefaultCsvDelimiter,
|
|
76
|
+
latestParametersWireRef,
|
|
77
|
+
});
|
|
313
78
|
const onFiltersChange = useCallback((filters, storeFiltersParam) => {
|
|
314
79
|
setEditedAutomationFilters(filters);
|
|
315
80
|
const shouldStoreFilters = storeFiltersParam ?? storeFilters;
|
|
@@ -474,101 +239,19 @@ export function useEditScheduledEmail({ scheduledExportToEdit, notificationChann
|
|
|
474
239
|
onFiltersChange(filters, value);
|
|
475
240
|
}
|
|
476
241
|
}, [onFiltersChange, onFiltersByTabChange, setStoreFilters]);
|
|
477
|
-
const isDashboardExportSelected = editedAutomation.exportDefinitions?.some((exportDefinition) => isExportDefinitionDashboardRequestPayload(exportDefinition.requestPayload)) ?? true;
|
|
478
|
-
const isCsvExportSelected = editedAutomation.exportDefinitions?.some((exportDefinition) => {
|
|
479
|
-
if (isExportDefinitionVisualizationObjectRequestPayload(exportDefinition.requestPayload)) {
|
|
480
|
-
return exportDefinition.requestPayload.format === "CSV";
|
|
481
|
-
}
|
|
482
|
-
return false;
|
|
483
|
-
}) ?? false;
|
|
484
|
-
const isXlsxExportSelected = editedAutomation.exportDefinitions?.some((exportDefinition) => {
|
|
485
|
-
if (isExportDefinitionVisualizationObjectRequestPayload(exportDefinition.requestPayload)) {
|
|
486
|
-
return exportDefinition.requestPayload.format === "XLSX";
|
|
487
|
-
}
|
|
488
|
-
return false;
|
|
489
|
-
}) ?? false;
|
|
490
|
-
const xlsxExportSettings = editedAutomation.exportDefinitions?.find((exportDefinition) => exportDefinition.requestPayload.format === "XLSX")?.requestPayload.settings;
|
|
491
|
-
const xlsxSettings = {
|
|
492
|
-
mergeHeaders: xlsxExportSettings?.mergeHeaders ?? true,
|
|
493
|
-
exportInfo: xlsxExportSettings?.exportInfo ?? true,
|
|
494
|
-
};
|
|
495
|
-
const pdfVisualizationSettings = editedAutomation.exportDefinitions?.find((exportDefinition) => isExportDefinitionVisualizationObjectRequestPayload(exportDefinition.requestPayload) &&
|
|
496
|
-
exportDefinition.requestPayload.format === "PDF_TABULAR")?.requestPayload.settings;
|
|
497
|
-
const pdfTabularSettings = pdfVisualizationSettings && "pageSize" in pdfVisualizationSettings
|
|
498
|
-
? pdfVisualizationSettings
|
|
499
|
-
: undefined;
|
|
500
|
-
const pdfSettings = {
|
|
501
|
-
pageSize: pdfTabularSettings?.pageSize ?? defaultPdfPageSize ?? "A4",
|
|
502
|
-
orientation: pdfTabularSettings?.orientation ?? "portrait",
|
|
503
|
-
exportInfo: pdfTabularSettings?.exportInfo ?? true,
|
|
504
|
-
};
|
|
505
|
-
const csvExportDefinition = editedAutomation.exportDefinitions?.find((exportDefinition) => isExportDefinitionVisualizationObjectRequestPayload(exportDefinition.requestPayload) &&
|
|
506
|
-
exportDefinition.requestPayload.format === "CSV");
|
|
507
|
-
const csvExportSettings = csvExportDefinition &&
|
|
508
|
-
isExportDefinitionVisualizationObjectRequestPayload(csvExportDefinition.requestPayload)
|
|
509
|
-
? csvExportDefinition.requestPayload.settings
|
|
510
|
-
: undefined;
|
|
511
|
-
const csvSettings = {
|
|
512
|
-
delimiter: csvExportSettings?.delimiter ?? resolvedDefaultCsvDelimiter,
|
|
513
|
-
};
|
|
514
|
-
const csvRawExportDefinition = editedAutomation.exportDefinitions?.find((exportDefinition) => isExportDefinitionVisualizationObjectRequestPayload(exportDefinition.requestPayload) &&
|
|
515
|
-
exportDefinition.requestPayload.format === "CSV_RAW");
|
|
516
|
-
const csvRawExportSettings = csvRawExportDefinition &&
|
|
517
|
-
isExportDefinitionVisualizationObjectRequestPayload(csvRawExportDefinition.requestPayload)
|
|
518
|
-
? csvRawExportDefinition.requestPayload.settings
|
|
519
|
-
: undefined;
|
|
520
|
-
const csvRawSettings = {
|
|
521
|
-
delimiter: csvRawExportSettings?.delimiter ?? resolvedDefaultCsvDelimiter,
|
|
522
|
-
};
|
|
523
|
-
// Extract templateId per slides format, scoped to the current dialog mode
|
|
524
|
-
const getTemplateIdForFormat = (format) => {
|
|
525
|
-
const def = editedAutomation.exportDefinitions?.find((ed) => ed.requestPayload.format === format &&
|
|
526
|
-
(isWidget
|
|
527
|
-
? isExportDefinitionVisualizationObjectRequestPayload(ed.requestPayload)
|
|
528
|
-
: isExportDefinitionDashboardRequestPayload(ed.requestPayload)));
|
|
529
|
-
return def?.requestPayload.templateId;
|
|
530
|
-
};
|
|
531
|
-
const slidesTemplateIds = {
|
|
532
|
-
PPTX: getTemplateIdForFormat("PPTX"),
|
|
533
|
-
PDF_SLIDES: getTemplateIdForFormat("PDF_SLIDES"),
|
|
534
|
-
PDF: getTemplateIdForFormat("PDF"),
|
|
535
|
-
};
|
|
536
242
|
const startDate = toNormalizedStartDate(editedAutomation.schedule?.firstRun, editedAutomation.schedule?.timezone);
|
|
537
|
-
const
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
const hasValidCreatorRecipient = allowOnlyLoggedUserRecipients
|
|
550
|
-
? editedAutomation.recipients?.length === 1 &&
|
|
551
|
-
editedAutomation.recipients[0].id === defaultRecipient.id
|
|
552
|
-
: true;
|
|
553
|
-
const hasNoUnknownRecipients = !editedAutomation.recipients?.some(isAutomationUnknownUserRecipient);
|
|
554
|
-
const hasDestination = !!editedAutomation.notificationChannel;
|
|
555
|
-
const respectsRecipientsLimit = (editedAutomation.recipients?.length ?? 0) <= maxAutomationsRecipients;
|
|
556
|
-
const hasFilledEmails = selectedNotificationChannel?.destinationType === "smtp"
|
|
557
|
-
? editedAutomation.recipients?.every((recipient) => isAutomationUserRecipient(recipient) ? isEmail(recipient.email ?? "") : true)
|
|
558
|
-
: true;
|
|
559
|
-
const isValid = isCronValid &&
|
|
560
|
-
hasRecipients &&
|
|
561
|
-
respectsRecipientsLimit &&
|
|
562
|
-
hasAttachments &&
|
|
563
|
-
hasDestination &&
|
|
564
|
-
hasValidExternalRecipients &&
|
|
565
|
-
hasValidCreatorRecipient &&
|
|
566
|
-
hasNoUnknownRecipients &&
|
|
567
|
-
hasFilledEmails &&
|
|
568
|
-
isOnMessageValid &&
|
|
569
|
-
isTitleValid &&
|
|
570
|
-
isSubjectValid;
|
|
571
|
-
const isSubmitDisabled = !isValid || (scheduledExportToEdit && areAutomationsEqual(originalAutomation, editedAutomation));
|
|
243
|
+
const { isSubmitDisabled, validationErrorMessage, isParentValid, allowExternalRecipients, allowOnlyLoggedUserRecipients, } = useScheduledEmailFormValidity({
|
|
244
|
+
editedAutomation,
|
|
245
|
+
originalAutomation,
|
|
246
|
+
scheduledExportToEdit,
|
|
247
|
+
notificationChannels,
|
|
248
|
+
defaultRecipient,
|
|
249
|
+
maxAutomationsRecipients,
|
|
250
|
+
isCronValid,
|
|
251
|
+
isTitleValid,
|
|
252
|
+
isSubjectValid,
|
|
253
|
+
isOnMessageValid,
|
|
254
|
+
});
|
|
572
255
|
return {
|
|
573
256
|
defaultUser,
|
|
574
257
|
areDashboardFiltersChanged,
|
|
@@ -614,155 +297,3 @@ export function useEditScheduledEmail({ scheduledExportToEdit, notificationChann
|
|
|
614
297
|
enableAutomationEvaluationMode,
|
|
615
298
|
};
|
|
616
299
|
}
|
|
617
|
-
/**
|
|
618
|
-
* Rebuilds the export definitions and re-applies the parameter wire (fresh definitions carry no
|
|
619
|
-
* `content.parametersByTab`). The wire is passed in rather than read off `automation` so it survives
|
|
620
|
-
* a rebuild from zero definitions — see `latestParametersWireRef`.
|
|
621
|
-
*/
|
|
622
|
-
function withRebuiltExportDefinitions(automation, exportDefinitions, parametersByTab) {
|
|
623
|
-
const next = { ...automation, exportDefinitions };
|
|
624
|
-
return parametersByTab ? setExportParametersByTab(next, parametersByTab) : next;
|
|
625
|
-
}
|
|
626
|
-
function newDashboardExportDefinitionMetadataObjectDefinition({ dashboardId, dashboardTitle, dashboardFilters, filtersByTab, format, templateId, }) {
|
|
627
|
-
// Use filtersByTab if provided, otherwise fall back to simple filters
|
|
628
|
-
const filtersObj = filtersByTab
|
|
629
|
-
? { filtersByTab }
|
|
630
|
-
: dashboardFilters
|
|
631
|
-
? { filters: dashboardFilters }
|
|
632
|
-
: {};
|
|
633
|
-
const settingsObj = format === "XLSX" ? { settings: { mergeHeaders: true, exportInfo: true } } : {};
|
|
634
|
-
return {
|
|
635
|
-
type: "exportDefinition",
|
|
636
|
-
title: dashboardTitle,
|
|
637
|
-
requestPayload: {
|
|
638
|
-
type: "dashboard",
|
|
639
|
-
fileName: dashboardTitle,
|
|
640
|
-
format,
|
|
641
|
-
content: {
|
|
642
|
-
dashboard: dashboardId,
|
|
643
|
-
...filtersObj,
|
|
644
|
-
},
|
|
645
|
-
...settingsObj,
|
|
646
|
-
...(templateId ? { templateId } : {}),
|
|
647
|
-
},
|
|
648
|
-
};
|
|
649
|
-
}
|
|
650
|
-
function newWidgetExportDefinitionMetadataObjectDefinition({ insight, widget, dashboardId, format, widgetFilters, widgetFiltersWithInsight, dashboardFilters, defaultPdfPageSize, defaultCsvDelimiter, }) {
|
|
651
|
-
const widgetTitle = widget.title;
|
|
652
|
-
// Determine which filters to use based on format:
|
|
653
|
-
// - CSV: Use widgetFiltersWithInsight (insight filters merged on frontend)
|
|
654
|
-
// - CSV_RAW: Use widgetFilters (insight filters merged on backend)
|
|
655
|
-
// - Other formats: Use dashboardFilters (backend handles insight filter merging)
|
|
656
|
-
const shouldUseCsvFilters = format === "CSV";
|
|
657
|
-
const shouldUseCsvRawFilters = format === "CSV_RAW";
|
|
658
|
-
let filtersObj = {};
|
|
659
|
-
if (shouldUseCsvFilters && (widgetFiltersWithInsight ?? []).length > 0) {
|
|
660
|
-
filtersObj = { filters: widgetFiltersWithInsight };
|
|
661
|
-
}
|
|
662
|
-
else if (shouldUseCsvRawFilters && (widgetFilters ?? []).length > 0) {
|
|
663
|
-
filtersObj = { filters: widgetFilters };
|
|
664
|
-
}
|
|
665
|
-
else if (!shouldUseCsvFilters && !shouldUseCsvRawFilters && (dashboardFilters ?? []).length > 0) {
|
|
666
|
-
filtersObj = { filters: dashboardFilters };
|
|
667
|
-
}
|
|
668
|
-
const grandTotalsPosition = insightProperties(insight)?.["controls"]?.["grandTotalsPosition"];
|
|
669
|
-
const pdfSettings = {
|
|
670
|
-
pageSize: defaultPdfPageSize ?? "A4",
|
|
671
|
-
orientation: "portrait",
|
|
672
|
-
exportInfo: true,
|
|
673
|
-
...(grandTotalsPosition ? { grandTotalsPosition } : {}),
|
|
674
|
-
};
|
|
675
|
-
const xlsxSettings = {
|
|
676
|
-
mergeHeaders: true,
|
|
677
|
-
exportInfo: true,
|
|
678
|
-
...(grandTotalsPosition ? { grandTotalsPosition } : {}),
|
|
679
|
-
};
|
|
680
|
-
const csvSettings = {
|
|
681
|
-
...(defaultCsvDelimiter ? { delimiter: defaultCsvDelimiter } : {}),
|
|
682
|
-
...(grandTotalsPosition ? { grandTotalsPosition } : {}),
|
|
683
|
-
};
|
|
684
|
-
const hasCsvSettings = Object.keys(csvSettings).length > 0;
|
|
685
|
-
const settingsObj = format === "XLSX"
|
|
686
|
-
? { settings: xlsxSettings }
|
|
687
|
-
: format === "PDF_TABULAR"
|
|
688
|
-
? { settings: pdfSettings }
|
|
689
|
-
: (format === "CSV" || format === "CSV_RAW") && hasCsvSettings
|
|
690
|
-
? { settings: csvSettings }
|
|
691
|
-
: {};
|
|
692
|
-
return {
|
|
693
|
-
type: "exportDefinition",
|
|
694
|
-
title: widgetTitle,
|
|
695
|
-
requestPayload: {
|
|
696
|
-
type: "visualizationObject",
|
|
697
|
-
fileName: widgetTitle,
|
|
698
|
-
format: format,
|
|
699
|
-
content: {
|
|
700
|
-
visualizationObject: insight.insight.identifier,
|
|
701
|
-
widget: widget.identifier,
|
|
702
|
-
dashboard: dashboardId,
|
|
703
|
-
...filtersObj,
|
|
704
|
-
},
|
|
705
|
-
...settingsObj,
|
|
706
|
-
},
|
|
707
|
-
};
|
|
708
|
-
}
|
|
709
|
-
function newAutomationMetadataObjectDefinition({ timezone, dashboardId, notificationChannel, title, insight, widget, recipient, dashboardFilters, filtersByTab, widgetFilters, widgetFiltersWithInsight, visibleFiltersMetadata, visibleFiltersByTab, defaultPdfPageSize, evaluationMode, targetTabId, parametersByTab, }) {
|
|
710
|
-
const { firstRun, cron } = toNormalizedFirstRunAndCron(timezone);
|
|
711
|
-
const exportDefinition = widget && insight
|
|
712
|
-
? newWidgetExportDefinitionMetadataObjectDefinition({
|
|
713
|
-
insight,
|
|
714
|
-
widget,
|
|
715
|
-
dashboardId,
|
|
716
|
-
format: "PNG",
|
|
717
|
-
widgetFilters,
|
|
718
|
-
widgetFiltersWithInsight,
|
|
719
|
-
dashboardFilters,
|
|
720
|
-
defaultPdfPageSize,
|
|
721
|
-
})
|
|
722
|
-
: newDashboardExportDefinitionMetadataObjectDefinition({
|
|
723
|
-
dashboardId,
|
|
724
|
-
dashboardTitle: title ?? "",
|
|
725
|
-
dashboardFilters,
|
|
726
|
-
filtersByTab,
|
|
727
|
-
format: "PDF",
|
|
728
|
-
});
|
|
729
|
-
let metadataObj = visibleFiltersMetadata || visibleFiltersByTab
|
|
730
|
-
? {
|
|
731
|
-
metadata: {
|
|
732
|
-
...(visibleFiltersMetadata ? { visibleFilters: visibleFiltersMetadata } : {}),
|
|
733
|
-
...(visibleFiltersByTab ? { visibleFiltersByTab } : {}),
|
|
734
|
-
},
|
|
735
|
-
}
|
|
736
|
-
: {};
|
|
737
|
-
if (targetTabId) {
|
|
738
|
-
metadataObj = {
|
|
739
|
-
...metadataObj,
|
|
740
|
-
metadata: {
|
|
741
|
-
...metadataObj.metadata,
|
|
742
|
-
targetTabIdentifier: targetTabId,
|
|
743
|
-
},
|
|
744
|
-
};
|
|
745
|
-
}
|
|
746
|
-
const automation = {
|
|
747
|
-
type: "automation",
|
|
748
|
-
title: undefined,
|
|
749
|
-
description: undefined,
|
|
750
|
-
tags: [],
|
|
751
|
-
schedule: {
|
|
752
|
-
timezone: timezone ?? getUserTimezone().identifier,
|
|
753
|
-
firstRun,
|
|
754
|
-
cron,
|
|
755
|
-
},
|
|
756
|
-
details: {
|
|
757
|
-
message: "",
|
|
758
|
-
subject: "",
|
|
759
|
-
},
|
|
760
|
-
exportDefinitions: [{ ...exportDefinition }],
|
|
761
|
-
recipients: [recipient],
|
|
762
|
-
evaluationMode,
|
|
763
|
-
notificationChannel,
|
|
764
|
-
dashboard: dashboardId ? { id: dashboardId } : undefined,
|
|
765
|
-
...metadataObj,
|
|
766
|
-
};
|
|
767
|
-
return parametersByTab ? setExportParametersByTab(automation, parametersByTab) : automation;
|
|
768
|
-
}
|