@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.
Files changed (26) hide show
  1. package/NOTICE +216 -203
  2. package/esm/__version.d.ts +1 -1
  3. package/esm/__version.js +1 -1
  4. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useEditScheduledEmail.d.ts +6 -6
  5. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useEditScheduledEmail.d.ts.map +1 -1
  6. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useEditScheduledEmail.js +65 -534
  7. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailEffectiveFilters.d.ts +38 -0
  8. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailEffectiveFilters.d.ts.map +1 -0
  9. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailEffectiveFilters.js +61 -0
  10. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailExportSettings.d.ts +57 -0
  11. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailExportSettings.d.ts.map +1 -0
  12. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailExportSettings.js +241 -0
  13. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailFormState.d.ts +55 -0
  14. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailFormState.d.ts.map +1 -0
  15. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailFormState.js +203 -0
  16. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailFormValidity.d.ts +21 -0
  17. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailFormValidity.d.ts.map +1 -0
  18. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailFormValidity.js +52 -0
  19. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/utils/exportDefinitions.d.ts +27 -0
  20. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/utils/exportDefinitions.d.ts.map +1 -0
  21. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/utils/exportDefinitions.js +95 -0
  22. package/esm/presentation/filterBar/filterBar/DefaultFilterBarContainer.d.ts.map +1 -1
  23. package/esm/presentation/filterBar/filterBar/DefaultFilterBarContainer.js +11 -5
  24. package/esm/tsdoc-metadata.json +1 -1
  25. package/package.json +21 -21
  26. package/styles/css/main.css +1 -1
