Skip to content

Commit 3c16d90

Browse files
committed
refactor(web): implement cancel edit functionality in SomedayRecurrenceSection
1 parent 033f4c5 commit 3c16d90

File tree

3 files changed

+60
-1
lines changed

3 files changed

+60
-1
lines changed

packages/web/src/views/Forms/EventForm/DateControlsSection/RecurrenceSection/SomedayRecurrenceSection/SomedayRecurrenceSection.test.tsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,4 +249,34 @@ describe("SomedayRecurrenceSection", () => {
249249
const value = await screen.findByTestId("someday-recurrence-value");
250250
expect(value).toHaveTextContent(/Repeats every Week/i);
251251
});
252+
253+
it("closes select on escape and restores original recurrence", async () => {
254+
const eventWithRecurrence = {
255+
...baseSomedayEvent,
256+
recurrence: { rule: ["RRULE:FREQ=WEEKLY;COUNT=5"] },
257+
};
258+
renderSection(eventWithRecurrence);
259+
260+
const initialCalls = mockSetEvent.mock.calls.length;
261+
const control = await openRecurrenceDropdown();
262+
const input = control.querySelector("input") as HTMLElement | null;
263+
fireEvent.keyDown(input ?? control, { key: "Escape", code: "Escape" });
264+
265+
expect(mockSetEvent.mock.calls.length).toBe(initialCalls);
266+
expect(screen.getByText(/Repeats every Week/i)).toBeInTheDocument();
267+
});
268+
269+
it("closes select on escape when no recurrence is set", async () => {
270+
renderSection();
271+
272+
const initialCalls = mockSetEvent.mock.calls.length;
273+
const control = await openRecurrenceDropdown();
274+
const input = control.querySelector("input") as HTMLElement | null;
275+
fireEvent.keyDown(input ?? control, { key: "Escape", code: "Escape" });
276+
277+
expect(mockSetEvent.mock.calls.length).toBe(initialCalls);
278+
expect(
279+
screen.getByRole("button", { name: /edit recurrence/i }),
280+
).toHaveTextContent(/^Repeat$/i);
281+
});
252282
});

packages/web/src/views/Forms/EventForm/DateControlsSection/RecurrenceSection/SomedayRecurrenceSection/SomedayRecurrenceSection.tsx

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { Dispatch, SetStateAction } from "react";
1+
import React, { Dispatch, SetStateAction, useRef } from "react";
22
import { Frequency } from "rrule";
33
import { Schema_Event } from "@core/types/event.types";
44
import { RepeatIcon } from "@web/components/Icons/Repeat";
@@ -27,6 +27,7 @@ export const SomedayRecurrenceSection = ({
2727
const [menuIsOpen, setMenuIsOpen] = React.useState<boolean | undefined>(
2828
undefined,
2929
);
30+
const initialStateRef = useRef({ hasRecurrence, freq });
3031

3132
const handleSelect = (option: SomedayFrequencyOption) => {
3233
if (option.value === Frequency.DAILY) {
@@ -55,10 +56,27 @@ export const SomedayRecurrenceSection = ({
5556
};
5657

5758
const openSelect = () => {
59+
initialStateRef.current = { hasRecurrence, freq };
5860
setIsEditing(true);
5961
setMenuIsOpen(true);
6062
};
6163

64+
const cancelEdit = () => {
65+
const { hasRecurrence: initialHasRecurrence, freq: initialFreq } =
66+
initialStateRef.current;
67+
68+
if (hasRecurrence !== initialHasRecurrence) {
69+
toggleRecurrence();
70+
}
71+
72+
if (freq !== initialFreq) {
73+
setFreq(initialFreq);
74+
}
75+
76+
setIsEditing(false);
77+
setMenuIsOpen(undefined);
78+
};
79+
6280
const shouldShowSelect = hasRecurrence || isEditing;
6381

6482
return (
@@ -71,6 +89,7 @@ export const SomedayRecurrenceSection = ({
7189
onSelect={handleSelect}
7290
menuIsOpen={menuIsOpen}
7391
onMenuClose={handleMenuClose}
92+
onCancel={cancelEdit}
7493
/>
7594
) : (
7695
<StyledRepeatTextContainer

packages/web/src/views/Forms/EventForm/DateControlsSection/RecurrenceSection/SomedayRecurrenceSection/SomedayRecurrenceSelect/SomedayRecurrenceSelect.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import ReactSelect, { SelectInstance, SingleValueProps } from "react-select";
33
import { components } from "react-select";
44
import { Frequency } from "rrule";
55
import { useTheme } from "styled-components";
6+
import { Key } from "ts-key-enum";
67
import { brighten, darken } from "@core/util/color.utils";
78
import { theme } from "@web/common/styles/theme";
89
import { RepeatIcon } from "@web/components/Icons/Repeat";
@@ -32,13 +33,15 @@ export const SomedayRecurrenceSelect = ({
3233
onSelect,
3334
menuIsOpen,
3435
onMenuClose,
36+
onCancel,
3537
}: {
3638
bgColor: string;
3739
hasRecurrence: boolean;
3840
freq: FrequencyValues;
3941
onSelect: (option: SomedayFrequencyOption) => void;
4042
menuIsOpen?: boolean;
4143
onMenuClose?: () => void;
44+
onCancel?: () => void;
4245
}) => {
4346
const fontSize = theme.text.size.m;
4447
const bgBright = brighten(bgColor);
@@ -61,6 +64,13 @@ export const SomedayRecurrenceSelect = ({
6164
}, [menuIsOpen]);
6265

6366
const handleKeyDown = (event: React.KeyboardEvent) => {
67+
if (event.key === Key.Escape) {
68+
event.preventDefault();
69+
event.stopPropagation();
70+
onCancel?.();
71+
return;
72+
}
73+
6474
if (event.key !== "Enter") {
6575
return;
6676
}

0 commit comments

Comments
 (0)