@gooddata/sdk-ui-dashboard 11.50.0-alpha.0 → 11.50.0-alpha.1

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 (15) hide show
  1. package/esm/__version.d.ts +1 -1
  2. package/esm/__version.js +1 -1
  3. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useEditScheduledEmail.d.ts +3 -3
  4. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useEditScheduledEmail.d.ts.map +1 -1
  5. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useEditScheduledEmail.js +33 -346
  6. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailExportSettings.d.ts +57 -0
  7. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailExportSettings.d.ts.map +1 -0
  8. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailExportSettings.js +241 -0
  9. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailFormValidity.d.ts +21 -0
  10. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailFormValidity.d.ts.map +1 -0
  11. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailFormValidity.js +52 -0
  12. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/utils/exportDefinitions.d.ts +27 -0
  13. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/utils/exportDefinitions.d.ts.map +1 -0
  14. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/utils/exportDefinitions.js +95 -0
  15. package/package.json +21 -21
@@ -1,4 +1,4 @@
1
- export declare const LIB_VERSION = "11.50.0-alpha.0";
1
+ export declare const LIB_VERSION = "11.50.0-alpha.1";
2
2
  export declare const LIB_DESCRIPTION = "GoodData SDK - Dashboard Component";
3
3
  export declare const LIB_NAME = "@gooddata/sdk-ui-dashboard";
4
4
  //# sourceMappingURL=__version.d.ts.map
package/esm/__version.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // (C) 2021 GoodData Corporation
2
2
  // DO NOT CHANGE THIS FILE, IT IS RE-GENERATED ON EVERY BUILD
3
- export const LIB_VERSION = "11.50.0-alpha.0";
3
+ export const LIB_VERSION = "11.50.0-alpha.1";
4
4
  export const LIB_DESCRIPTION = "GoodData SDK - Dashboard Component";
5
5
  export const LIB_NAME = "@gooddata/sdk-ui-dashboard";
@@ -1,4 +1,4 @@
1
- import { type DashboardAttachmentType, type FilterContextItem, type IAutomationMetadataObject, type IAutomationMetadataObjectDefinition, type IAutomationRecipient, type IAutomationVisibleFilter, type IDashboardExportParameter, type IExportDefinitionVisualizationObjectSettings, type IFilter, type IInsight, type INotificationChannelIdentifier, type INotificationChannelMetadataObject, type IWidget, type IWorkspaceUser, type WidgetAttachmentType } from "@gooddata/sdk-model";
1
+ import { type FilterContextItem, type IAutomationMetadataObject, type IAutomationMetadataObjectDefinition, type IAutomationRecipient, type IAutomationVisibleFilter, type IDashboardExportParameter, type IExportDefinitionVisualizationObjectSettings, type IFilter, type IInsight, type INotificationChannelIdentifier, type INotificationChannelMetadataObject, type IWidget, type IWorkspaceUser } from "@gooddata/sdk-model";
2
2
  import type { IAutomationFiltersTab } from "../../../../../model/store/filtering/types.js";
3
3
  export interface IUseEditScheduledEmailProps {
4
4
  scheduledExportToEdit?: IAutomationMetadataObject;
@@ -71,8 +71,8 @@ export declare function useEditScheduledEmail({ scheduledExportToEdit, notificat
71
71
  onRecipientsChange: (updatedRecipients: IAutomationRecipient[]) => void;
72
72
  onSubjectChange: (value: string | number, isValid: boolean) => void;
73
73
  onMessageChange: (value: string, isValid: boolean) => void;
74
- onDashboardAttachmentsChange: (formats: DashboardAttachmentType[]) => void;
75
- onWidgetAttachmentsChange: (formats: WidgetAttachmentType[]) => void;
74
+ onDashboardAttachmentsChange: (formats: import("@gooddata/sdk-model").DashboardAttachmentType[]) => void;
75
+ onWidgetAttachmentsChange: (formats: import("@gooddata/sdk-model").WidgetAttachmentType[]) => void;
76
76
  onXlsxSettingsChange: (settings: IExportDefinitionVisualizationObjectSettings) => void;
77
77
  onPdfSettingsChange: (settings: IExportDefinitionVisualizationObjectSettings) => void;
78
78
  onCsvSettingsChange: (settings: IExportDefinitionVisualizationObjectSettings) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"useEditScheduledEmail.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useEditScheduledEmail.ts"],"names":[],"mappings":"AAOA,OAAO,EAGH,KAAK,uBAAuB,EAC5B,KAAK,iBAAiB,EACtB,KAAK,yBAAyB,EAE9B,KAAK,mCAAmC,EACxC,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAE9B,KAAK,4CAA4C,EACjD,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,KAAK,8BAA8B,EACnC,KAAK,kCAAkC,EACvC,KAAK,OAAO,EACZ,KAAK,cAAc,EACnB,KAAK,oBAAoB,EAQ5B,MAAM,qBAAqB,CAAC;AAM7B,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,+CAA+C,CAAC;AA2B3F,MAAM,WAAW,2BAA2B;IACxC,qBAAqB,CAAC,EAAE,yBAAyB,CAAC;IAClD,oBAAoB,EAAE,8BAA8B,EAAE,GAAG,kCAAkC,EAAE,CAAC;IAC9F,wBAAwB,EAAE,MAAM,CAAC;IACjC,iFAAiF;IACjF,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,QAAQ,CAAC;IACnB,aAAa,CAAC,EAAE,OAAO,EAAE,CAAC;IAC1B,uBAAuB,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC9C,gBAAgB,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACvC,0BAA0B,EAAE,CAAC,OAAO,EAAE,iBAAiB,EAAE,KAAK,IAAI,CAAC;IAEnE;;;OAGG;IACH,4BAA4B,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC,CAAC;IACnE;;;OAGG;IACH,+BAA+B,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC,KAAK,IAAI,CAAC;IACzF,gBAAgB,CAAC,EAAE,qBAAqB,EAAE,GAAG,SAAS,CAAC;IACvD,gCAAgC,CAAC,EAAE,wBAAwB,EAAE,GAAG,SAAS,CAAC;IAC1E,qCAAqC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,EAAE,CAAC,CAAC;IAEnF,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,eAAe,EAAE,CAAC,YAAY,EAAE,OAAO,KAAK,IAAI,CAAC;IACjD,uBAAuB,EAAE,iBAAiB,EAAE,CAAC;IAC7C,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,kBAAkB,CAAC,EAAE,4CAA4C,CAAC,UAAU,CAAC,CAAC;CACjF;AAED,wBAAgB,qBAAqB,CAAC,EAClC,qBAAqB,EACrB,oBAAoB,EACpB,OAAO,EACP,MAAM,EACN,KAAK,EACL,uBAAuB,EACvB,gBAAgB,EAChB,4BAA4B,EAC5B,wBAAwB,EACxB,0BAA0B,EAC1B,+BAA+B,EAC/B,gCAAgC,EAChC,YAAY,EACZ,eAAe,EACf,uBAAuB,EACvB,yBAAyB,EACzB,kBAAkB,EAClB,gBAAgB,EAChB,qCAAqC,EACxC,EAAE,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAg2B7B"}
1
+ {"version":3,"file":"useEditScheduledEmail.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useEditScheduledEmail.ts"],"names":[],"mappings":"AAIA,OAAO,EAGH,KAAK,iBAAiB,EACtB,KAAK,yBAAyB,EAE9B,KAAK,mCAAmC,EACxC,KAAK,oBAAoB,EACzB,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,4CAA4C,EACjD,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,KAAK,8BAA8B,EACnC,KAAK,kCAAkC,EACvC,KAAK,OAAO,EACZ,KAAK,cAAc,EAItB,MAAM,qBAAqB,CAAC;AAM7B,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,+CAA+C,CAAC;AA8B3F,MAAM,WAAW,2BAA2B;IACxC,qBAAqB,CAAC,EAAE,yBAAyB,CAAC;IAClD,oBAAoB,EAAE,8BAA8B,EAAE,GAAG,kCAAkC,EAAE,CAAC;IAC9F,wBAAwB,EAAE,MAAM,CAAC;IACjC,iFAAiF;IACjF,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,QAAQ,CAAC;IACnB,aAAa,CAAC,EAAE,OAAO,EAAE,CAAC;IAC1B,uBAAuB,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC9C,gBAAgB,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACvC,0BAA0B,EAAE,CAAC,OAAO,EAAE,iBAAiB,EAAE,KAAK,IAAI,CAAC;IAEnE;;;OAGG;IACH,4BAA4B,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC,CAAC;IACnE;;;OAGG;IACH,+BAA+B,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC,KAAK,IAAI,CAAC;IACzF,gBAAgB,CAAC,EAAE,qBAAqB,EAAE,GAAG,SAAS,CAAC;IACvD,gCAAgC,CAAC,EAAE,wBAAwB,EAAE,GAAG,SAAS,CAAC;IAC1E,qCAAqC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,EAAE,CAAC,CAAC;IAEnF,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,eAAe,EAAE,CAAC,YAAY,EAAE,OAAO,KAAK,IAAI,CAAC;IACjD,uBAAuB,EAAE,iBAAiB,EAAE,CAAC;IAC7C,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,kBAAkB,CAAC,EAAE,4CAA4C,CAAC,UAAU,CAAC,CAAC;CACjF;AAED,wBAAgB,qBAAqB,CAAC,EAClC,qBAAqB,EACrB,oBAAoB,EACpB,OAAO,EACP,MAAM,EACN,KAAK,EACL,uBAAuB,EACvB,gBAAgB,EAChB,4BAA4B,EAC5B,wBAAwB,EACxB,0BAA0B,EAC1B,+BAA+B,EAC/B,gCAAgC,EAChC,YAAY,EACZ,eAAe,EACf,uBAAuB,EACvB,yBAAyB,EACzB,kBAAkB,EAClB,gBAAgB,EAChB,qCAAqC,EACxC,EAAE,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+iB7B"}
@@ -1,21 +1,19 @@
1
1
  // (C) 2019-2026 GoodData Corporation