@@ -0,0 +1,203 @@
1
+ // (C) 2026 GoodData Corporation
2
+ import { useState } from "react";
3
+ import { setExportParametersByTab } from "../../../../../_staging/automation/index.js";
4
+ import { useAutomationsContext } from "../../../contexts/AutomationsContext.js";
5
+ import { useScheduledEmailDialogContext } from "../../../contexts/ScheduledEmailDialogContext.js";
6
+ import { convertCurrentUserToAutomationRecipient, convertCurrentUserToWorkspaceUser, convertExternalRecipientToAutomationRecipient, } from "../../../shared/utils/automationUtils.js";
7
+ import { toModifiedISOStringToTimezone, toNormalizedFirstRunAndCron } from "../../utils/date.js";
8
+ import { getUserTimezone } from "../../utils/timezone.js";
9
+ import { newDashboardExportDefinitionMetadataObjectDefinition, newWidgetExportDefinitionMetadataObjectDefinition, } from "../utils/exportDefinitions.js";
10
+ /**
11
+ * Owns the scheduled-email dialog's `editedAutomation` draft (initialized either from
12
+ * `scheduledExportToEdit` or via `newAutomationMetadataObjectDefinition`), its `originalAutomation`
13
+ * baseline, the derived defaults (`defaultRecipient`, `defaultUser`), and the form's field/message
14
+ * change handlers and their validity UI state.
15
+ *
16
+ * `timezone` (already part 1) and `currentUser` are read from {@link useAutomationsContext};
17
+ * `dashboardId`/`dashboardTitle` from {@link useScheduledEmailDialogContext}. The effective-filters
18
+ * derivations, `parametersByTabForNewAutomation`, `defaultPdfPageSize`, and `targetTabId` stay owned
19
+ * by the parent (`useEditScheduledEmail`) — shared with other consumers — and are passed in as params.
20
+ *
21
+ * Part 2 of 2 (mirrors the alerting `useAlertFormState` part 2): completes the hook by folding in the
22
+ * draft init that part 1 left in the parent.
23
+ *
24
+ * @internal
25
+ */
26
+ export function useScheduledEmailFormState({ scheduledExportToEdit, widget, insight, notificationChannels, users, externalRecipientOverride, effectiveWidgetFilters, effectiveWidgetFiltersWithInsight, effectiveVisibleWidgetFilters, effectiveDashboardFilters, effectiveDashboardFiltersByTab, effectiveVisibleDashboardFilters, effectiveVisibleDashboardFiltersByTab, parametersByTabForNewAutomation, defaultPdfPageSize, targetTabId, }) {
27
+ const { timezone, currentUser } = useAutomationsContext();
28
+ const { dashboardId, dashboardTitle } = useScheduledEmailDialogContext();
29
+ const isWidget = !!widget && !!insight;
30
+ const defaultUser = convertCurrentUserToWorkspaceUser(users ?? [], currentUser);
31
+ const defaultRecipient = externalRecipientOverride
32
+ ? convertExternalRecipientToAutomationRecipient(externalRecipientOverride)
33
+ : convertCurrentUserToAutomationRecipient(users ?? [], currentUser);
34
+ const firstChannel = notificationChannels[0]?.id;
35
+ const [editedAutomation, setEditedAutomation] = useState(scheduledExportToEdit ??
36
+ newAutomationMetadataObjectDefinition(isWidget
37
+ ? {
38
+ timezone,
39
+ dashboardId: dashboardId,
40
+ notificationChannel: firstChannel,
41
+ insight,
42
+ widget,
43
+ recipient: defaultRecipient,
44
+ widgetFilters: effectiveWidgetFilters,
45
+ widgetFiltersWithInsight: effectiveWidgetFiltersWithInsight,
46
+ dashboardFilters: effectiveDashboardFilters,
47
+ visibleFiltersMetadata: effectiveVisibleWidgetFilters,
48
+ defaultPdfPageSize,
49
+ evaluationMode: "PER_RECIPIENT",
50
+ targetTabId,
51
+ parametersByTab: parametersByTabForNewAutomation,
52
+ }
53
+ : {
54
+ timezone,
55
+ dashboardId: dashboardId,
56
+ notificationChannel: firstChannel,
57
+ title: dashboardTitle,
58
+ recipient: defaultRecipient,
59
+ dashboardFilters: effectiveDashboardFilters,
60
+ filtersByTab: effectiveDashboardFiltersByTab,
61
+ visibleFiltersMetadata: effectiveVisibleDashboardFilters,
62
+ visibleFiltersByTab: effectiveVisibleDashboardFiltersByTab,
63
+ defaultPdfPageSize,
64
+ evaluationMode: "PER_RECIPIENT",
65
+ parametersByTab: parametersByTabForNewAutomation,
66
+ }));
67
+ const [originalAutomation] = useState(editedAutomation);
68
+ const [isCronValid, setIsCronValid] = useState(true);
69
+ const [isTitleValid, setIsTitleValid] = useState(true);
70
+ const [isSubjectValid, setIsSubjectValid] = useState(true);
71
+ const [isOnMessageValid, setIsOnMessageValid] = useState(true);
72
+ const onTitleChange = (value, isValid) => {
73
+ setIsTitleValid(isValid);
74
+ setEditedAutomation((s) => ({ ...s, title: value }));
75
+ };
76
+ const onRecurrenceChange = (cronExpression, startDate, isValid) => {
77
+ setIsCronValid(isValid);
78
+ setEditedAutomation((s) => ({
79
+ ...s,
80
+ schedule: {
81
+ ...s.schedule,
82
+ cron: cronExpression,
83
+ firstRun: toModifiedISOStringToTimezone(startDate ?? new Date(), timezone).iso,
84
+ },
85
+ }));
86
+ };
87
+ const onEvaluationModeChange = (isShared) => {
88
+ setEditedAutomation((s) => ({
89
+ ...s,
90
+ evaluationMode: isShared ? "SHARED" : "PER_RECIPIENT",
91
+ }));
92
+ };
93
+ const onDestinationChange = (notificationChannelId) => {
94
+ setEditedAutomation((s) => ({
95
+ ...s,
96
+ notificationChannel: notificationChannelId,
97
+ }));
98
+ };
99
+ const onRecipientsChange = (updatedRecipients) => {
100
+ setEditedAutomation((s) => ({
101
+ ...s,
102
+ recipients: updatedRecipients,
103
+ }));
104
+ };
105
+ const onSubjectChange = (value, isValid) => {
106
+ setIsSubjectValid(isValid);
107
+ setEditedAutomation((s) => ({
108
+ ...s,
109
+ details: {
110
+ ...s.details,
111
+ subject: value,
112
+ },
113
+ }));
114
+ };
115
+ const onMessageChange = (value, isValid) => {
116
+ setIsOnMessageValid(isValid);
117
+ setEditedAutomation((s) => ({
118
+ ...s,
119
+ details: {
120
+ ...s.details,
121
+ message: value,
122
+ },
123
+ }));
124
+ };
125
+ return {
126
+ editedAutomation,
127
+ setEditedAutomation,
128
+ originalAutomation,
129
+ defaultRecipient,
130
+ defaultUser,
131
+ onTitleChange,
132
+ onRecurrenceChange,
133
+ onEvaluationModeChange,
134
+ onDestinationChange,
135
+ onRecipientsChange,
136
+ onSubjectChange,
137
+ onMessageChange,
138
+ isCronValid,
139
+ isTitleValid,
140
+ isSubjectValid,
141
+ isOnMessageValid,
142
+ };
143
+ }
144
+ function newAutomationMetadataObjectDefinition({ timezone, dashboardId, notificationChannel, title, insight, widget, recipient, dashboardFilters, filtersByTab, widgetFilters, widgetFiltersWithInsight, visibleFiltersMetadata, visibleFiltersByTab, defaultPdfPageSize, evaluationMode, targetTabId, parametersByTab, }) {
145
+ const { firstRun, cron } = toNormalizedFirstRunAndCron(timezone);
146
+ const exportDefinition = widget && insight
147
+ ? newWidgetExportDefinitionMetadataObjectDefinition({
148
+ insight,
149
+ widget,
150
+ dashboardId,
151
+ format: "PNG",
152
+ widgetFilters,
153
+ widgetFiltersWithInsight,
154
+ dashboardFilters,
155
+ defaultPdfPageSize,
156
+ })
157
+ : newDashboardExportDefinitionMetadataObjectDefinition({
158
+ dashboardId,
159
+ dashboardTitle: title ?? "",
160
+ dashboardFilters,
161
+ filtersByTab,
162
+ format: "PDF",
163
+ });
164
+ let metadataObj = visibleFiltersMetadata || visibleFiltersByTab
165
+ ? {
166
+ metadata: {
167
+ ...(visibleFiltersMetadata ? { visibleFilters: visibleFiltersMetadata } : {}),
168
+ ...(visibleFiltersByTab ? { visibleFiltersByTab } : {}),
169
+ },
170
+ }
171
+ : {};
172
+ if (targetTabId) {
173
+ metadataObj = {
174
+ ...metadataObj,
175
+ metadata: {
176
+ ...metadataObj.metadata,
177
+ targetTabIdentifier: targetTabId,
178
+ },
179
+ };
180
+ }
181
+ const automation = {
182
+ type: "automation",
183
+ title: undefined,
184
+ description: undefined,
185
+ tags: [],
186
+ schedule: {
187
+ timezone: timezone ?? getUserTimezone().identifier,
188
+ firstRun,
189
+ cron,
190
+ },
191
+ details: {
192
+ message: "",
193
+ subject: "",
194
+ },
195
+ exportDefinitions: [{ ...exportDefinition }],
196
+ recipients: [recipient],
197
+ evaluationMode,
198
+ notificationChannel,
199
+ dashboard: dashboardId ? { id: dashboardId } : undefined,
200
+ ...metadataObj,
201
+ };
202
+ return parametersByTab ? setExportParametersByTab(automation, parametersByTab) : automation;
203
+ }
@@ -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
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"DefaultFilterBarContainer.d.ts","sourceRoot":"","sources":["../../../../src/presentation/filterBar/filterBar/DefaultFilterBarContainer.tsx"],"names":[],"mappings":"AAEA,OAAO,EAEH,KAAK,SAAS,EAOjB,MAAM,OAAO,CAAC;AAybf;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAA;CAAE,2CAQ/E"}
1
+ {"version":3,"file":"DefaultFilterBarContainer.d.ts","sourceRoot":"","sources":["../../../../src/presentation/filterBar/filterBar/DefaultFilterBarContainer.tsx"],"names":[],"mappings":"AAEA,OAAO,EAEH,KAAK,SAAS,EAOjB,MAAM,OAAO,CAAC;AAgcf;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAA;CAAE,2CAQ/E"}
@@ -29,7 +29,8 @@ import { useExecutionTimestampMessage } from "./useExecutionTimestampMessage.js"
29
29
  const Measure = defaultImport(DefaultMeasure);
