@gooddata/sdk-ui-dashboard 11.50.0-alpha.2 → 11.50.0-alpha.3

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 (38) hide show
  1. package/esm/__version.d.ts +1 -1
  2. package/esm/__version.js +1 -1
  3. package/esm/_staging/dateFilterConfig/dateFilterConfigConverters.d.ts +1 -9
  4. package/esm/_staging/dateFilterConfig/dateFilterConfigConverters.d.ts.map +1 -1
  5. package/esm/_staging/dateFilterConfig/dateFilterConfigConverters.js +3 -88
  6. package/esm/_staging/dateFilterConfig/dateFilterOptionMapping.d.ts +1 -33
  7. package/esm/_staging/dateFilterConfig/dateFilterOptionMapping.d.ts.map +1 -1
  8. package/esm/_staging/dateFilterConfig/dateFilterOptionMapping.js +3 -260
  9. package/esm/_staging/dateFilterConfig/defaultConfig.d.ts +1 -11
  10. package/esm/_staging/dateFilterConfig/defaultConfig.d.ts.map +1 -1
  11. package/esm/_staging/dateFilterConfig/defaultConfig.js +3 -436
  12. package/esm/model/store/config/configSelectors.d.ts.map +1 -1
  13. package/esm/model/store/config/configSelectors.js +2 -9
  14. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useEditScheduledEmail.d.ts.map +1 -1
  15. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useEditScheduledEmail.js +9 -162
  16. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailEffectiveFilters.d.ts +7 -7
  17. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailEffectiveFilters.js +7 -7
  18. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailFilters.d.ts +35 -0
  19. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailFilters.d.ts.map +1 -0
  20. package/esm/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailFilters.js +195 -0
  21. package/esm/presentation/automations/shared/dateFilterConfig/dateFilterConfigConverters.d.ts +1 -9
  22. package/esm/presentation/automations/shared/dateFilterConfig/dateFilterConfigConverters.d.ts.map +1 -1
  23. package/esm/presentation/automations/shared/dateFilterConfig/dateFilterConfigConverters.js +3 -88
  24. package/esm/presentation/automations/shared/dateFilterConfig/dateFilterOptionMapping.d.ts +1 -33
  25. package/esm/presentation/automations/shared/dateFilterConfig/dateFilterOptionMapping.d.ts.map +1 -1
  26. package/esm/presentation/automations/shared/dateFilterConfig/dateFilterOptionMapping.js +3 -260
  27. package/esm/presentation/automations/shared/dateFilterConfig/defaultConfig.d.ts +1 -11
  28. package/esm/presentation/automations/shared/dateFilterConfig/defaultConfig.d.ts.map +1 -1
  29. package/esm/presentation/automations/shared/dateFilterConfig/defaultConfig.js +3 -436
  30. package/esm/presentation/dashboardList/DashboardList.d.ts.map +1 -1
  31. package/esm/presentation/dashboardList/DashboardList.js +6 -0
  32. package/esm/presentation/widget/common/InsightDropdown.d.ts.map +1 -1
  33. package/esm/presentation/widget/common/InsightDropdown.js +14 -0
  34. package/esm/presentation/widget/common/configuration/ConfigurationBubble.d.ts.map +1 -1
  35. package/esm/presentation/widget/common/configuration/ConfigurationBubble.js +2 -0
  36. package/esm/presentation/widget/insightMenu/DefaultDashboardInsightMenu/DashboardInsightMenu/DashboardInsightMenuBubble.d.ts.map +1 -1
  37. package/esm/presentation/widget/insightMenu/DefaultDashboardInsightMenu/DashboardInsightMenu/DashboardInsightMenuBubble.js +1 -1
  38. package/package.json +21 -21
@@ -1,20 +1,18 @@
1
1
  // (C) 2019-2026 GoodData Corporation
2
2
  import { useCallback, useRef } from "react";
3
- import { DEFAULT_CSV_DELIMITER, isExportDefinitionDashboardRequestPayload, isExportDefinitionVisualizationObjectRequestPayload, isInsightWidget, } from "@gooddata/sdk-model";
3
+ import { DEFAULT_CSV_DELIMITER, } from "@gooddata/sdk-model";
4
4
  import { getAutomationExportParametersByTab, setExportParametersByTab, } from "../../../../../_staging/automation/index.js";
5
5
  import { useAutomationsContext } from "../../../contexts/AutomationsContext.js";
6
6
  import { useScheduledEmailDialogContext } from "../../../contexts/ScheduledEmailDialogContext.js";
7
- import { getDefaultSelectedFiltersFromFiltersByTab } from "../../../shared/automationFilters/useAutomationFiltersSelect.js";
8
- import { getAppliedDashboardFilters, getAppliedWidgetFilters, getVisibleFiltersByFilters, getVisibleFiltersByFiltersByTab, } from "../../../shared/automationFilters/utils.js";
9
7
  import { toNormalizedStartDate } from "../../utils/date.js";
10
8
  import { useScheduledEmailEffectiveFilters } from "./useScheduledEmailEffectiveFilters.js";
11
9
  import { useScheduledEmailExportSettings } from "./useScheduledEmailExportSettings.js";
10
+ import { useScheduledEmailFilters } from "./useScheduledEmailFilters.js";
12
11
  import { useScheduledEmailFormState } from "./useScheduledEmailFormState.js";
13
12
  import { useScheduledEmailFormValidity } from "./useScheduledEmailFormValidity.js";
