Skip to content

Commit ebc57ef

Browse files
:sparkles feat(agenda-events): add event shortcuts (n, m) to Day view command palette (#1389)
* Initial plan * Add Create event [n] and Edit event [m] to DayCmdPalette with tests Co-authored-by: victor-enogwe <23452630+victor-enogwe@users.noreply.github.com> * Fix test mocks and pass all tests with linting Co-authored-by: victor-enogwe <23452630+victor-enogwe@users.noreply.github.com> * Remove unnecessary onEventTargetVisibility wrapper from event shortcuts Co-authored-by: victor-enogwe <23452630+victor-enogwe@users.noreply.github.com> * :bug fix(DayCmdPalette): update event handlers to use queueMicrotask to stagger open and keep focus on open --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: victor-enogwe <23452630+victor-enogwe@users.noreply.github.com>
1 parent 203feb8 commit ebc57ef

2 files changed

Lines changed: 67 additions & 1 deletion

File tree

packages/web/src/views/Day/components/DayCmdPalette.test.tsx

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@ import { fireEvent, screen, waitFor } from "@testing-library/react";
33
import userEvent from "@testing-library/user-event";
44
import { render } from "@web/__tests__/__mocks__/mock.render";
55
import { keyPressed$ } from "@web/common/utils/dom/event-emitter.util";
6+
import * as eventUtil from "@web/common/utils/event/event.util";
67
import { getModifierKey } from "@web/common/utils/shortcut/shortcut.util";
78
import { viewSlice } from "@web/ducks/events/slices/view.slice";
89
import { settingsSlice } from "@web/ducks/settings/slices/settings.slice";
910
import { useGlobalShortcuts } from "@web/views/Calendar/hooks/shortcuts/useGlobalShortcuts";
1011
import { DayCmdPalette } from "@web/views/Day/components/DayCmdPalette";
1112

1213
// Mock react-router-dom
14+
const mockNavigate = jest.fn();
1315
jest.mock("react-router-dom", () => ({
1416
...jest.requireActual("react-router-dom"),
1517
useNavigate: jest.fn(),
@@ -37,6 +39,9 @@ jest.mock("@web/common/utils/dom/event-target-visibility.util", () => ({
3739
onEventTargetVisibility: (callback: () => void) => callback,
3840
}));
3941

42+
// Mock event utility functions
43+
jest.mock("@web/common/utils/event/event.util");
44+
4045
jest.mock("@web/store/store.hooks", () => ({
4146
useAppDispatch: () => mockDispatch,
4247
useAppSelector: jest.requireActual("@web/store/store.hooks").useAppSelector,
@@ -49,7 +54,14 @@ function Component() {
4954
}
5055

5156
describe("DayCmdPalette", () => {
52-
const mockNavigate = jest.fn();
57+
const mockOpenEventFormCreateEvent = jest.spyOn(
58+
eventUtil,
59+
"openEventFormCreateEvent",
60+
);
61+
const mockOpenEventFormEditEvent = jest.spyOn(
62+
eventUtil,
63+
"openEventFormEditEvent",
64+
);
5365

5466
beforeEach(() => {
5567
jest.clearAllMocks();
@@ -70,6 +82,8 @@ describe("DayCmdPalette", () => {
7082
expect(screen.getByText("Navigation")).toBeInTheDocument();
7183
expect(screen.getByText("Go to Now [1]")).toBeInTheDocument();
7284
expect(screen.getByText("Go to Week [3]")).toBeInTheDocument();
85+
expect(screen.getByText("Create event [n]")).toBeInTheDocument();
86+
expect(screen.getByText("Edit event [m]")).toBeInTheDocument();
7387
expect(screen.getByText("Edit Reminder [r]")).toBeInTheDocument();
7488
expect(
7589
screen.getByText("Go to Today (Monday, November 24) [t]"),
@@ -201,6 +215,42 @@ describe("DayCmdPalette", () => {
201215
expect(mockNavigate).toHaveBeenCalledWith("/logout");
202216
});
203217

218+
it("calls openEventFormEditEvent when Edit event is clicked", async () => {
219+
const user = userEvent.setup();
220+
221+
await act(() =>
222+
render(<Component />, {
223+
state: { settings: { isCmdPaletteOpen: true } },
224+
}),
225+
);
226+
227+
const editEventBtn = await screen.findByRole("button", {
228+
name: /edit event \[m\]/i,
229+
});
230+
231+
await act(() => user.click(editEventBtn));
232+
233+
expect(mockOpenEventFormEditEvent).toHaveBeenCalled();
234+
});
235+
236+
it("calls openEventFormCreateEvent when Create event is clicked", async () => {
237+
const user = userEvent.setup();
238+
239+
await act(() =>
240+
render(<Component />, {
241+
state: { settings: { isCmdPaletteOpen: true } },
242+
}),
243+
);
244+
245+
const createEventBtn = await screen.findByRole("button", {
246+
name: /create event \[n\]/i,
247+
});
248+
249+
await act(() => user.click(createEventBtn));
250+
251+
expect(mockOpenEventFormCreateEvent).toHaveBeenCalled();
252+
});
253+
204254
it("filters items based on search input", async () => {
205255
const user = userEvent.setup();
206256
await act(() =>

packages/web/src/views/Day/components/DayCmdPalette.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ import { moreCommandPaletteItems } from "@web/common/constants/more.cmd.constant
66
import { ROOT_ROUTES } from "@web/common/constants/routes";
77
import { pressKey } from "@web/common/utils/dom/event-emitter.util";
88
import { onEventTargetVisibility } from "@web/common/utils/dom/event-target-visibility.util";
9+
import {
10+
openEventFormCreateEvent,
11+
openEventFormEditEvent,
12+
} from "@web/common/utils/event/event.util";
913
import { selectIsCmdPaletteOpen } from "@web/ducks/settings/selectors/settings.selectors";
1014
import { settingsSlice } from "@web/ducks/settings/slices/settings.slice";
1115
import { useAppDispatch, useAppSelector } from "@web/store/store.hooks";
@@ -39,6 +43,18 @@ export const DayCmdPalette = ({ onGoToToday }: DayCmdPaletteProps) => {
3943
icon: "CalendarIcon",
4044
onClick: () => pressKey("3"),
4145
},
46+
{
47+
id: "create-event",
48+
children: "Create event [n]",
49+
icon: "PlusIcon",
50+
onClick: () => queueMicrotask(openEventFormCreateEvent),
51+
},
52+
{
53+
id: "edit-event",
54+
children: "Edit event [m]",
55+
icon: "PencilSquareIcon",
56+
onClick: () => queueMicrotask(openEventFormEditEvent),
57+
},
4258
{
4359
id: "edit-reminder",
4460
children: `Edit Reminder [r]`,

0 commit comments

Comments
 (0)