30
30
  function DefaultFilterBarContainerCore({ children }) {
31
31
  const { rows, height, isFilterBarExpanded, scrollable, setFilterBarExpanded, setCalculatedRows } = useFilterBarState();
32
- const dropRef = useFilterExpansionByDragAndDrop(rows.length > 1, isFilterBarExpanded, setFilterBarExpanded);
32
+ const hasMultipleRows = rows.length > 1;
33
+ const dropRef = useFilterExpansionByDragAndDrop(hasMultipleRows, isFilterBarExpanded, setFilterBarExpanded);
33
34
  const isWorkingFilterContextChanged = useDashboardSelector(selectIsWorkingFilterContextChanged);
34
35
  const isApplyAllAtOnceEnabledAndSet = useDashboardSelector(selectIsApplyFiltersAllAtOnceEnabledAndSet);
35
36
  const filtersWithInvalidSelection = useDashboardSelector(selectNamesOfFiltersWithInvalidSelection);
@@ -53,9 +54,11 @@ function DefaultFilterBarContainerCore({ children }) {
53
54
  return;
54
55
  }
55
56
  setCollapseAnnouncement("");
56
- setFilterBarExpanded(true);
57
- setExpandedAutomatically(true);
58
- }, [setFilterBarExpanded]);
57
+ if (hasMultipleRows && !isFilterBarExpanded) {
58
+ setFilterBarExpanded(true);
59
+ setExpandedAutomatically(true);
60
+ }
61
+ }, [hasMultipleRows, isFilterBarExpanded, setFilterBarExpanded]);
59
62
  const onContainerBlur = useCallback(() => {
60
63
  if (isFocusVisible() && expandedAutomatically) {
61
64
  setFilterBarExpanded(false);
@@ -84,7 +87,10 @@ function DefaultFilterBarContainerCore({ children }) {
84
87
  ariaLabel: bubbleText,
85
88
  }, label: intl.formatMessage({ id: "apply" }), variant: "primary", onClick: applyAllDashboardFilters, isDisabled: hasInvalidFilterSelections }) })) : null, _jsx(FilterViews, {})