2
2
  import { useCallback, useMemo, useRef, useState } from "react";
3
- import { useIntl } from "react-intl";
4
- import { invariant } from "ts-invariant";
5
- import { DEFAULT_CSV_DELIMITER, insightProperties, isAutomationExternalUserRecipient, isAutomationUnknownUserRecipient, isAutomationUserRecipient, isExportDefinitionDashboardRequestPayload, isExportDefinitionVisualizationObjectRequestPayload, isInsightWidget, } from "@gooddata/sdk-model";
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
7
  import { shouldStoreExportParameters } from "../../../shared/automationFilters/automationParameters.js";
10
8
  import { getDefaultSelectedFiltersFromFiltersByTab } from "../../../shared/automationFilters/useAutomationFiltersSelect.js";
11
9
  import { getAppliedDashboardFilters, getAppliedWidgetFilters, getVisibleFiltersByFilters, getVisibleFiltersByFiltersByTab, } from "../../../shared/automationFilters/utils.js";
12
- import { areAutomationsEqual, convertCurrentUserToAutomationRecipient, convertCurrentUserToWorkspaceUser, convertExternalRecipientToAutomationRecipient, } from "../../../shared/utils/automationUtils.js";
10
+ import { convertCurrentUserToAutomationRecipient, convertCurrentUserToWorkspaceUser, convertExternalRecipientToAutomationRecipient, } from "../../../shared/utils/automationUtils.js";
13
11
  import { toModifiedISOStringToTimezone, toNormalizedFirstRunAndCron, toNormalizedStartDate, } from "../../utils/date.js";
14
12
  import { getUserTimezone } from "../../utils/timezone.js";
15
- import { isEmail } from "../../utils/validate.js";
16
- import { useScheduleValidation } from "./useScheduleValidation.js";
13
+ import { newDashboardExportDefinitionMetadataObjectDefinition, newWidgetExportDefinitionMetadataObjectDefinition, } from "../utils/exportDefinitions.js";
14
+ import { useScheduledEmailExportSettings } from "./useScheduledEmailExportSettings.js";
15
+ import { useScheduledEmailFormValidity } from "./useScheduledEmailFormValidity.js";
17
16
  export function useEditScheduledEmail({ scheduledExportToEdit, notificationChannels, insight, widget, users, editedAutomationFilters, dashboardFilters, editedAutomationFiltersByTab, maxAutomationsRecipients, setEditedAutomationFilters, setEditedAutomationFiltersByTab, availableFiltersAsVisibleFilters, storeFilters, setStoreFilters, filtersForNewAutomation, externalRecipientOverride, defaultPdfPageSize, filtersDataByTab, availableFiltersAsVisibleFiltersByTab, }) {
18
- const intl = useIntl();
19
17
  const { settings, timezone, currentUser, features: { enableAutomationEvaluationMode }, } = useAutomationsContext();
20
18
  const { dashboardId, dashboardTitle, hiddenFilters: dashboardHiddenFilters, commonDateFilterId, widgetLocalIdToTabIdMap: widgetTabMap, exportParametersByTab: effectiveExportParametersByTab, } = useScheduledEmailDialogContext();
21
19
  const [isCronValid, setIsCronValid] = useState(true);
@@ -104,11 +102,6 @@ export function useEditScheduledEmail({ scheduledExportToEdit, notificationChann
104
102
  latestParametersWireRef.current = wire;
105
103
  setEditedAutomation((automation) => setExportParametersByTab(automation, wire));
106
104
  }, []);
107
- const selectedAttachments = useMemo(() => {
108
- return (editedAutomation.exportDefinitions
109
- ?.map((exportDefinition) => exportDefinition.requestPayload.format)
110
- .filter(Boolean) ?? []);
111
- }, [editedAutomation.exportDefinitions]);
112
105
  const onTitleChange = (value, isValid) => {
113
106
  setIsTitleValid(isValid);
114
107
  setEditedAutomation((s) => ({ ...s, title: value }));
@@ -162,154 +155,6 @@ export function useEditScheduledEmail({ scheduledExportToEdit, notificationChann
162
155
  },
163
156
  }));
