Skip to content

Commit eb400ee

Browse files
[9.1] [ResponseOps][MW][Reporting] Fix recurrent schedule for Daily recurrence (#244571) (#244968)
# Backport This will backport the following commits from `main` to `9.1`: - [[ResponseOps][MW][Reporting] Fix recurrent schedule for Daily recurrence (#244571)](#244571) <!--- Backport version: 10.2.0 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sorenlouv/backport) <!--BACKPORT [{"author":{"name":"Janki Salvi","email":"[email protected]"},"sourceCommit":{"committedDate":"2025-12-02T15:29:09Z","message":"[ResponseOps][MW][Reporting] Fix recurrent schedule for Daily recurrence (#244571)\n\n## Summary\n\nFixes https://github.com/elastic/kibana/issues/230056\n\n\n### Checklist\n\n- [x] [Unit or functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere updated or added to match the most common scenarios","sha":"330f4f678510e42be1c079947b488b117fdc299f","branchLabelMapping":{"^v9.3.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["bug","release_note:skip","Team:ResponseOps","Feature:Reporting:Framework","backport:version","Feature:Maintenance Window","v9.3.0","v9.2.2"],"title":"[ResponseOps][MW][Reporting] Fix recurrent schedule for Daily recurrence","number":244571,"url":"https://github.com/elastic/kibana/pull/244571","mergeCommit":{"message":"[ResponseOps][MW][Reporting] Fix recurrent schedule for Daily recurrence (#244571)\n\n## Summary\n\nFixes https://github.com/elastic/kibana/issues/230056\n\n\n### Checklist\n\n- [x] [Unit or functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere updated or added to match the most common scenarios","sha":"330f4f678510e42be1c079947b488b117fdc299f"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v9.3.0","branchLabelMappingKey":"^v9.3.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/244571","number":244571,"mergeCommit":{"message":"[ResponseOps][MW][Reporting] Fix recurrent schedule for Daily recurrence (#244571)\n\n## Summary\n\nFixes https://github.com/elastic/kibana/issues/230056\n\n\n### Checklist\n\n- [x] [Unit or functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere updated or added to match the most common scenarios","sha":"330f4f678510e42be1c079947b488b117fdc299f"}},{"branch":"9.2","label":"v9.2.2","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"url":"https://github.com/elastic/kibana/pull/244964","number":244964,"state":"OPEN"}]}] BACKPORT--> --------- Co-authored-by: kibanamachine <[email protected]>
1 parent 95a39c2 commit eb400ee

File tree

8 files changed

+99
-17
lines changed

8 files changed

+99
-17
lines changed

src/platform/packages/shared/response-ops/recurring-schedule-form/components/recurring_schedule_form_fields.test.tsx

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ describe('RecurringScheduleForm', () => {
9090
expect(await screen.findByTestId('count-field')).toBeInTheDocument();
9191
});
9292

93-
it('renders custom schedule if frequency = daily', async () => {
93+
it('does not render custom schedule if frequency = daily', async () => {
9494
render(
9595
<TestWrapper
9696
iv={{ recurringSchedule: { frequency: Frequency.DAILY, ends: RecurrenceEnd.NEVER } }}
@@ -99,9 +99,33 @@ describe('RecurringScheduleForm', () => {
9999
</TestWrapper>
100100
);
101101

102+
expect(
103+
screen.queryByTestId('customRecurringScheduleByWeekdayButtonGroup')
104+
).not.toBeInTheDocument();
105+
expect(await screen.findByText('Repeats every day')).toBeInTheDocument();
106+
});
107+
108+
it('renders schedule with frequency = daily and weekdays', async () => {
109+
const recurringSchedule: RecurringSchedule = {
110+
frequency: Frequency.DAILY as any,
111+
ends: RecurrenceEnd.NEVER,
112+
byweekday: { 1: true, 5: true },
113+
interval: 1,
114+
};
115+
render(
116+
<TestWrapper
117+
iv={{
118+
recurringSchedule,
119+
}}
120+
>
121+
<RecurringScheduleFormFields {...baseProps} initialRecurringSchedule={recurringSchedule} />
122+
</TestWrapper>
123+
);
124+
102125
expect(
103126
await screen.findByTestId('customRecurringScheduleByWeekdayButtonGroup')
104127
).toBeInTheDocument();
128+
expect(await screen.findByText('Repeats every Monday, Friday')).toBeInTheDocument();
105129
});
106130

107131
it('renders custom schedule if frequency = custom', async () => {

src/platform/packages/shared/response-ops/recurring-schedule-form/components/recurring_schedule_form_fields.tsx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ export interface RecurringScheduleFieldsProps {
5959
showTimeInSummary?: boolean;
6060
readOnly?: boolean;
6161
compressed?: boolean;
62+
initialRecurringSchedule?: RecurringSchedule;
6263
}
6364

6465
/**
@@ -76,6 +77,7 @@ export const RecurringScheduleFormFields = memo(
7677
showTimeInSummary = false,
7778
readOnly = false,
7879
compressed = false,
80+
initialRecurringSchedule,
7981
}: RecurringScheduleFieldsProps) => {
8082
const [formData] = useFormData<{ recurringSchedule: RecurringSchedule }>({
8183
watch: [
@@ -92,6 +94,14 @@ export const RecurringScheduleFormFields = memo(
9294

9395
const [today] = useState<Moment>(moment());
9496

97+
const recurringSchedule = useMemo(
98+
() => ({
99+
...initialRecurringSchedule,
100+
...formData.recurringSchedule,
101+
}),
102+
[initialRecurringSchedule, formData.recurringSchedule]
103+
);
104+
95105
const { options, presets } = useMemo(() => {
96106
let _options: Array<EuiSelectOption & { 'data-test-subj'?: string }> =
97107
DEFAULT_FREQUENCY_OPTIONS;
@@ -141,7 +151,7 @@ export const RecurringScheduleFormFields = memo(
141151
};
142152
}, [minFrequency, startDate]);
143153

144-
const parsedSchedule = useMemo(() => parseSchedule(formData.recurringSchedule), [formData]);
154+
const parsedSchedule = useMemo(() => parseSchedule(recurringSchedule), [recurringSchedule]);
145155

146156
return (
147157
<EuiSplitPanel.Outer hasShadow={false} hasBorder={true} data-test-subj="recurring-form">
@@ -158,7 +168,7 @@ export const RecurringScheduleFormFields = memo(
158168
},
159169
}}
160170
/>
161-
{(parsedSchedule?.frequency === Frequency.DAILY ||
171+
{((parsedSchedule?.frequency === Frequency.DAILY && parsedSchedule?.byweekday) ||
162172
parsedSchedule?.frequency === 'CUSTOM') && (
163173
<CustomRecurringSchedule
164174
startDate={startDate}

x-pack/platform/plugins/private/reporting/public/management/components/scheduled_report_flyout_content.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,7 @@ export const ScheduledReportFlyoutContent = ({
389389
minFrequency={Frequency.MONTHLY}
390390
showTimeInSummary
391391
compressed
392+
initialRecurringSchedule={scheduledReport.recurringSchedule}
392393
/>
393394
</>
394395
)}

x-pack/platform/plugins/private/reporting/public/management/utils.test.ts

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,33 @@ describe('transformScheduledReport', () => {
5959
);
6060
});
6161

62-
it('marks as custom when freq=DAILY and no weekdays', () => {
62+
it('handles freq=DAILY and no weekdays', () => {
6363
const report = {
6464
...baseReport,
65-
schedule: { rrule: { freq: Frequency.DAILY, tzid: 'UTC' } },
65+
schedule: { rrule: { freq: Frequency.DAILY, tzid: 'UTC', interval: 1 } },
6666
} as ScheduledReportApiJSON;
6767
expect(transformScheduledReport(report).recurringSchedule).toEqual(
68-
expect.objectContaining({ frequency: 'CUSTOM', customFrequency: Frequency.DAILY })
68+
expect.objectContaining({ ends: 'never', frequency: Frequency.DAILY, interval: 1 })
69+
);
70+
});
71+
72+
it('handles freq=DAILY and weekdays', () => {
73+
const report = {
74+
...baseReport,
75+
schedule: {
76+
rrule: { freq: Frequency.DAILY, tzid: 'UTC', byweekday: ['MO', 'TU'], interval: 1 },
77+
},
78+
} as ScheduledReportApiJSON;
79+
expect(transformScheduledReport(report).recurringSchedule).toEqual(
80+
expect.objectContaining({
81+
byweekday: {
82+
'1': true,
83+
'2': true,
84+
},
85+
ends: 'never',
86+
frequency: 3,
87+
interval: 1,
88+
})
6989
);
7090
});
7191

x-pack/platform/plugins/private/reporting/public/management/utils.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,6 @@ const isCustomRrule = (rRule: Rrule) => {
6767
if (rRule.interval && rRule.interval > 1) {
6868
return true;
6969
}
70-
// frequency is daily and no weekdays are selected
71-
if (freq && freq === Frequency.DAILY && !rRule.byweekday) {
72-
return true;
73-
}
7470
// frequency is weekly and there are multiple weekdays selected
7571
if (freq && freq === Frequency.WEEKLY && rRule.byweekday && rRule.byweekday.length > 1) {
7672
return true;

x-pack/platform/plugins/shared/alerting/public/pages/maintenance_windows/components/create_maintenance_windows_form.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,7 @@ export const CreateMaintenanceWindowForm = React.memo<CreateMaintenanceWindowFor
420420
startDate={startDate}
421421
endDate={endDate}
422422
timezone={timezone}
423+
initialRecurringSchedule={initialValue?.recurringSchedule}
423424
/>
424425
</EuiFlexItem>
425426
)}

x-pack/platform/plugins/shared/alerting/public/pages/maintenance_windows/helpers/convert_from_maintenance_window_to_form.test.ts

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ describe('convertFromMaintenanceWindowToForm', () => {
220220
});
221221
});
222222

223-
test('should convert a maintenance window that is recurring on a custom daily schedule', () => {
223+
test('should not convert a maintenance window that is recurring on a daily schedule', () => {
224224
const maintenanceWindow = convertFromMaintenanceWindowToForm({
225225
title,
226226
duration,
@@ -239,15 +239,42 @@ describe('convertFromMaintenanceWindowToForm', () => {
239239
timezone: ['UTC'],
240240
recurring: true,
241241
recurringSchedule: {
242-
customFrequency: Frequency.DAILY,
243242
ends: 'never',
244-
frequency: 'CUSTOM',
243+
frequency: Frequency.DAILY,
245244
interval: 1,
246245
},
247246
solutionId: undefined,
248247
});
249248
});
250249

250+
test('should handle a maintenance window with recurring on a daily schedule and weekdays', () => {
251+
const maintenanceWindow = convertFromMaintenanceWindowToForm({
252+
title,
253+
duration,
254+
rRule: {
255+
dtstart: startDate.toISOString(),
256+
tzid: 'UTC',
257+
freq: Frequency.DAILY,
258+
interval: 1,
259+
byweekday: ['MO', 'TU', 'WE', 'TH', 'FR'],
260+
},
261+
} as MaintenanceWindow);
262+
263+
expect(maintenanceWindow).toEqual({
264+
title,
265+
startDate: startDate.toISOString(),
266+
endDate: endDate.toISOString(),
267+
timezone: ['UTC'],
268+
recurring: true,
269+
recurringSchedule: {
270+
ends: 'never',
271+
frequency: Frequency.DAILY,
272+
interval: 1,
273+
byweekday: { 1: true, 2: true, 3: true, 4: true, 5: true, 6: false, 7: false },
274+
},
275+
});
276+
});
277+
251278
test('should convert a maintenance window that is recurring on a custom weekly schedule', () => {
252279
const maintenanceWindow = convertFromMaintenanceWindowToForm({
253280
title,

x-pack/platform/plugins/shared/alerting/public/pages/maintenance_windows/helpers/convert_from_maintenance_window_to_form.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,13 @@ export const convertFromMaintenanceWindowToForm = (
7878
}
7979
}
8080

81+
if (frequency === Frequency.DAILY && rRule.byweekday) {
82+
recurringSchedule.byweekday = getInitialByWeekday(
83+
rRule.byweekday as string[],
84+
moment(startDate)
85+
);
86+
}
87+
8188
form.recurringSchedule = recurringSchedule;
8289

8390
return form;
@@ -89,10 +96,6 @@ const isCustom = (rRule: RRuleParams) => {
8996
if (rRule.interval && rRule.interval > 1) {
9097
return true;
9198
}
92-
// frequency is daily and no weekdays are selected
93-
if (freq && freq === Frequency.DAILY && !rRule.byweekday) {
94-
return true;
95-
}
9699
// frequency is weekly and there are multiple weekdays selected
97100
if (freq && freq === Frequency.WEEKLY && rRule.byweekday && rRule.byweekday.length > 1) {
98101
return true;

0 commit comments

Comments
 (0)