86
89
  ] })
87
- ] }), _jsx(ShowAllFiltersButton, { isFilterBarExpanded: isFilterBarExpanded, isVisible: rows.length > 1, onToggle: (isExpanded) => setFilterBarExpanded(isExpanded) }), isInEditMode ? _jsx(FlexibleBulletsBar, {}) : null] }), isWorkingFilterContextChanged && isApplyAllAtOnceEnabledAndSet ? (_jsx("div", { "aria-hidden": "true", className: "filters-message", style: { marginTop: rows.length > 1 ? "35px" : "10px" }, children: _jsx(Message, { type: "progress", children: _jsx(FormattedMessage, { id: "filterBar.unappliedFiltersNotification", values: {
90
+ ] }), _jsx(ShowAllFiltersButton, { isFilterBarExpanded: isFilterBarExpanded, isVisible: rows.length > 1, onToggle: (isExpanded) => {
91
+ setFilterBarExpanded(isExpanded);
92
+ setExpandedAutomatically(false);
93
+ } }), isInEditMode ? _jsx(FlexibleBulletsBar, {}) : null] }), isWorkingFilterContextChanged && isApplyAllAtOnceEnabledAndSet ? (_jsx("div", { "aria-hidden": "true", className: "filters-message", style: { marginTop: rows.length > 1 ? "35px" : "10px" }, children: _jsx(Message, { type: "progress", children: _jsx(FormattedMessage, { id: "filterBar.unappliedFiltersNotification", values: {
88
94
  link: (chunks) => (_jsx("strong", { children: _jsxs(BubbleHoverTrigger, { showDelay: 100, hideDelay: 0, children: [
89
95
  _jsx(UiButton, { variant: "link", onClick: applyAllDashboardFilters, label: chunks, isDisabled: hasInvalidFilterSelections }), hasInvalidFilterSelections ? (_jsx(Bubble, { children: bubbleText })) : null] }) })),
90
96
  } }) }) })) : null, showExecutionTimestampMessage ? (_jsx("div", { className: "filters-message", style: { marginTop: rows.length > 1 ? "35px" : "10px" }, children: _jsxs(Message, { type: "progress", children: [_jsx(FormattedMessage, { id: "filterBar.executionTimestampNotificationMessage", values: {
@@ -5,7 +5,7 @@
5
5
  "toolPackages": [
6
6
  {
7
7
  "packageName": "@microsoft/api-extractor",
8
- "packageVersion": "7.58.9"
8
+ "packageVersion": "7.58.12"
9
9
  }
10
10
  ]
11
11
  }
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.2",
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-base": "11.50.0-alpha.2",
64
+ "@gooddata/sdk-backend-spi": "11.50.0-alpha.2",
65
+ "@gooddata/sdk-model": "11.50.0-alpha.2",
66
+ "@gooddata/sdk-ui": "11.50.0-alpha.2",
67
+ "@gooddata/sdk-ui-charts": "11.50.0-alpha.2",
68
+ "@gooddata/sdk-ui-ext": "11.50.0-alpha.2",
69
+ "@gooddata/sdk-ui-geo": "11.50.0-alpha.2",
70
+ "@gooddata/sdk-ui-filters": "11.50.0-alpha.2",
71
+ "@gooddata/sdk-ui-kit": "11.50.0-alpha.2",
72
+ "@gooddata/sdk-ui-pivot": "11.50.0-alpha.2",
73
+ "@gooddata/sdk-ui-semantic-search": "11.50.0-alpha.2",
74
+ "@gooddata/sdk-ui-theme-provider": "11.50.0-alpha.2",
75
+ "@gooddata/util": "11.50.0-alpha.2",
76
+ "@gooddata/sdk-ui-vis-commons": "11.50.0-alpha.2"
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/i18n-toolkit": "11.50.0-alpha.2",
123
+ "@gooddata/eslint-config": "11.50.0-alpha.2",
124
+ "@gooddata/oxlint-config": "11.50.0-alpha.2",
125
+ "@gooddata/reference-workspace": "11.50.0-alpha.2",
126
+ "@gooddata/sdk-backend-mockingbird": "11.50.0-alpha.2",
127
+ "@gooddata/stylelint-config": "11.50.0-alpha.2"
128
128
  },
129
129
  "peerDependencies": {
130
130
  "react": "^18.0.0 || ^19.0.0",
@@ -12865,7 +12865,7 @@ a.gd-button-link:hover .gd-button-text, a.gd-button-link-dimmed:hover .gd-button
12865
12865
  }
12866
12866
 
12867
12867
  .gd-date-filter-form-buttons .gd-date-filter-form-buttons-container .gd-date-filter-form-button {
12868
- padding: 0 10px 0 10px;
12868
+ padding: 0 30px 0 10px;
12869
12869
  border: 0;
12870
12870
  height: 23px;
12871
12871
  }