@gooddata/sdk-ui-dashboard 11.50.0-alpha.0 → 11.50.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE +216 -203
- package/esm/__version.d.ts +1 -1
- package/esm/__version.js +1 -1
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useEditScheduledEmail.d.ts +6 -6
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useEditScheduledEmail.d.ts.map +1 -1
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useEditScheduledEmail.js +65 -534
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailEffectiveFilters.d.ts +38 -0
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailEffectiveFilters.d.ts.map +1 -0
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailEffectiveFilters.js +61 -0
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailExportSettings.d.ts +57 -0
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailExportSettings.d.ts.map +1 -0
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailExportSettings.js +241 -0
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailFormState.d.ts +55 -0
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailFormState.d.ts.map +1 -0
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailFormState.js +203 -0
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailFormValidity.d.ts +21 -0
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailFormValidity.d.ts.map +1 -0
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailFormValidity.js +52 -0
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/utils/exportDefinitions.d.ts +27 -0
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/utils/exportDefinitions.d.ts.map +1 -0
- package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/utils/exportDefinitions.js +95 -0
- package/esm/presentation/filterBar/filterBar/DefaultFilterBarContainer.d.ts.map +1 -1
- package/esm/presentation/filterBar/filterBar/DefaultFilterBarContainer.js +11 -5
- package/esm/tsdoc-metadata.json +1 -1
- package/package.json +21 -21
- package/styles/css/main.css +1 -1
|
@@ -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;
|
|
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
|
|
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
|
-
|
|
57
|
-
|
|
58
|
-
|
|
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) =>
|
|
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: {
|
package/esm/tsdoc-metadata.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gooddata/sdk-ui-dashboard",
|
|
3
|
-
"version": "11.50.0-alpha.
|
|
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.
|
|
64
|
-
"@gooddata/sdk-backend-spi": "11.50.0-alpha.
|
|
65
|
-
"@gooddata/sdk-model": "11.50.0-alpha.
|
|
66
|
-
"@gooddata/sdk-ui
|
|
67
|
-
"@gooddata/sdk-ui": "11.50.0-alpha.
|
|
68
|
-
"@gooddata/sdk-ui-ext": "11.50.0-alpha.
|
|
69
|
-
"@gooddata/sdk-ui-
|
|
70
|
-
"@gooddata/sdk-ui-
|
|
71
|
-
"@gooddata/sdk-ui-
|
|
72
|
-
"@gooddata/sdk-ui-pivot": "11.50.0-alpha.
|
|
73
|
-
"@gooddata/sdk-ui-semantic-search": "11.50.0-alpha.
|
|
74
|
-
"@gooddata/sdk-ui-theme-provider": "11.50.0-alpha.
|
|
75
|
-
"@gooddata/
|
|
76
|
-
"@gooddata/
|
|
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/
|
|
123
|
-
"@gooddata/
|
|
124
|
-
"@gooddata/oxlint-config": "11.50.0-alpha.
|
|
125
|
-
"@gooddata/reference-workspace": "11.50.0-alpha.
|
|
126
|
-
"@gooddata/
|
|
127
|
-
"@gooddata/
|
|
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",
|
package/styles/css/main.css
CHANGED
|
@@ -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
|
|
12868
|
+
padding: 0 30px 0 10px;
|
|
12869
12869
|
border: 0;
|
|
12870
12870
|
height: 23px;
|
|
12871
12871
|
}
|