14
13
  export function useEditScheduledEmail({ scheduledExportToEdit, notificationChannels, insight, widget, users, editedAutomationFilters, dashboardFilters, editedAutomationFiltersByTab, maxAutomationsRecipients, setEditedAutomationFilters, setEditedAutomationFiltersByTab, availableFiltersAsVisibleFilters, storeFilters, setStoreFilters, filtersForNewAutomation, externalRecipientOverride, defaultPdfPageSize, filtersDataByTab, availableFiltersAsVisibleFiltersByTab, }) {
15
14
  const { settings, features: { enableAutomationEvaluationMode }, } = useAutomationsContext();
16
- const { dashboardId, dashboardTitle, hiddenFilters: dashboardHiddenFilters, commonDateFilterId, widgetLocalIdToTabIdMap: widgetTabMap, } = useScheduledEmailDialogContext();
17
- const isWidget = !!widget && !!insight;
15
+ const { dashboardId, dashboardTitle, widgetLocalIdToTabIdMap: widgetTabMap, } = useScheduledEmailDialogContext();
18
16
  // Dashboard
19
17
  const resolvedDefaultCsvDelimiter = settings?.exportCsvCustomDelimiter ?? DEFAULT_CSV_DELIMITER;
20
18
  const areDashboardFiltersChanged = !!dashboardFilters;
@@ -75,170 +73,19 @@ export function useEditScheduledEmail({ scheduledExportToEdit, notificationChann
75
73
  resolvedDefaultCsvDelimiter,
76
74
  latestParametersWireRef,
77
75
  });
78
- const onFiltersChange = useCallback((filters, storeFiltersParam) => {
79
- setEditedAutomationFilters(filters);
80
- const shouldStoreFilters = storeFiltersParam ?? storeFilters;
81
- if (isWidget) {
82
- if (!isInsightWidget(widget)) {
83
- return;
84
- }
85
- setEditedAutomation((s) => {
86
- const appliedDashboardFilters = getAppliedDashboardFilters(filters, dashboardHiddenFilters, true);
87
- const appliedWidgetFiltersWithInsight = getAppliedWidgetFilters(filters, dashboardHiddenFilters, widget, insight, commonDateFilterId, true);
88
- const appliedWidgetFiltersWithoutInsight = getAppliedWidgetFilters(filters, dashboardHiddenFilters, widget, insight, commonDateFilterId, false);
89
- const visibleFilters = getVisibleFiltersByFilters(filters, availableFiltersAsVisibleFilters, true);
90
- return {
91
- ...s,
92
- exportDefinitions: s.exportDefinitions?.map((exportDefinition) => {
93
- if (isExportDefinitionVisualizationObjectRequestPayload(exportDefinition.requestPayload)) {
94
- const format = exportDefinition.requestPayload.format;
95
- const shouldUseWidgetFiltersWithInsight = format === "CSV";
96
- const shouldUseWidgetFiltersWithoutInsight = format === "CSV_RAW";
97
- const appliedFilters = shouldUseWidgetFiltersWithInsight
98
- ? appliedWidgetFiltersWithInsight
99
- : shouldUseWidgetFiltersWithoutInsight
100
- ? appliedWidgetFiltersWithoutInsight
101
- : appliedDashboardFilters;
102
- return {
103
- ...exportDefinition,
104
- requestPayload: {
105
- ...exportDefinition.requestPayload,
106
- content: {
107
- ...exportDefinition.requestPayload.content,
108
- filters: appliedFilters,
109
- },
110
- },
111
- };
112
- }
113
- else {
114
- return exportDefinition;
115
- }
116
- }),
117
- metadata: {
118
- ...s.metadata,
119
- visibleFilters,
120
- },
121
- };
122
- });
123
- }
124
- else {
125
- setEditedAutomation((s) => {
126
- const appliedFilters = getAppliedDashboardFilters(filters, dashboardHiddenFilters, shouldStoreFilters);
127
- const visibleFilters = getVisibleFiltersByFilters(filters, availableFiltersAsVisibleFilters, shouldStoreFilters);
128
- return {
129
- ...s,
130
- exportDefinitions: s.exportDefinitions?.map((exportDefinition) => {
131
- if (isExportDefinitionDashboardRequestPayload(exportDefinition.requestPayload)) {
132
- return {
133
- ...exportDefinition,
134
- requestPayload: {
135
- ...exportDefinition.requestPayload,
136
- content: {
137
- ...exportDefinition.requestPayload.content,
138
- filters: appliedFilters,
139
- },
140
- },
141
- };
142
- }
143
- else {
144
- return exportDefinition;
145
- }
146
- }),
147
- metadata: {
148
- ...s.metadata,
149
- visibleFilters,
150
- },
151
- };
152
- });
153
- }
154
- }, [
155
- setEditedAutomationFilters,
76
+ const { onFiltersChange, onFiltersByTabChange, onApplyCurrentFilters, onStoreFiltersChange } = useScheduledEmailFilters({
156
77
  setEditedAutomation,
157
- dashboardHiddenFilters,
158
- availableFiltersAsVisibleFilters,
159
- storeFilters,
160
78
  widget,
161
79
  insight,
162
- isWidget,
163
- commonDateFilterId,
164
- ]);
165
- // Callback for per-tab filter changes - updates state AND syncs to export definitions
166
- const onFiltersByTabChange = useCallback((newFiltersByTab, storeFiltersParam) => {
167
- // Update the editedFiltersByTab state
168
- setEditedAutomationFiltersByTab?.(newFiltersByTab);
169
- const shouldStoreFilters = storeFiltersParam ?? storeFilters;
170
- const newEffectiveFiltersByTab = shouldStoreFilters
171
- ? Object.entries(newFiltersByTab).reduce((acc, [tabId, filters]) => {
172
- const tabHiddenFilters = filtersDataByTab?.find((tab) => tab.tabId === tabId)?.hiddenFilters ?? [];
173
- const appliedFilters = getAppliedDashboardFilters(filters ?? [], tabHiddenFilters, true);
174
- if (appliedFilters) {
175
- acc[tabId] = appliedFilters;
176
- }
177
- return acc;
178
- }, {})
179
- : undefined;
180
- const newVisibleFiltersByTab = getVisibleFiltersByFiltersByTab(newFiltersByTab, availableFiltersAsVisibleFiltersByTab, shouldStoreFilters);
181
- // Sync to export definitions AND metadata
182
- setEditedAutomation((s) => ({
183
- ...s,
184
- exportDefinitions: s.exportDefinitions?.map((exportDefinition) => {
185
- if (isExportDefinitionDashboardRequestPayload(exportDefinition.requestPayload)) {
186
- return {
187
- ...exportDefinition,
188
- requestPayload: {
189
- ...exportDefinition.requestPayload,
190
- content: {
191
- ...exportDefinition.requestPayload.content,
192
- filtersByTab: newEffectiveFiltersByTab,
193
- },
194
- },
195
- };
196
- }
197
- return exportDefinition;
198
- }),
199
- metadata: {
200
- ...s.metadata,
201
- visibleFiltersByTab: newVisibleFiltersByTab,
202
- },
203
- }));
204
- }, [
80
+ setEditedAutomationFilters,
205
81
  setEditedAutomationFiltersByTab,
206
- storeFilters,
207
- setEditedAutomation,
82
+ availableFiltersAsVisibleFilters,
208
83
  availableFiltersAsVisibleFiltersByTab,
209
84
  filtersDataByTab,
210
- ]);
211
- const onApplyCurrentFilters = useCallback(() => {
212
- // Widget schedules should never use per-tab filters, only dashboard schedules can have tabs
213
- const filtersByTabForNewAutomation = widget
214
- ? undefined
215
- : getDefaultSelectedFiltersFromFiltersByTab(filtersDataByTab);
216
- if (filtersByTabForNewAutomation) {
217
- onFiltersByTabChange(filtersByTabForNewAutomation);
218
- }
219
- else {
220
- onFiltersChange(filtersForNewAutomation ?? [], widget ? true : storeFilters);
221
- }
222
- }, [
223
- filtersForNewAutomation,
224
85
  storeFilters,
225
- onFiltersChange,
226
- onFiltersByTabChange,
227
- widget,
228
- filtersDataByTab,
229
- ]);
230
- const onStoreFiltersChange = useCallback((value, filters, filtersByTabParam) => {
231
- setStoreFilters(value);
232
- // If filtersByTab is provided, use onFiltersByTabChange, otherwise use onFiltersChange
233
- if (filtersByTabParam) {
234
- // Trigger filtersByTab change which handles the sync
235
- onFiltersByTabChange(filtersByTabParam, value);
236
- }
237
- if (filters) {
238
- // Use regular filters change
239
- onFiltersChange(filters, value);
240
- }
241
- }, [onFiltersChange, onFiltersByTabChange, setStoreFilters]);
86
+ setStoreFilters,
87
+ filtersForNewAutomation,
88
+ });
242
89
  const startDate = toNormalizedStartDate(editedAutomation.schedule?.firstRun, editedAutomation.schedule?.timezone);
243
90
  const { isSubmitDisabled, validationErrorMessage, isParentValid, allowExternalRecipients, allowOnlyLoggedUserRecipients, } = useScheduledEmailFormValidity({
244
91
  editedAutomation,
@@ -12,16 +12,16 @@ export interface IUseScheduledEmailEffectiveFiltersProps {
12
12
  }
13
13
  /**
14
14
  * Derives the effective-filters cluster consumed early by `useScheduledEmailFormState` (draft init) and
15
- * `useScheduledEmailExportSettings`, and later still by the (still-in-parent) filters handlers.
15
+ * `useScheduledEmailExportSettings`, and later still by the `useScheduledEmailFilters` handlers.
16
16
  *
17
17
  * Filters slice A of 2. Reads `hiddenFilters`/`commonDateFilterId`/`exportParametersByTab` from
18
- * {@link useScheduledEmailDialogContext} internally, same as the parent (`useEditScheduledEmail`) does
19
- * today. `isWidget` is re-derived internally (`!!widget && !!insight`) — if the parent still needs it for
20
- * the filters handlers, it keeps its own copy, a harmless identical re-derivation (mirrors the sibling
21
- * hooks).
18
+ * {@link useScheduledEmailDialogContext} internally, as does `useScheduledEmailFilters` — the parent
19
+ * (`useEditScheduledEmail`) no longer reads them itself. `isWidget` is re-derived internally
20
+ * (`!!widget && !!insight`) — `useScheduledEmailFilters` keeps its own copy, a harmless identical
21
+ * re-derivation (mirrors the sibling hooks).
22
22
  *
23
- * Slice B (`useScheduledEmailFilters`, next PR) will own the four filters handlers, which run after
24
- * `formState` (they need `setEditedAutomation`); this derivation cluster runs before it, hence the split.
23
+ * `useScheduledEmailFilters` (slice B) owns the four filters handlers, which run after `formState` (they
24
+ * need `setEditedAutomation`); this derivation cluster runs before it, hence the split.
25
25
  *
26
26
  * @internal
27
27
  */
@@ -5,16 +5,16 @@ import { shouldStoreExportParameters } from "../../../shared/automationFilters/a
5
5
  import { getAppliedDashboardFilters, getAppliedWidgetFilters, getVisibleFiltersByFilters, getVisibleFiltersByFiltersByTab, } from "../../../shared/automationFilters/utils.js";
6
6
  /**
7
7
  * Derives the effective-filters cluster consumed early by `useScheduledEmailFormState` (draft init) and
8
- * `useScheduledEmailExportSettings`, and later still by the (still-in-parent) filters handlers.
8
+ * `useScheduledEmailExportSettings`, and later still by the `useScheduledEmailFilters` handlers.
9
9
  *
10
10
  * Filters slice A of 2. Reads `hiddenFilters`/`commonDateFilterId`/`exportParametersByTab` from
11
- * {@link useScheduledEmailDialogContext} internally, same as the parent (`useEditScheduledEmail`) does
12
- * today. `isWidget` is re-derived internally (`!!widget && !!insight`) — if the parent still needs it for
13
- * the filters handlers, it keeps its own copy, a harmless identical re-derivation (mirrors the sibling
14
- * hooks).
11
+ * {@link useScheduledEmailDialogContext} internally, as does `useScheduledEmailFilters` — the parent
12
+ * (`useEditScheduledEmail`) no longer reads them itself. `isWidget` is re-derived internally
13
+ * (`!!widget && !!insight`) — `useScheduledEmailFilters` keeps its own copy, a harmless identical
14
+ * re-derivation (mirrors the sibling hooks).
15
15
  *
16
- * Slice B (`useScheduledEmailFilters`, next PR) will own the four filters handlers, which run after
17
- * `formState` (they need `setEditedAutomation`); this derivation cluster runs before it, hence the split.
16
+ * `useScheduledEmailFilters` (slice B) owns the four filters handlers, which run after `formState` (they
17
+ * need `setEditedAutomation`); this derivation cluster runs before it, hence the split.
18
18
  *
19
19
  * @internal
20
20
  */
@@ -0,0 +1,35 @@
1
+ import { type Dispatch, type SetStateAction } from "react";
2
+ import { type FilterContextItem, type IAutomationMetadataObjectDefinition, type IAutomationVisibleFilter, type IInsight, type IWidget } from "@gooddata/sdk-model";
3
+ import type { IAutomationFiltersTab } from "../../../../../model/store/filtering/types.js";
4
+ export interface IUseScheduledEmailFiltersProps {
5
+ setEditedAutomation: Dispatch<SetStateAction<IAutomationMetadataObjectDefinition>>;
6
+ widget?: IWidget;
7
+ insight?: IInsight;
8
+ setEditedAutomationFilters: (filters: FilterContextItem[]) => void;
9
+ setEditedAutomationFiltersByTab?: (filters: Record<string, FilterContextItem[]>) => void;
10
+ availableFiltersAsVisibleFilters?: IAutomationVisibleFilter[] | undefined;
11
+ availableFiltersAsVisibleFiltersByTab?: Record<string, IAutomationVisibleFilter[]>;
12
+ filtersDataByTab?: IAutomationFiltersTab[] | undefined;
13
+ storeFilters?: boolean;
14
+ setStoreFilters: (storeFilters: boolean) => void;
15
+ filtersForNewAutomation: FilterContextItem[];
16
+ }
17
+ /**
18
+ * Owns the four scheduled-email filters handlers: they update the edited filters state and sync the
19
+ * result into the draft's export definitions and `metadata.visibleFilters`/`visibleFiltersByTab`.
20
+ *
21
+ * Filters slice B of 2. Runs after `useScheduledEmailFormState` because the handlers need
22
+ * `setEditedAutomation`; the derivation cluster in {@link useScheduledEmailEffectiveFilters} (slice A)
23
+ * has to run before it, which is why the two are separate hooks. Reads
24
+ * `hiddenFilters`/`commonDateFilterId` from {@link useScheduledEmailDialogContext} internally, same as
25
+ * slice A and as the parent (`useEditScheduledEmail`) did before.
26
+ *
27
+ * @internal
28
+ */
29
+ export declare function useScheduledEmailFilters({ setEditedAutomation, widget, insight, setEditedAutomationFilters, setEditedAutomationFiltersByTab, availableFiltersAsVisibleFilters, availableFiltersAsVisibleFiltersByTab, filtersDataByTab, storeFilters, setStoreFilters, filtersForNewAutomation }: IUseScheduledEmailFiltersProps): {
30
+ onFiltersChange: (filters: FilterContextItem[], storeFiltersParam?: boolean | undefined) => void;
31
+ onFiltersByTabChange: (newFiltersByTab: Record<string, FilterContextItem[]>, storeFiltersParam?: boolean | undefined) => void;
32
+ onApplyCurrentFilters: () => void;
33
+ onStoreFiltersChange: (value: boolean, filters?: FilterContextItem[] | undefined, filtersByTabParam?: Record<string, FilterContextItem[]> | undefined) => void;
34
+ };
35
+ //# sourceMappingURL=useScheduledEmailFilters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useScheduledEmailFilters.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/automations/scheduledEmail/DefaultScheduledEmailDialog/hooks/useScheduledEmailFilters.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,cAAc,EAAe,MAAM,OAAO,CAAC;AAExE,OAAO,EACH,KAAK,iBAAiB,EACtB,KAAK,mCAAmC,EACxC,KAAK,wBAAwB,EAC7B,KAAK,QAAQ,EACb,KAAK,OAAO,EAIf,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,+CAA+C,CAAC;AAU3F,MAAM,WAAW,8BAA8B;IAC3C,mBAAmB,EAAE,QAAQ,CAAC,cAAc,CAAC,mCAAmC,CAAC,CAAC,CAAC;IACnF,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,QAAQ,CAAC;IACnB,0BAA0B,EAAE,CAAC,OAAO,EAAE,iBAAiB,EAAE,KAAK,IAAI,CAAC;IACnE,+BAA+B,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC,KAAK,IAAI,CAAC;IACzF,gCAAgC,CAAC,EAAE,wBAAwB,EAAE,GAAG,SAAS,CAAC;IAC1E,qCAAqC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,EAAE,CAAC,CAAC;IACnF,gBAAgB,CAAC,EAAE,qBAAqB,EAAE,GAAG,SAAS,CAAC;IACvD,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,eAAe,EAAE,CAAC,YAAY,EAAE,OAAO,KAAK,IAAI,CAAC;IACjD,uBAAuB,EAAE,iBAAiB,EAAE,CAAC;CAChD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CAAC,EACrC,mBAAmB,EACnB,MAAM,EACN,OAAO,EACP,0BAA0B,EAC1B,+BAA+B,EAC/B,gCAAgC,EAChC,qCAAqC,EACrC,gBAAgB,EAChB,YAAY,EACZ,eAAe,EACf,uBAAuB,EAC1B,EAAE,8BAA8B;;;;;EAqPhC"}
@@ -0,0 +1,195 @@
1
+ // (C) 2026 GoodData Corporation
2
+ import { useCallback } from "react";
3
+ import { isExportDefinitionDashboardRequestPayload, isExportDefinitionVisualizationObjectRequestPayload, isInsightWidget, } from "@gooddata/sdk-model";
4
+ import { useScheduledEmailDialogContext } from "../../../contexts/ScheduledEmailDialogContext.js";
5
+ import { getDefaultSelectedFiltersFromFiltersByTab } from "../../../shared/automationFilters/useAutomationFiltersSelect.js";
6
+ import { getAppliedDashboardFilters, getAppliedWidgetFilters, getVisibleFiltersByFilters, getVisibleFiltersByFiltersByTab, } from "../../../shared/automationFilters/utils.js";
7
+ /**
8
+ * Owns the four scheduled-email filters handlers: they update the edited filters state and sync the
9
+ * result into the draft's export definitions and `metadata.visibleFilters`/`visibleFiltersByTab`.
10
+ *
11
+ * Filters slice B of 2. Runs after `useScheduledEmailFormState` because the handlers need
12
+ * `setEditedAutomation`; the derivation cluster in {@link useScheduledEmailEffectiveFilters} (slice A)
13
+ * has to run before it, which is why the two are separate hooks. Reads
14
+ * `hiddenFilters`/`commonDateFilterId` from {@link useScheduledEmailDialogContext} internally, same as
15
+ * slice A and as the parent (`useEditScheduledEmail`) did before.
16
+ *
17
+ * @internal
18
+ */
19
+ export function useScheduledEmailFilters({ setEditedAutomation, widget, insight, setEditedAutomationFilters, setEditedAutomationFiltersByTab, availableFiltersAsVisibleFilters, availableFiltersAsVisibleFiltersByTab, filtersDataByTab, storeFilters, setStoreFilters, filtersForNewAutomation, }) {
20
+ const { hiddenFilters: dashboardHiddenFilters, commonDateFilterId } = useScheduledEmailDialogContext();
21
+ // Re-derived locally (not passed as a prop) so that the `if (isWidget)` branch below narrows
22
+ // `widget`/`insight` via TS's aliased-condition control-flow analysis — this requires the boolean
23
+ // to be declared from those exact variables in this same scope, same as in the parent.
24
+ const isWidget = !!widget && !!insight;
25
+ const onFiltersChange = useCallback((filters, storeFiltersParam) => {
26
+ setEditedAutomationFilters(filters);
27
+ const shouldStoreFilters = storeFiltersParam ?? storeFilters;
28
+ if (isWidget) {
29
+ if (!isInsightWidget(widget)) {
30
+ return;
31
+ }
32
+ setEditedAutomation((s) => {
33
+ const appliedDashboardFilters = getAppliedDashboardFilters(filters, dashboardHiddenFilters, true);
34
+ const appliedWidgetFiltersWithInsight = getAppliedWidgetFilters(filters, dashboardHiddenFilters, widget, insight, commonDateFilterId, true);
35
+ const appliedWidgetFiltersWithoutInsight = getAppliedWidgetFilters(filters, dashboardHiddenFilters, widget, insight, commonDateFilterId, false);
36
+ const visibleFilters = getVisibleFiltersByFilters(filters, availableFiltersAsVisibleFilters, true);
37
+ return {
38
+ ...s,
39
+ exportDefinitions: s.exportDefinitions?.map((exportDefinition) => {
40
+ if (isExportDefinitionVisualizationObjectRequestPayload(exportDefinition.requestPayload)) {
41
+ const format = exportDefinition.requestPayload.format;
42
+ const shouldUseWidgetFiltersWithInsight = format === "CSV";
43
+ const shouldUseWidgetFiltersWithoutInsight = format === "CSV_RAW";
44
+ const appliedFilters = shouldUseWidgetFiltersWithInsight
45
+ ? appliedWidgetFiltersWithInsight
46
+ : shouldUseWidgetFiltersWithoutInsight
47
+ ? appliedWidgetFiltersWithoutInsight
48
+ : appliedDashboardFilters;
49
+ return {
50
+ ...exportDefinition,
51
+ requestPayload: {
52
+ ...exportDefinition.requestPayload,
53
+ content: {
54
+ ...exportDefinition.requestPayload.content,
55
+ filters: appliedFilters,
56
+ },
57
+ },
58
+ };
59
+ }
60
+ else {
61
+ return exportDefinition;
62
+ }
63
+ }),
64
+ metadata: {
65
+ ...s.metadata,
66
+ visibleFilters,
67
+ },
68
+ };
69
+ });
70
+ }
71
+ else {
72
+ setEditedAutomation((s) => {
73
+ const appliedFilters = getAppliedDashboardFilters(filters, dashboardHiddenFilters, shouldStoreFilters);
74
+ const visibleFilters = getVisibleFiltersByFilters(filters, availableFiltersAsVisibleFilters, shouldStoreFilters);
75
+ return {
76
+ ...s,
77
+ exportDefinitions: s.exportDefinitions?.map((exportDefinition) => {
78
+ if (isExportDefinitionDashboardRequestPayload(exportDefinition.requestPayload)) {
79
+ return {
80
+ ...exportDefinition,
81
+ requestPayload: {
82
+ ...exportDefinition.requestPayload,
83
+ content: {
84
+ ...exportDefinition.requestPayload.content,
85
+ filters: appliedFilters,
86
+ },
87
+ },
88
+ };
89
+ }
90
+ else {
91
+ return exportDefinition;
92
+ }
93
+ }),
94
+ metadata: {
95
+ ...s.metadata,
96
+ visibleFilters,
97
+ },
98
+ };
99
+ });
100
+ }
101
+ }, [
102
+ setEditedAutomationFilters,
103
+ setEditedAutomation,
104
+ dashboardHiddenFilters,
105
+ availableFiltersAsVisibleFilters,
106
+ storeFilters,
107
+ widget,
108
+ insight,
109
+ isWidget,
110
+ commonDateFilterId,
111
+ ]);
112
+ // Callback for per-tab filter changes - updates state AND syncs to export definitions
113
+ const onFiltersByTabChange = useCallback((newFiltersByTab, storeFiltersParam) => {
114
+ // Update the editedFiltersByTab state
115
+ setEditedAutomationFiltersByTab?.(newFiltersByTab);
116
+ const shouldStoreFilters = storeFiltersParam ?? storeFilters;
117
+ const newEffectiveFiltersByTab = shouldStoreFilters
118
+ ? Object.entries(newFiltersByTab).reduce((acc, [tabId, filters]) => {
119
+ const tabHiddenFilters = filtersDataByTab?.find((tab) => tab.tabId === tabId)?.hiddenFilters ?? [];
120
+ const appliedFilters = getAppliedDashboardFilters(filters ?? [], tabHiddenFilters, true);
121
+ if (appliedFilters) {
122
+ acc[tabId] = appliedFilters;
123
+ }
124
+ return acc;
125
+ }, {})
126
+ : undefined;
127
+ const newVisibleFiltersByTab = getVisibleFiltersByFiltersByTab(newFiltersByTab, availableFiltersAsVisibleFiltersByTab, shouldStoreFilters);
128
+ // Sync to export definitions AND metadata
129
+ setEditedAutomation((s) => ({
130
+ ...s,
131
+ exportDefinitions: s.exportDefinitions?.map((exportDefinition) => {
132
+ if (isExportDefinitionDashboardRequestPayload(exportDefinition.requestPayload)) {
133
+ return {
134
+ ...exportDefinition,
135
+ requestPayload: {
136
+ ...exportDefinition.requestPayload,
137
+ content: {
138
+ ...exportDefinition.requestPayload.content,
139
+ filtersByTab: newEffectiveFiltersByTab,
140
+ },
141
+ },
142
+ };
143
+ }
144
+ return exportDefinition;
145
+ }),
146
+ metadata: {
147
+ ...s.metadata,
148
+ visibleFiltersByTab: newVisibleFiltersByTab,
149
+ },
150
+ }));
151
+ }, [
152
+ setEditedAutomationFiltersByTab,
153
+ storeFilters,
154
+ setEditedAutomation,
155
+ availableFiltersAsVisibleFiltersByTab,
156
+ filtersDataByTab,
157
+ ]);
158
+ const onApplyCurrentFilters = useCallback(() => {
159
+ // Widget schedules should never use per-tab filters, only dashboard schedules can have tabs
160
+ const filtersByTabForNewAutomation = widget
161
+ ? undefined
162
+ : getDefaultSelectedFiltersFromFiltersByTab(filtersDataByTab);
163
+ if (filtersByTabForNewAutomation) {
164
+ onFiltersByTabChange(filtersByTabForNewAutomation);
165
+ }
166
+ else {
167
+ onFiltersChange(filtersForNewAutomation ?? [], widget ? true : storeFilters);
168
+ }
169
+ }, [
170
+ filtersForNewAutomation,
171
+ storeFilters,
172
+ onFiltersChange,
173
+ onFiltersByTabChange,
174
+ widget,
175
+ filtersDataByTab,
176
+ ]);
177
+ const onStoreFiltersChange = useCallback((value, filters, filtersByTabParam) => {
178
+ setStoreFilters(value);
179
+ // If filtersByTab is provided, use onFiltersByTabChange, otherwise use onFiltersChange
180
+ if (filtersByTabParam) {
181
+ // Trigger filtersByTab change which handles the sync
182
+ onFiltersByTabChange(filtersByTabParam, value);
183
+ }
184
+ if (filters) {
185
+ // Use regular filters change
186
+ onFiltersChange(filters, value);
187
+ }
188
+ }, [onFiltersChange, onFiltersByTabChange, setStoreFilters]);
189
+ return {
190
+ onFiltersChange,
191
+ onFiltersByTabChange,
192
+ onApplyCurrentFilters,
193
+ onStoreFiltersChange,
194
+ };
195
+ }
@@ -1,10 +1,2 @@
1
- import { type IDateFilterConfig } from "@gooddata/sdk-model";
2
- import { type IDateFilterOptionsByType } from "@gooddata/sdk-ui-filters";
3
- /**
4
- * Converts date filter config - as stored on the backend - into the date filter options that are aimed for
5
- * consumption by the actual date filtering view components.
6
- *
7
- * @param config - date filter config from backend
8
- */
9
- export declare function convertDateFilterConfigToDateFilterOptions(config: IDateFilterConfig): IDateFilterOptionsByType;
1
+ export { convertDateFilterConfigToDateFilterOptions } from "@gooddata/sdk-ui-filters";
10
2
  //# sourceMappingURL=dateFilterConfigConverters.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dateFilterConfigConverters.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/automations/shared/dateFilterConfig/dateFilterConfigConverters.ts"],"names":[],"mappings":"AAKA,OAAO,EAIH,KAAK,iBAAiB,EAIzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAGH,KAAK,wBAAwB,EAIhC,MAAM,0BAA0B,CAAC;AAKlC;;;;;GAKG;AACH,wBAAgB,0CAA0C,CACtD,MAAM,EAAE,iBAAiB,GAC1B,wBAAwB,CAgB1B"}
1
+ {"version":3,"file":"dateFilterConfigConverters.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/automations/shared/dateFilterConfig/dateFilterConfigConverters.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,0CAA0C,EAAE,MAAM,0BAA0B,CAAC"}
@@ -1,89 +1,4 @@
1
1
  // (C) 2019-2026 GoodData Corporation
2
- import { endOfDay, format, startOfDay, subMonths } from "date-fns";
3
- import { groupBy, isEmpty, max, min } from "lodash-es";
4
- // TODO: this import was coming from internal/esm and was wrecking tests
5
- const PLATFORM_DATE_FORMAT = "yyyy-MM-dd HH:mm";
6
- /**
7
- * Converts date filter config - as stored on the backend - into the date filter options that are aimed for
8
- * consumption by the actual date filtering view components.
9
- *
10
- * @param config - date filter config from backend
11
- */
12
- export function convertDateFilterConfigToDateFilterOptions(config) {
13
- const allTime = convertAllTime(config.allTime);
14
- const emptyValues = convertEmptyValues(config.emptyValues);
15
- const absoluteForm = convertAbsoluteForm(config.absoluteForm);
16
- const relativeForm = convertRelativeForm(config.relativeForm);
17
- const absolutePreset = convertAbsolutePresets(config.absolutePresets);
18
- const relativePreset = convertRelativePresets(config.relativePresets);
19
- return removeEmptyKeysFromDateFilterOptions({
20
- allTime,
21
- emptyValues,
22
- absoluteForm,
23
- absolutePreset,
24
- relativeForm,
25
- relativePreset,
26
- });
27
- }
28
- function convertAllTime(filter) {
29
- return (filter && {
30
- ...filter,
31
- type: "allTime",
32
- });
33
- }
34
- function convertEmptyValues(filter) {
35
- return (filter && {
36
- ...filter,
37
- type: "emptyValues",
38
- });
39
- }
40
- function convertAbsoluteForm(filter) {
41
- return (filter && {
42
- ...filter,
43
- from: format(startOfDay(subMonths(new Date(), 1)), PLATFORM_DATE_FORMAT),
44
- to: format(endOfDay(new Date()), PLATFORM_DATE_FORMAT),
45
- type: "absoluteForm",
46
- });
47
- }
48
- function convertRelativeForm(filter) {
49
- return (filter && {
50
- from: undefined,
51
- // we order the granularities anyway, this lets the user to config the default
52
- granularity: filter.availableGranularities[0],
53
- localIdentifier: filter.localIdentifier,
54
- name: filter.name,
55
- to: undefined,
56
- type: "relativeForm",
57
- visible: filter.visible,
58
- });
59
- }
60
- function convertAbsolutePresets(filters) {
61
- return filters?.map((preset) => sanitizeDateFilterOption({
62
- ...preset,
63
- type: "absolutePreset",
64
- }));
65
- }
66
- function convertRelativePresets(filters) {
67
- return (filters &&
68
- groupBy(filters.map((preset) => sanitizeDateFilterOption({
69
- ...preset,
70
- type: "relativePreset",
71
- })), (preset) => preset.granularity));
72
- }
73
- function removeEmptyKeysFromDateFilterOptions({ absoluteForm, absolutePreset, allTime, emptyValues, relativeForm, relativePreset, }) {
74
- return {
75
- ...(allTime && { allTime }),
76
- ...(emptyValues && { emptyValues }),
77
- ...(absoluteForm && { absoluteForm }),
78
- ...(!isEmpty(absolutePreset) && { absolutePreset }),
79
- ...(relativeForm && { relativeForm }),
80
- ...(!isEmpty(relativePreset) && { relativePreset }),
81
- };
82
- }
83
- function sanitizeDateFilterOption(option) {
84
- return {
85
- ...option,
86
- from: min([option.from, option.to]),
87
- to: max([option.from, option.to]),
88
- };
89
- }
2
+ /* oxlint-disable no-barrel-files/no-barrel-files */
3
+ // Moved to sdk-ui-filters (shared with the CF date picker); re-exported for existing import sites.
4
+ export { convertDateFilterConfigToDateFilterOptions } from "@gooddata/sdk-ui-filters";
@@ -1,34 +1,2 @@
1
- import { type IDashboardDateFilter } from "@gooddata/sdk-model";
2
- import { type DateFilterOption, type IDateFilterOptionsByType } from "@gooddata/sdk-ui-filters";
3
- interface IDateFilterOptionInfo {
4
- dateFilterOption: DateFilterOption;
5
- excludeCurrentPeriod: boolean;
6
- }
7
- /**
8
- * Tries to match a preset or a form with the provided value. Prioritizes the provided option if possible.
9
- *
10
- * @remarks
11
- * This is to handle cases when user picked a form and filled values that match an existing preset.
12
- * In those cases we want to show the form as picked even though a preset would otherwise be preferred.
13
- *
14
- * @param dateFilter - value to match against
15
- * @param availableOptions - date options available
16
- * @param preferredOptionId - id of the option that should be matched first if possible
17
- */
18
- export declare function matchDateFilterToDateFilterOptionWithPreference(dateFilter: IDashboardDateFilter | undefined, availableOptions: IDateFilterOptionsByType, preferredOptionId: string | undefined): IDateFilterOptionInfo;
19
- /**
20
- * Tries to match a preset or a form with the provided value. Prioritizes presets over forms.
21
- * @param dateFilterValue - value to match against
22
- * @param availableOptions - date options available
23
- */
24
- export declare function matchDateFilterToDateFilterOption(dateFilter: IDashboardDateFilter | undefined, availableOptions: IDateFilterOptionsByType): IDateFilterOptionInfo;
25
- /**
26
- * Flattens the provided date filter options. The flattening maintains a stable, predefined order in which
27
- * the options should be rendered by the date filter component.
28
- *
29
- * @param dateFilterOptions - available options to flatten
30
- */
31
- export declare function flattenDateFilterOptions(dateFilterOptions: IDateFilterOptionsByType): DateFilterOption[];
32
- export declare function findDateFilterOptionByValue(dateFilter: IDashboardDateFilter, dateFilterOptions: IDateFilterOptionsByType): DateFilterOption | undefined;
33
- export {};
1
+ export { findDateFilterOptionByValue, flattenDateFilterOptions, matchDateFilterToDateFilterOption, matchDateFilterToDateFilterOptionWithPreference, } from "@gooddata/sdk-ui-filters";
34
2
  //# sourceMappingURL=dateFilterOptionMapping.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dateFilterOptionMapping.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/automations/shared/dateFilterConfig/dateFilterOptionMapping.ts"],"names":[],"mappings":"AAIA,OAAO,EAKH,KAAK,oBAAoB,EAM5B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACH,KAAK,gBAAgB,EACrB,KAAK,wBAAwB,EAKhC,MAAM,0BAA0B,CAAC;AAUlC,UAAU,qBAAqB;IAC3B,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,oBAAoB,EAAE,OAAO,CAAC;CACjC;AAaD;;;;;;;;;;GAUG;AACH,wBAAgB,+CAA+C,CAC3D,UAAU,EAAE,oBAAoB,GAAG,SAAS,EAC5C,gBAAgB,EAAE,wBAAwB,EAC1C,iBAAiB,EAAE,MAAM,GAAG,SAAS,GACtC,qBAAqB,CAmBvB;AAED;;;;GAIG;AACH,wBAAgB,iCAAiC,CAC7C,UAAU,EAAE,oBAAoB,GAAG,SAAS,EAC5C,gBAAgB,EAAE,wBAAwB,GAC3C,qBAAqB,CAqEvB;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,iBAAiB,EAAE,wBAAwB,GAAG,gBAAgB,EAAE,CAmBxG;AAsDD,wBAAgB,2BAA2B,CACvC,UAAU,EAAE,oBAAoB,EAChC,iBAAiB,EAAE,wBAAwB,gCAG9C"}
1
+ {"version":3,"file":"dateFilterOptionMapping.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/automations/shared/dateFilterConfig/dateFilterOptionMapping.ts"],"names":[],"mappings":"AAKA,OAAO,EACH,2BAA2B,EAC3B,wBAAwB,EACxB,iCAAiC,EACjC,+CAA+C,GAClD,MAAM,0BAA0B,CAAC"}