164
157
  };
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
- }, [setEditedAutomation]);
272
- const onCsvRawSettingsChange = useCallback((settings) => {
273
- setEditedAutomation((s) => ({
274
- ...s,
275
- exportDefinitions: s.exportDefinitions?.map((exportDefinition) => {
276
- if (exportDefinition.requestPayload.format !== "CSV_RAW") {
277
- return exportDefinition;
278
- }
279
- return {
280
- ...exportDefinition,
281
- requestPayload: {
282
- ...exportDefinition.requestPayload,
283
- settings: {
284
- ...exportDefinition.requestPayload.settings,
285
- delimiter: settings.delimiter,
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]);
313
158
  const onFiltersChange = useCallback((filters, storeFiltersParam) => {
314
159
  setEditedAutomationFilters(filters);
315
160
  const shouldStoreFilters = storeFiltersParam ?? storeFilters;
@@ -474,101 +319,35 @@ export function useEditScheduledEmail({ scheduledExportToEdit, notificationChann
474
319
  onFiltersChange(filters, value);
475
320
  }
476
321
  }, [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
- };
322
+ const { selectedAttachments, isDashboardExportSelected, isCsvExportSelected, isXlsxExportSelected, xlsxSettings, pdfSettings, csvSettings, csvRawSettings, slidesTemplateIds, onDashboardAttachmentsChange, onWidgetAttachmentsChange, onXlsxSettingsChange, onPdfSettingsChange, onCsvSettingsChange, onCsvRawSettingsChange, onSlidesTemplateIdChange, } = useScheduledEmailExportSettings({
323
+ editedAutomation,
324
+ setEditedAutomation,
325
+ insight,
326
+ widget,
327
+ dashboardId,
328
+ dashboardTitle,
329
+ storeFilters,
330
+ effectiveDashboardFilters,
331
+ effectiveDashboardFiltersByTab,
332
+ effectiveWidgetFilters,
333
+ effectiveWidgetFiltersWithInsight,
334
+ defaultPdfPageSize,
335
+ resolvedDefaultCsvDelimiter,
336
+ latestParametersWireRef,
337
+ });
536
338
  const startDate = toNormalizedStartDate(editedAutomation.schedule?.firstRun, editedAutomation.schedule?.timezone);
537
- const selectedNotificationChannel = notificationChannels.find((channel) => channel.id === editedAutomation.notificationChannel);
538
- const allowExternalRecipients = selectedNotificationChannel?.allowedRecipients === "external";
539
- const allowOnlyLoggedUserRecipients = selectedNotificationChannel?.allowedRecipients === "creator";
540
- const { isValid: isParentValid } = useScheduleValidation(originalAutomation);
541
- const validationErrorMessage = isParentValid
542
- ? undefined
543
- : intl.formatMessage({ id: "dialogs.schedule.email.widgetError" });
544
- const hasAttachments = !!editedAutomation.exportDefinitions?.length;
545
- const hasRecipients = (editedAutomation.recipients?.length ?? 0) > 0;
546
- const hasValidExternalRecipients = allowExternalRecipients
547
- ? true
548
- : !editedAutomation.recipients?.some(isAutomationExternalUserRecipient);
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));
339
+ const { isSubmitDisabled, validationErrorMessage, isParentValid, allowExternalRecipients, allowOnlyLoggedUserRecipients, } = useScheduledEmailFormValidity({
340
+ editedAutomation,
341
+ originalAutomation,
342
+ scheduledExportToEdit,
343
+ notificationChannels,
344
+ defaultRecipient,
345
+ maxAutomationsRecipients,
346
+ isCronValid,
347
+ isTitleValid,
348
+ isSubjectValid,
349
+ isOnMessageValid,
350
+ });
572
351
  return {
573
352
  defaultUser,
574
353
  areDashboardFiltersChanged,
@@ -614,98 +393,6 @@ export function useEditScheduledEmail({ scheduledExportToEdit, notificationChann
614
393
  enableAutomationEvaluationMode,
615
394
  };
616
395
  }
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
396
  function newAutomationMetadataObjectDefinition({ timezone, dashboardId, notificationChannel, title, insight, widget, recipient, dashboardFilters, filtersByTab, widgetFilters, widgetFiltersWithInsight, visibleFiltersMetadata, visibleFiltersByTab, defaultPdfPageSize, evaluationMode, targetTabId, parametersByTab, }) {
710
397
  const { firstRun, cron } = toNormalizedFirstRunAndCron(timezone);
711
398
  const exportDefinition = widget && insight
@@ -0,0 +1,57 @@
1
+ import { type Dispatch, type RefObject, type SetStateAction } from "react";
2
+ import { type DashboardAttachmentType, type FilterContextItem, type IAutomationMetadataObjectDefinition, type IDashboardExportParameter, type IExportDefinitionVisualizationObjectSettings, type IFilter, type IInsight, type IWidget, type WidgetAttachmentType } from "@gooddata/sdk-model";
3
+ export interface IUseScheduledEmailExportSettingsProps {
4
+ editedAutomation: IAutomationMetadataObjectDefinition;
5
+ setEditedAutomation: Dispatch<SetStateAction<IAutomationMetadataObjectDefinition>>;
6
+ insight?: IInsight;
7
+ widget?: IWidget;
8
+ dashboardId?: string;
9
+ dashboardTitle: string;
10
+ storeFilters?: boolean;
11
+ effectiveDashboardFilters: FilterContextItem[] | undefined;
12
+ effectiveDashboardFiltersByTab: Record<string, FilterContextItem[]> | undefined;
13
+ effectiveWidgetFilters: IFilter[];
14
+ effectiveWidgetFiltersWithInsight: IFilter[];
15
+ defaultPdfPageSize?: IExportDefinitionVisualizationObjectSettings["pageSize"];
16
+ resolvedDefaultCsvDelimiter: string;
17
+ /**
18
+ * Holds the wire outside the automation so it survives a rebuild from zero export definitions —
19
+ * with no definitions `setExportParametersByTab` has nowhere to store it. Owned by the parent
20
+ * (`useEditScheduledEmail`); read here (never written) at attachment-change time.
21
+ */
22
+ latestParametersWireRef: RefObject<Record<string, IDashboardExportParameter[]> | undefined>;
23
+ }
24
+ export declare function useScheduledEmailExportSettings({ editedAutomation, setEditedAutomation, insight, widget, dashboardId, dashboardTitle, storeFilters, effectiveDashboardFilters, effectiveDashboardFiltersByTab, effectiveWidgetFilters, effectiveWidgetFiltersWithInsight, defaultPdfPageSize, resolvedDefaultCsvDelimiter, latestParametersWireRef }: IUseScheduledEmailExportSettingsProps): {
25
+ selectedAttachments: ("CSV" | "CSV_RAW" | "HTML" | "PDF" | "PDF_SLIDES" | "PDF_TABULAR" | "PNG" | "PPTX" | "XLSX")[];
26
+ isDashboardExportSelected: boolean;
27
+ isCsvExportSelected: boolean;
28
+ isXlsxExportSelected: boolean;
29
+ xlsxSettings: {
30
+ mergeHeaders: boolean;
31
+ exportInfo: boolean;
32
+ };
33
+ pdfSettings: {
34
+ pageSize: "A3" | "A4" | "LETTER";
35
+ orientation: "landscape" | "portrait";
36
+ exportInfo: boolean;
37
+ };
38
+ csvSettings: {
39
+ delimiter: string;
40
+ };
41
+ csvRawSettings: {
42
+ delimiter: string;
43
+ };
44
+ slidesTemplateIds: {
45
+ PPTX: string | undefined;
46
+ PDF_SLIDES: string | undefined;
47
+ PDF: string | undefined;
48
+ };
49
+ onDashboardAttachmentsChange: (formats: DashboardAttachmentType[]) => void;
50
+ onWidgetAttachmentsChange: (formats: WidgetAttachmentType[]) => void;
51
+ onXlsxSettingsChange: (settings: IExportDefinitionVisualizationObjectSettings) => void;
52
+ onPdfSettingsChange: (settings: IExportDefinitionVisualizationObjectSettings) => void;
53
+ onCsvSettingsChange: (settings: IExportDefinitionVisualizationObjectSettings) => void;
54
+ onCsvRawSettingsChange: (settings: IExportDefinitionVisualizationObjectSettings) => void;
55
+ onSlidesTemplateIdChange: (templateId: string | undefined, format: "PDF" | "PDF_SLIDES" | "PPTX") => void;
56
+ };
57
+ //# sourceMappingURL=useScheduledEmailExportSettings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useScheduledEmailExportSettings.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailExportSettings.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAE,KAAK,cAAc,EAAwB,MAAM,OAAO,CAAC;AAIjG,OAAO,EACH,KAAK,uBAAuB,EAC5B,KAAK,iBAAiB,EACtB,KAAK,mCAAmC,EACxC,KAAK,yBAAyB,EAC9B,KAAK,4CAA4C,EACjD,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,KAAK,OAAO,EACZ,KAAK,oBAAoB,EAG5B,MAAM,qBAAqB,CAAC;AAQ7B,MAAM,WAAW,qCAAqC;IAClD,gBAAgB,EAAE,mCAAmC,CAAC;IACtD,mBAAmB,EAAE,QAAQ,CAAC,cAAc,CAAC,mCAAmC,CAAC,CAAC,CAAC;IACnF,OAAO,CAAC,EAAE,QAAQ,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,yBAAyB,EAAE,iBAAiB,EAAE,GAAG,SAAS,CAAC;IAC3D,8BAA8B,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC,GAAG,SAAS,CAAC;IAChF,sBAAsB,EAAE,OAAO,EAAE,CAAC;IAClC,iCAAiC,EAAE,OAAO,EAAE,CAAC;IAC7C,kBAAkB,CAAC,EAAE,4CAA4C,CAAC,UAAU,CAAC,CAAC;IAC9E,2BAA2B,EAAE,MAAM,CAAC;IACpC;;;;OAIG;IACH,uBAAuB,EAAE,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,yBAAyB,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC;CAC/F;AAED,wBAAgB,+BAA+B,CAAC,EAC5C,gBAAgB,EAChB,mBAAmB,EACnB,OAAO,EACP,MAAM,EACN,WAAW,EACX,cAAc,EACd,YAAY,EACZ,yBAAyB,EACzB,8BAA8B,EAC9B,sBAAsB,EACtB,iCAAiC,EACjC,kBAAkB,EAClB,2BAA2B,EAC3B,uBAAuB,EAC1B,EAAE,qCAAqC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8UvC"}
@@ -0,0 +1,241 @@
1
+ // (C) 2019-2026 GoodData Corporation
2
+ import { useCallback, useMemo } from "react";
3
+ import { invariant } from "ts-invariant";
4
+ import { isExportDefinitionDashboardRequestPayload, isExportDefinitionVisualizationObjectRequestPayload, } from "@gooddata/sdk-model";
5
+ import { newDashboardExportDefinitionMetadataObjectDefinition, newWidgetExportDefinitionMetadataObjectDefinition, withRebuiltExportDefinitions, } from "../utils/exportDefinitions.js";
6
+ export function useScheduledEmailExportSettings({ editedAutomation, setEditedAutomation, insight, widget, dashboardId, dashboardTitle, storeFilters, effectiveDashboardFilters, effectiveDashboardFiltersByTab, effectiveWidgetFilters, effectiveWidgetFiltersWithInsight, defaultPdfPageSize, resolvedDefaultCsvDelimiter, latestParametersWireRef, }) {
7
+ // Re-derived locally (not passed as a prop) so that `invariant(isWidget, ...)` below narrows
8
+ // `widget`/`insight` via TS's aliased-condition control-flow analysis — this requires the boolean
9
+ // to be declared from those exact variables in this same scope, same as in the parent.
10
+ const isWidget = !!widget && !!insight;
11
+ const selectedAttachments = useMemo(() => {
12
+ return (editedAutomation.exportDefinitions
13
+ ?.map((exportDefinition) => exportDefinition.requestPayload.format)
14
+ .filter(Boolean) ?? []);
15
+ }, [editedAutomation.exportDefinitions]);
16
+ const onDashboardAttachmentsChange = (formats) => {
17
+ setEditedAutomation((s) => {
18
+ const currentExportDefinitions = s.exportDefinitions || [];
19
+ const currentDashboardExportDefinitions = currentExportDefinitions.filter((exportDefinition) => isExportDefinitionDashboardRequestPayload(exportDefinition.requestPayload));
20
+ const currentFormats = currentDashboardExportDefinitions.map((exportDefinition) => exportDefinition.requestPayload.format);
21
+ const formatsToKeep = currentFormats.filter((format) => formats.includes(format));
22
+ const formatsToAdd = formats.filter((format) => !currentFormats.includes(format));
23
+ const keptExportDefinitions = currentDashboardExportDefinitions.filter((exportDefinition) => formatsToKeep.includes(exportDefinition.requestPayload.format));
24
+ const newExportDefinitions = formatsToAdd.map((format) => newDashboardExportDefinitionMetadataObjectDefinition({
25
+ dashboardId: dashboardId,
26
+ dashboardTitle,
27
+ dashboardFilters: storeFilters ? effectiveDashboardFilters : undefined,
28
+ filtersByTab: storeFilters ? effectiveDashboardFiltersByTab : undefined,
29
+ format,
30
+ }));
31
+ const updatedExportDefinitions = [...keptExportDefinitions, ...newExportDefinitions];
32
+ return withRebuiltExportDefinitions(s, updatedExportDefinitions, latestParametersWireRef.current);
33
+ });
34
+ };
35
+ const onWidgetAttachmentsChange = (formats) => {
36
+ invariant(isWidget, "Widget or insight is missing in scheduling dialog context.");
37
+ setEditedAutomation((s) => {
38
+ const currentExportDefinitions = s.exportDefinitions || [];
39
+ const currentWidgetExportDefinitions = currentExportDefinitions.filter((exportDefinition) => isExportDefinitionVisualizationObjectRequestPayload(exportDefinition.requestPayload));
40
+ const currentFormats = currentWidgetExportDefinitions.map((exportDefinition) => exportDefinition.requestPayload.format);
41
+ const formatsToKeep = currentFormats.filter((format) => formats.includes(format));
42
+ const formatsToAdd = formats.filter((format) => !currentFormats.includes(format));
43
+ const keptExportDefinitions = currentWidgetExportDefinitions.filter((exportDefinition) => formatsToKeep.includes(exportDefinition.requestPayload.format));
44
+ const newExportDefinitions = formatsToAdd.map((format) => newWidgetExportDefinitionMetadataObjectDefinition({
45
+ insight,
46
+ widget,
47
+ dashboardId: dashboardId,
48
+ format,
49
+ widgetFilters: effectiveWidgetFilters,
50
+ widgetFiltersWithInsight: effectiveWidgetFiltersWithInsight,
51
+ dashboardFilters: effectiveDashboardFilters,
52
+ defaultPdfPageSize,
53
+ }));
54
+ const updatedExportDefinitions = [...keptExportDefinitions, ...newExportDefinitions];
55
+ return withRebuiltExportDefinitions(s, updatedExportDefinitions, latestParametersWireRef.current);
56
+ });
57
+ };
58
+ const onXlsxSettingsChange = useCallback((settings) => {
59
+ setEditedAutomation((s) => ({
60
+ ...s,
61
+ exportDefinitions: s.exportDefinitions?.map((exportDefinition) => {
62
+ if (exportDefinition.requestPayload.format !== "XLSX") {
63
+ return exportDefinition;
64
+ }
65
+ const nextSettings = {
66
+ ...exportDefinition.requestPayload?.settings,
67
+ mergeHeaders: settings.mergeHeaders,
68
+ exportInfo: settings.exportInfo,
69
+ };
70
+ return {
71
+ ...exportDefinition,
72
+ requestPayload: {
73
+ ...exportDefinition.requestPayload,
74
+ settings: nextSettings,
75
+ },
76
+ };
77
+ }),
78
+ }));
79
+ }, [setEditedAutomation]);
80
+ const onPdfSettingsChange = useCallback((settings) => {
81
+ setEditedAutomation((s) => ({
82
+ ...s,
83
+ exportDefinitions: s.exportDefinitions?.map((exportDefinition) => {
84
+ if (exportDefinition.requestPayload.format !== "PDF_TABULAR") {
85
+ return exportDefinition;
86
+ }
87
+ const nextSettings = {
88
+ ...exportDefinition.requestPayload?.settings,
89
+ pageSize: settings.pageSize,
90
+ orientation: settings.orientation ?? "portrait",
91
+ exportInfo: settings.exportInfo,
92
+ };
93
+ return {
94
+ ...exportDefinition,
95
+ requestPayload: {
96
+ ...exportDefinition.requestPayload,
97
+ settings: nextSettings,
98
+ },
99
+ };
100
+ }),
101
+ }));
102
+ }, [setEditedAutomation]);
103
+ const onCsvSettingsChange = useCallback((settings) => {
104
+ setEditedAutomation((s) => ({
105
+ ...s,
106
+ exportDefinitions: s.exportDefinitions?.map((exportDefinition) => {
107
+ if (exportDefinition.requestPayload.format !== "CSV") {
108
+ return exportDefinition;
109
+ }
110
+ return {
111
+ ...exportDefinition,
112
+ requestPayload: {
113
+ ...exportDefinition.requestPayload,
114
+ settings: {
115
+ ...exportDefinition.requestPayload.settings,
116
+ delimiter: settings.delimiter,
117
+ },
118
+ },
119
+ };
120
+ }),
121
+ }));
122
+ }, [setEditedAutomation]);
123
+ const onCsvRawSettingsChange = useCallback((settings) => {
124
+ setEditedAutomation((s) => ({
125
+ ...s,
126
+ exportDefinitions: s.exportDefinitions?.map((exportDefinition) => {
127
+ if (exportDefinition.requestPayload.format !== "CSV_RAW") {
128
+ return exportDefinition;
129
+ }
130
+ return {
131
+ ...exportDefinition,
132
+ requestPayload: {
133
+ ...exportDefinition.requestPayload,
134
+ settings: {
135
+ ...exportDefinition.requestPayload.settings,
136
+ delimiter: settings.delimiter,
137
+ },
138
+ },
139
+ };
140
+ }),
141
+ }));
142
+ }, [setEditedAutomation]);
143
+ const onSlidesTemplateIdChange = useCallback((templateId, format) => {
144
+ setEditedAutomation((s) => ({
145
+ ...s,
146
+ exportDefinitions: s.exportDefinitions?.map((exportDefinition) => {
147
+ const matchesFormat = exportDefinition.requestPayload.format === format;
148
+ const matchesType = isWidget
149
+ ? isExportDefinitionVisualizationObjectRequestPayload(exportDefinition.requestPayload)
150
+ : isExportDefinitionDashboardRequestPayload(exportDefinition.requestPayload);
151
+ if (!matchesFormat || !matchesType) {
152
+ return exportDefinition;
153
+ }
154
+ return {
155
+ ...exportDefinition,
156
+ requestPayload: {
157
+ ...exportDefinition.requestPayload,
158
+ templateId,
159
+ },
160
+ };
161
+ }),
162
+ }));
163
+ }, [setEditedAutomation, isWidget]);
164
+ const isDashboardExportSelected = editedAutomation.exportDefinitions?.some((exportDefinition) => isExportDefinitionDashboardRequestPayload(exportDefinition.requestPayload)) ?? true;
165
+ const isCsvExportSelected = editedAutomation.exportDefinitions?.some((exportDefinition) => {
166
+ if (isExportDefinitionVisualizationObjectRequestPayload(exportDefinition.requestPayload)) {
167
+ return exportDefinition.requestPayload.format === "CSV";
168
+ }
169
+ return false;
170
+ }) ?? false;
171
+ const isXlsxExportSelected = editedAutomation.exportDefinitions?.some((exportDefinition) => {
172
+ if (isExportDefinitionVisualizationObjectRequestPayload(exportDefinition.requestPayload)) {
173
+ return exportDefinition.requestPayload.format === "XLSX";
174
+ }
175
+ return false;
176
+ }) ?? false;
177
+ const xlsxExportSettings = editedAutomation.exportDefinitions?.find((exportDefinition) => exportDefinition.requestPayload.format === "XLSX")?.requestPayload.settings;
178
+ const xlsxSettings = {
179
+ mergeHeaders: xlsxExportSettings?.mergeHeaders ?? true,
180
+ exportInfo: xlsxExportSettings?.exportInfo ?? true,
181
+ };
182
+ const pdfVisualizationSettings = editedAutomation.exportDefinitions?.find((exportDefinition) => isExportDefinitionVisualizationObjectRequestPayload(exportDefinition.requestPayload) &&
183
+ exportDefinition.requestPayload.format === "PDF_TABULAR")?.requestPayload.settings;
184
+ const pdfTabularSettings = pdfVisualizationSettings && "pageSize" in pdfVisualizationSettings
185
+ ? pdfVisualizationSettings
186
+ : undefined;
187
+ const pdfSettings = {
188
+ pageSize: pdfTabularSettings?.pageSize ?? defaultPdfPageSize ?? "A4",
189
+ orientation: pdfTabularSettings?.orientation ?? "portrait",
190
+ exportInfo: pdfTabularSettings?.exportInfo ?? true,
191
+ };
192
+ const csvExportDefinition = editedAutomation.exportDefinitions?.find((exportDefinition) => isExportDefinitionVisualizationObjectRequestPayload(exportDefinition.requestPayload) &&
193
+ exportDefinition.requestPayload.format === "CSV");
194
+ const csvExportSettings = csvExportDefinition &&
195
+ isExportDefinitionVisualizationObjectRequestPayload(csvExportDefinition.requestPayload)
196
+ ? csvExportDefinition.requestPayload.settings
197
+ : undefined;
198
+ const csvSettings = {
199
+ delimiter: csvExportSettings?.delimiter ?? resolvedDefaultCsvDelimiter,
200
+ };
201
+ const csvRawExportDefinition = editedAutomation.exportDefinitions?.find((exportDefinition) => isExportDefinitionVisualizationObjectRequestPayload(exportDefinition.requestPayload) &&
202
+ exportDefinition.requestPayload.format === "CSV_RAW");
203
+ const csvRawExportSettings = csvRawExportDefinition &&
204
+ isExportDefinitionVisualizationObjectRequestPayload(csvRawExportDefinition.requestPayload)
205
+ ? csvRawExportDefinition.requestPayload.settings
206
+ : undefined;
207
+ const csvRawSettings = {
208
+ delimiter: csvRawExportSettings?.delimiter ?? resolvedDefaultCsvDelimiter,
209
+ };
210
+ // Extract templateId per slides format, scoped to the current dialog mode
211
+ const getTemplateIdForFormat = (format) => {
212
+ const def = editedAutomation.exportDefinitions?.find((ed) => ed.requestPayload.format === format &&
213
+ (isWidget
214
+ ? isExportDefinitionVisualizationObjectRequestPayload(ed.requestPayload)
215
+ : isExportDefinitionDashboardRequestPayload(ed.requestPayload)));
216
+ return def?.requestPayload.templateId;
217
+ };
218
+ const slidesTemplateIds = {
219
+ PPTX: getTemplateIdForFormat("PPTX"),
220
+ PDF_SLIDES: getTemplateIdForFormat("PDF_SLIDES"),
221
+ PDF: getTemplateIdForFormat("PDF"),
222
+ };
223
+ return {
224
+ selectedAttachments,
225
+ isDashboardExportSelected,
226
+ isCsvExportSelected,
227
+ isXlsxExportSelected,
228
+ xlsxSettings,
229
+ pdfSettings,
230
+ csvSettings,
231
+ csvRawSettings,
232
+ slidesTemplateIds,
233
+ onDashboardAttachmentsChange,
234
+ onWidgetAttachmentsChange,
235
+ onXlsxSettingsChange,
236
+ onPdfSettingsChange,
237
+ onCsvSettingsChange,
238
+ onCsvRawSettingsChange,
239
+ onSlidesTemplateIdChange,
240
+ };
241
+ }
@@ -0,0 +1,21 @@
1
+ import { type IAutomationMetadataObject, type IAutomationMetadataObjectDefinition, type IAutomationRecipient, type INotificationChannelIdentifier, type INotificationChannelMetadataObject } from "@gooddata/sdk-model";
2
+ export interface IUseScheduledEmailFormValidityProps {
3
+ editedAutomation: IAutomationMetadataObjectDefinition;
4
+ originalAutomation: IAutomationMetadataObjectDefinition;
5
+ scheduledExportToEdit?: IAutomationMetadataObject;
6
+ notificationChannels: INotificationChannelIdentifier[] | INotificationChannelMetadataObject[];
7
+ defaultRecipient: IAutomationRecipient;
8
+ maxAutomationsRecipients: number;
9
+ isCronValid: boolean;
10
+ isTitleValid: boolean;
11
+ isSubjectValid: boolean;
12
+ isOnMessageValid: boolean;
13
+ }
14
+ export declare function useScheduledEmailFormValidity(props: IUseScheduledEmailFormValidityProps): {
15
+ isSubmitDisabled: boolean | undefined;
16
+ validationErrorMessage: string | undefined;
17
+ isParentValid: boolean;
18
+ allowExternalRecipients: boolean;
19
+ allowOnlyLoggedUserRecipients: boolean;
20
+ };
21
+ //# sourceMappingURL=useScheduledEmailFormValidity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useScheduledEmailFormValidity.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailFormValidity.ts"],"names":[],"mappings":"AAIA,OAAO,EACH,KAAK,yBAAyB,EAC9B,KAAK,mCAAmC,EACxC,KAAK,oBAAoB,EACzB,KAAK,8BAA8B,EACnC,KAAK,kCAAkC,EAI1C,MAAM,qBAAqB,CAAC;AAO7B,MAAM,WAAW,mCAAmC;IAChD,gBAAgB,EAAE,mCAAmC,CAAC;IACtD,kBAAkB,EAAE,mCAAmC,CAAC;IACxD,qBAAqB,CAAC,EAAE,yBAAyB,CAAC;IAClD,oBAAoB,EAAE,8BAA8B,EAAE,GAAG,kCAAkC,EAAE,CAAC;IAC9F,gBAAgB,EAAE,oBAAoB,CAAC;IACvC,wBAAwB,EAAE,MAAM,CAAC;IACjC,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,EAAE,OAAO,CAAC;IACtB,cAAc,EAAE,OAAO,CAAC;IACxB,gBAAgB,EAAE,OAAO,CAAC;CAC7B;AAED,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,mCAAmC,GAAG;IAIvF,gBAAgB,EAAE,OAAO,GAAG,SAAS,CAAC;IACtC,sBAAsB,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3C,aAAa,EAAE,OAAO,CAAC;IACvB,uBAAuB,EAAE,OAAO,CAAC;IACjC,6BAA6B,EAAE,OAAO,CAAC;CAC1C,CAsEA"}
@@ -0,0 +1,52 @@
1
+ // (C) 2026 GoodData Corporation
2
+ import { useIntl } from "react-intl";
3
+ import { isAutomationExternalUserRecipient, isAutomationUnknownUserRecipient, isAutomationUserRecipient, } from "@gooddata/sdk-model";
4
+ import { areAutomationsEqual } from "../../../shared/utils/automationUtils.js";
5
+ import { isEmail } from "../../utils/validate.js";
6
+ import { useScheduleValidation } from "./useScheduleValidation.js";
7
+ export function useScheduledEmailFormValidity(props) {
8
+ const { editedAutomation, originalAutomation, scheduledExportToEdit, notificationChannels, defaultRecipient, maxAutomationsRecipients, isCronValid, isTitleValid, isSubjectValid, isOnMessageValid, } = props;
9
+ const intl = useIntl();
10
+ const selectedNotificationChannel = notificationChannels.find((channel) => channel.id === editedAutomation.notificationChannel);
11
+ const allowExternalRecipients = selectedNotificationChannel?.allowedRecipients === "external";
12
+ const allowOnlyLoggedUserRecipients = selectedNotificationChannel?.allowedRecipients === "creator";
13
+ const { isValid: isParentValid } = useScheduleValidation(originalAutomation);
14
+ const validationErrorMessage = isParentValid
15
+ ? undefined
16
+ : intl.formatMessage({ id: "dialogs.schedule.email.widgetError" });
17
+ const hasAttachments = !!editedAutomation.exportDefinitions?.length;
18
+ const hasRecipients = (editedAutomation.recipients?.length ?? 0) > 0;
19
+ const hasValidExternalRecipients = allowExternalRecipients
20
+ ? true
21
+ : !editedAutomation.recipients?.some(isAutomationExternalUserRecipient);
22
+ const hasValidCreatorRecipient = allowOnlyLoggedUserRecipients
23
+ ? editedAutomation.recipients?.length === 1 &&
24
+ editedAutomation.recipients[0].id === defaultRecipient.id
25
+ : true;
26
+ const hasNoUnknownRecipients = !editedAutomation.recipients?.some(isAutomationUnknownUserRecipient);
27
+ const hasDestination = !!editedAutomation.notificationChannel;
28
+ const respectsRecipientsLimit = (editedAutomation.recipients?.length ?? 0) <= maxAutomationsRecipients;
29
+ const hasFilledEmails = selectedNotificationChannel?.destinationType === "smtp"
30
+ ? editedAutomation.recipients?.every((recipient) => isAutomationUserRecipient(recipient) ? isEmail(recipient.email ?? "") : true)
31
+ : true;
32
+ const isValid = isCronValid &&
33
+ hasRecipients &&
34
+ respectsRecipientsLimit &&
35
+ hasAttachments &&
36
+ hasDestination &&
37
+ hasValidExternalRecipients &&
38
+ hasValidCreatorRecipient &&
39
+ hasNoUnknownRecipients &&
40
+ hasFilledEmails &&
41
+ isOnMessageValid &&
42
+ isTitleValid &&
43
+ isSubjectValid;
44
+ const isSubmitDisabled = !isValid || (scheduledExportToEdit && areAutomationsEqual(originalAutomation, editedAutomation));
45
+ return {
46
+ isSubmitDisabled,
47
+ validationErrorMessage,
48
+ isParentValid,
49
+ allowExternalRecipients,
50
+ allowOnlyLoggedUserRecipients,
51
+ };
52
+ }
@@ -0,0 +1,27 @@
1
+ import { type DashboardAttachmentType, type FilterContextItem, type IAutomationMetadataObjectDefinition, type IDashboardExportParameter, type IExportDefinitionMetadataObjectDefinition, type IExportDefinitionVisualizationObjectSettings, type IFilter, type IInsight, type IWidget, type WidgetAttachmentType } from "@gooddata/sdk-model";
2
+ /**
3
+ * Rebuilds the export definitions and re-applies the parameter wire (fresh definitions carry no
4
+ * `content.parametersByTab`). The wire is passed in rather than read off `automation` so it survives
5
+ * a rebuild from zero definitions — see `latestParametersWireRef`.
6
+ */
7
+ export declare function withRebuiltExportDefinitions(automation: IAutomationMetadataObjectDefinition, exportDefinitions: NonNullable<IAutomationMetadataObjectDefinition["exportDefinitions"]>, parametersByTab: Record<string, IDashboardExportParameter[]> | undefined): IAutomationMetadataObjectDefinition;
8
+ export declare function newDashboardExportDefinitionMetadataObjectDefinition({ dashboardId, dashboardTitle, dashboardFilters, filtersByTab, format, templateId }: {
9
+ dashboardId: string;
10
+ dashboardTitle: string;
11
+ dashboardFilters?: FilterContextItem[];
12
+ filtersByTab?: Record<string, FilterContextItem[]>;
13
+ format: DashboardAttachmentType;
14
+ templateId?: string;
15
+ }): IExportDefinitionMetadataObjectDefinition;
16
+ export declare function newWidgetExportDefinitionMetadataObjectDefinition({ insight, widget, dashboardId, format, widgetFilters, widgetFiltersWithInsight, dashboardFilters, defaultPdfPageSize, defaultCsvDelimiter }: {
17
+ insight: IInsight;
18
+ widget: IWidget;
19
+ dashboardId: string;
20
+ format: WidgetAttachmentType;
21
+ widgetFilters?: IFilter[];
22
+ widgetFiltersWithInsight?: IFilter[];
23
+ dashboardFilters?: FilterContextItem[];
24
+ defaultPdfPageSize?: IExportDefinitionVisualizationObjectSettings["pageSize"];
25
+ defaultCsvDelimiter?: string;
26
+ }): IExportDefinitionMetadataObjectDefinition;
27
+ //# sourceMappingURL=exportDefinitions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exportDefinitions.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/utils/exportDefinitions.ts"],"names":[],"mappings":"AAEA,OAAO,EACH,KAAK,uBAAuB,EAC5B,KAAK,iBAAiB,EACtB,KAAK,mCAAmC,EACxC,KAAK,yBAAyB,EAC9B,KAAK,yCAAyC,EAC9C,KAAK,4CAA4C,EACjD,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,KAAK,OAAO,EACZ,KAAK,oBAAoB,EAE5B,MAAM,qBAAqB,CAAC;AAI7B;;;;GAIG;AACH,wBAAgB,4BAA4B,CACxC,UAAU,EAAE,mCAAmC,EAC/C,iBAAiB,EAAE,WAAW,CAAC,mCAAmC,CAAC,mBAAmB,CAAC,CAAC,EACxF,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,yBAAyB,EAAE,CAAC,GAAG,SAAS,GACzE,mCAAmC,CAGrC;AAED,wBAAgB,oDAAoD,CAAC,EACjE,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,MAAM,EACN,UAAU,EACb,EAAE;IACC,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACvC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC,CAAC;IACnD,MAAM,EAAE,uBAAuB,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,yCAAyC,CAyB5C;AAED,wBAAgB,iDAAiD,CAAC,EAC9D,OAAO,EACP,MAAM,EACN,WAAW,EACX,MAAM,EACN,aAAa,EACb,wBAAwB,EACxB,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACtB,EAAE;IACC,OAAO,EAAE,QAAQ,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,oBAAoB,CAAC;IAC7B,aAAa,CAAC,EAAE,OAAO,EAAE,CAAC;IAC1B,wBAAwB,CAAC,EAAE,OAAO,EAAE,CAAC;IACrC,gBAAgB,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACvC,kBAAkB,CAAC,EAAE,4CAA4C,CAAC,UAAU,CAAC,CAAC;IAC9E,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAChC,GAAG,yCAAyC,CAiE5C"}
@@ -0,0 +1,95 @@
1
+ // (C) 2019-2026 GoodData Corporation
2
+ import { insightProperties, } from "@gooddata/sdk-model";
3
+ import { setExportParametersByTab } from "../../../../../_staging/automation/index.js";
4
+ /**
5
+ * Rebuilds the export definitions and re-applies the parameter wire (fresh definitions carry no
6
+ * `content.parametersByTab`). The wire is passed in rather than read off `automation` so it survives
7
+ * a rebuild from zero definitions — see `latestParametersWireRef`.
8
+ */
9
+ export function withRebuiltExportDefinitions(automation, exportDefinitions, parametersByTab) {
10
+ const next = { ...automation, exportDefinitions };
11
+ return parametersByTab ? setExportParametersByTab(next, parametersByTab) : next;
12
+ }
13
+ export function newDashboardExportDefinitionMetadataObjectDefinition({ dashboardId, dashboardTitle, dashboardFilters, filtersByTab, format, templateId, }) {
14
+ // Use filtersByTab if provided, otherwise fall back to simple filters
15
+ const filtersObj = filtersByTab
16
+ ? { filtersByTab }
17
+ : dashboardFilters
18
+ ? { filters: dashboardFilters }
19
+ : {};
20
+ const settingsObj = format === "XLSX" ? { settings: { mergeHeaders: true, exportInfo: true } } : {};
21
+ return {
22
+ type: "exportDefinition",
23
+ title: dashboardTitle,
24
+ requestPayload: {
25
+ type: "dashboard",
26
+ fileName: dashboardTitle,
27
+ format,
28
+ content: {
29
+ dashboard: dashboardId,
30
+ ...filtersObj,
31
+ },
32
+ ...settingsObj,
33
+ ...(templateId ? { templateId } : {}),
34
+ },
35
+ };
36
+ }
37
+ export function newWidgetExportDefinitionMetadataObjectDefinition({ insight, widget, dashboardId, format, widgetFilters, widgetFiltersWithInsight, dashboardFilters, defaultPdfPageSize, defaultCsvDelimiter, }) {
38
+ const widgetTitle = widget.title;
39
+ // Determine which filters to use based on format:
40
+ // - CSV: Use widgetFiltersWithInsight (insight filters merged on frontend)
41
+ // - CSV_RAW: Use widgetFilters (insight filters merged on backend)
42
+ // - Other formats: Use dashboardFilters (backend handles insight filter merging)
43
+ const shouldUseCsvFilters = format === "CSV";
44
+ const shouldUseCsvRawFilters = format === "CSV_RAW";
45
+ let filtersObj = {};
46
+ if (shouldUseCsvFilters && (widgetFiltersWithInsight ?? []).length > 0) {
47
+ filtersObj = { filters: widgetFiltersWithInsight };
48
+ }
49
+ else if (shouldUseCsvRawFilters && (widgetFilters ?? []).length > 0) {
50
+ filtersObj = { filters: widgetFilters };
51
+ }
52
+ else if (!shouldUseCsvFilters && !shouldUseCsvRawFilters && (dashboardFilters ?? []).length > 0) {
53
+ filtersObj = { filters: dashboardFilters };
54
+ }
55
+ const grandTotalsPosition = insightProperties(insight)?.["controls"]?.["grandTotalsPosition"];
56
+ const pdfSettings = {
57
+ pageSize: defaultPdfPageSize ?? "A4",
58
+ orientation: "portrait",
59
+ exportInfo: true,
60
+ ...(grandTotalsPosition ? { grandTotalsPosition } : {}),
61
+ };
62
+ const xlsxSettings = {
63
+ mergeHeaders: true,
64
+ exportInfo: true,
65
+ ...(grandTotalsPosition ? { grandTotalsPosition } : {}),
66
+ };
67
+ const csvSettings = {
68
+ ...(defaultCsvDelimiter ? { delimiter: defaultCsvDelimiter } : {}),
69
+ ...(grandTotalsPosition ? { grandTotalsPosition } : {}),
70
+ };
71
+ const hasCsvSettings = Object.keys(csvSettings).length > 0;
72
+ const settingsObj = format === "XLSX"
73
+ ? { settings: xlsxSettings }
74
+ : format === "PDF_TABULAR"
75
+ ? { settings: pdfSettings }
76
+ : (format === "CSV" || format === "CSV_RAW") && hasCsvSettings
77
+ ? { settings: csvSettings }
78
+ : {};
79
+ return {
80
+ type: "exportDefinition",
81
+ title: widgetTitle,
82
+ requestPayload: {
83
+ type: "visualizationObject",
84
+ fileName: widgetTitle,
85
+ format: format,
86
+ content: {
87
+ visualizationObject: insight.insight.identifier,
88
+ widget: widget.identifier,
89
+ dashboard: dashboardId,
90
+ ...filtersObj,
91
+ },
92
+ ...settingsObj,
93
+ },
94
+ };
95
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gooddata/sdk-ui-dashboard",
3
- "version": "11.50.0-alpha.0",
3
+ "version": "11.50.0-alpha.1",
4
4
  "description": "GoodData SDK - Dashboard Component",
5
5
  "license": "LicenseRef-LICENSE",
6
6
  "author": "GoodData Corporation",
@@ -60,20 +60,20 @@
60
60
  "ts-invariant": "0.10.3",
61
61
  "tslib": "2.8.1",
62
62
  "uuid": "11.1.1",
63
- "@gooddata/sdk-backend-base": "11.50.0-alpha.0",
64
- "@gooddata/sdk-backend-spi": "11.50.0-alpha.0",
65
- "@gooddata/sdk-model": "11.50.0-alpha.0",
66
- "@gooddata/sdk-ui-charts": "11.50.0-alpha.0",
67
- "@gooddata/sdk-ui": "11.50.0-alpha.0",
68
- "@gooddata/sdk-ui-ext": "11.50.0-alpha.0",
69
- "@gooddata/sdk-ui-filters": "11.50.0-alpha.0",
70
- "@gooddata/sdk-ui-kit": "11.50.0-alpha.0",
71
- "@gooddata/sdk-ui-geo": "11.50.0-alpha.0",
72
- "@gooddata/sdk-ui-pivot": "11.50.0-alpha.0",
73
- "@gooddata/sdk-ui-semantic-search": "11.50.0-alpha.0",
74
- "@gooddata/sdk-ui-theme-provider": "11.50.0-alpha.0",
75
- "@gooddata/sdk-ui-vis-commons": "11.50.0-alpha.0",
76
- "@gooddata/util": "11.50.0-alpha.0"
63
+ "@gooddata/sdk-backend-spi": "11.50.0-alpha.1",
64
+ "@gooddata/sdk-backend-base": "11.50.0-alpha.1",
65
+ "@gooddata/sdk-model": "11.50.0-alpha.1",
66
+ "@gooddata/sdk-ui-charts": "11.50.0-alpha.1",
67
+ "@gooddata/sdk-ui": "11.50.0-alpha.1",
68
+ "@gooddata/sdk-ui-ext": "11.50.0-alpha.1",
69
+ "@gooddata/sdk-ui-kit": "11.50.0-alpha.1",
70
+ "@gooddata/sdk-ui-geo": "11.50.0-alpha.1",
71
+ "@gooddata/sdk-ui-pivot": "11.50.0-alpha.1",
72
+ "@gooddata/sdk-ui-filters": "11.50.0-alpha.1",
73
+ "@gooddata/sdk-ui-semantic-search": "11.50.0-alpha.1",
74
+ "@gooddata/sdk-ui-theme-provider": "11.50.0-alpha.1",
75
+ "@gooddata/sdk-ui-vis-commons": "11.50.0-alpha.1",
76
+ "@gooddata/util": "11.50.0-alpha.1"
77
77
  },
78
78
  "devDependencies": {
79
79
  "@microsoft/api-documenter": "^7.17.0",
@@ -119,12 +119,12 @@
119
119
  "typescript": "5.9.3",
120
120
  "vitest": "4.1.8",
121
121
  "vitest-dom": "0.1.1",
122
- "@gooddata/eslint-config": "11.50.0-alpha.0",
123
- "@gooddata/i18n-toolkit": "11.50.0-alpha.0",
124
- "@gooddata/oxlint-config": "11.50.0-alpha.0",
125
- "@gooddata/reference-workspace": "11.50.0-alpha.0",
126
- "@gooddata/stylelint-config": "11.50.0-alpha.0",
127
- "@gooddata/sdk-backend-mockingbird": "11.50.0-alpha.0"
122
+ "@gooddata/eslint-config": "11.50.0-alpha.1",
123
+ "@gooddata/reference-workspace": "11.50.0-alpha.1",
124
+ "@gooddata/sdk-backend-mockingbird": "11.50.0-alpha.1",
125
+ "@gooddata/stylelint-config": "11.50.0-alpha.1",
126
+ "@gooddata/i18n-toolkit": "11.50.0-alpha.1",
127
+ "@gooddata/oxlint-config": "11.50.0-alpha.1"
128
128
  },
129
129
  "peerDependencies": {
130
130
  "react": "^18.0.0 || ^19.0.0",