Repository: SwitchbackTech/compass (ts)

Issue:
Creating someday events from command palette does not work
### Where did this happen?

Local code with an up-to-date main branch

### Expected Behavior

When selecting any of the event creation actions from the command palette, the respective draft is started:
- Create Week Event (W)
- Create Month Event (M)
- Create Event (C)

### Current Behavior

Nothing happens when selecting those Week/Month events (timed events work like normal)

### Steps to Reproduce

1. Launch command palette
2. Move mouse down to highlight the desired action
3. Press enter
4. Notice: nothing happens

### Possible Solution

Need to update how default someday events are created

### Context

Bug was introduced in #265 

Pull request:
🐛 Fix: Cmd Palette not triggering new events
closes #274 

### After
https://github.com/user-attachments/assets/2195dd1e-b342-4c98-a0fe-bf3f9866cb0c

### Notes
Introduces a known bug: #283


Patch:
diff --git a/packages/web/src/common/utils/draft/draft.util.ts b/packages/web/src/common/utils/draft/draft.util.ts
index 92232454..af18bb00 100644
--- a/packages/web/src/common/utils/draft/draft.util.ts
+++ b/packages/web/src/common/utils/draft/draft.util.ts
@@ -1,15 +1,17 @@
 import dayjs, { Dayjs } from "dayjs";
 import { MouseEvent } from "react";
+import { Dispatch } from "redux";
 import { Categories_Event } from "@core/types/event.types";
 import {
   ID_GRID_EVENTS_ALLDAY,
   ID_GRID_EVENTS_TIMED,
-  ID_SIDEBAR,
 } from "@web/common/constants/web.constants";
 import { Schema_GridEvent } from "@web/common/types/web.event.types";
 import { roundToNext } from "@web/common/utils";
 import { assembleDefaultEvent } from "@web/common/utils/event.util";
 import { getElemById, getX } from "@web/common/utils/grid.util";
+import { draftSlice } from "@web/ducks/events/slices/draft.slice";
+import { Activity_DraftEvent } from "@web/ducks/events/slices/draft.slice.types";
 import { DateCalcs } from "@web/views/Calendar/hooks/grid/useDateCalcs";
 import {
   DRAFT_DURATION_MIN,
@@ -54,7 +56,30 @@ export const assembleTimedDraft = async (
   return event;
 };
 
-export const getDraftTimes = (isCurrentWeek: boolean, startOfWeek: Dayjs) => {
+export const createTimedDraft = async (
+  isCurrentWeek: boolean,
+  startOfView: Dayjs,
+  activity: Activity_DraftEvent,
+  dispatch: Dispatch,
+) => {
+  const { startDate, endDate } = getDraftTimes(isCurrentWeek, startOfView);
+
+  const event = (await assembleDefaultEvent(
+    Categories_Event.TIMED,
+    startDate,
+    endDate,
+  )) as Schema_GridEvent;
+
+  dispatch(
+    draftSlice.actions.start({
+      activity,
+      eventType: Categories_Event.TIMED,
+      event,
+    }),
+  );
+};
+
+const getDraftTimes = (isCurrentWeek: boolean, startOfWeek: Dayjs) => {
   const currentMinute = dayjs().minute();
   const nextMinuteInterval = roundToNext(currentMinute, GRID_TIME_STEP);
 
diff --git a/packages/web/src/common/utils/draft/someday.draft.util.ts b/packages/web/src/common/utils/draft/someday.draft.util.ts
new file mode 100644
index 00000000..296ac9dc
--- /dev/null
+++ b/packages/web/src/common/utils/draft/someday.draft.util.ts
@@ -0,0 +1,28 @@
+import { Dayjs } from "dayjs";
+import { Dispatch } from "redux";
+import { YEAR_MONTH_FORMAT } from "@core/constants/date.constants";
+import { Categories_Event } from "@core/types/event.types";
+import { draftSlice } from "@web/ducks/events/slices/draft.slice";
+import { Activity_DraftEvent } from "@web/ducks/events/slices/draft.slice.types";
+import { assembleDefaultEvent } from "../event.util";
+
+export const createSomedayDraft = async (
+  category: Categories_Event.SOMEDAY_WEEK | Categories_Event.SOMEDAY_MONTH,
+  startOfView: Dayjs,
+  endOfView: Dayjs,
+  activity: Activity_DraftEvent,
+  dispatch: Dispatch,
+) => {
+  const startDate = startOfView.format(YEAR_MONTH_FORMAT);
+  const endDate = endOfView.format(YEAR_MONTH_FORMAT);
+
+  const event = await assembleDefaultEvent(category, startDate, endDate);
+
+  dispatch(
+    draftSlice.actions.start({
+      activity,
+      eventType: category,
+      event,
+    }),
+  );
+};
diff --git a/packages/web/src/common/utils/event.util.ts b/packages/web/src/common/utils/event.util.ts
index 4f064531..29afa4b9 100644
--- a/packages/web/src/common/utils/event.util.ts
+++ b/packages/web/src/common/utils/event.util.ts
@@ -67,12 +67,14 @@ export const assembleDefaultEvent = async (
       };
       return defaultAllday;
     }
-    case Categories_Event.SOMEDAY_WEEK || Categories_Event.SOMEDAY_MONTH: {
+    case Categories_Event.SOMEDAY_WEEK:
+    case Categories_Event.SOMEDAY_MONTH: {
       const defaultSomeday: Schema_Event = {
         ...baseEvent,
         isAllDay: false,
         isSomeday: true,
         origin: Origin.COMPASS,
+        ...(startDate && endDate ? { startDate, endDate } : {}),
       };
       return defaultSomeday;
     }
@@ -168,6 +170,11 @@ export const getCategory = (event: Schema_Event) => {
   return Categories_Event.TIMED;
 };
 
+export const getCalendarEventIdFromElement = (element: HTMLElement) => {
+  const eventElement = element.closest(`[${DATA_EVENT_ELEMENT_ID}]`);
+  return eventElement ? eventElement.getAttribute(DATA_EVENT_ELEMENT_ID) : null;
+};
+
 export const getMonthListLabel = (start: Dayjs) => {
   return start.format("MMMM");
 };
@@ -284,8 +291,3 @@ const _assembleBaseEvent = (
 
   return baseEvent;
 };
-
-export const getCalendarEventIdFromElement = (element: HTMLElement) => {
-  const eventElement = element.closest(`[${DATA_EVENT_ELEMENT_ID}]`);
-  return eventElement ? eventElement.getAttribute(DATA_EVENT_ELEMENT_ID) : null;
-};
diff --git a/packages/web/src/views/Calendar/hooks/shortcuts/useShortcuts.ts b/packages/web/src/views/Calendar/hooks/shortcuts/useShortcuts.ts
index 78859f7b..ffdbe870 100644
--- a/packages/web/src/views/Calendar/hooks/shortcuts/useShortcuts.ts
+++ b/packages/web/src/views/Calendar/hooks/shortcuts/useShortcuts.ts
@@ -4,17 +4,14 @@ import { useHotkeys } from "react-hotkeys-hook";
 import { useNavigate } from "react-router-dom";
 import { Key } from "ts-keycode-enum";
 import {
-  Priorities,
   SOMEDAY_MONTH_LIMIT_MSG,
   SOMEDAY_WEEK_LIMIT_MSG,
 } from "@core/constants/core.constants";
-import { YEAR_MONTH_FORMAT } from "@core/constants/date.constants";
 import { Categories_Event } from "@core/types/event.types";
 import { ROOT_ROUTES } from "@web/common/constants/routes";
-import { Schema_GridEvent } from "@web/common/types/web.event.types";
 import { isEventFormOpen } from "@web/common/utils";
-import { getDraftTimes } from "@web/common/utils/draft/draft.util";
-import { assembleDefaultEvent } from "@web/common/utils/event.util";
+import { createTimedDraft } from "@web/common/utils/draft/draft.util";
+import { createSomedayDraft } from "@web/common/utils/draft/someday.draft.util";
 import {
   selectIsAtMonthlyLimit,
   selectIsAtWeeklyLimit,
@@ -61,63 +58,29 @@ export const useShortcuts = ({
   });
 
   useEffect(() => {
-    const _createSomedayDraft = async (type: "week" | "month") => {
-      if (type === "week" && isAtWeeklyLimit) {
+    const _createSomedayDraft = async (
+      category: Categories_Event.SOMEDAY_WEEK | Categories_Event.SOMEDAY_MONTH,
+    ) => {
+      if (category === Categories_Event.SOMEDAY_WEEK && isAtWeeklyLimit) {
         alert(SOMEDAY_WEEK_LIMIT_MSG);
         return;
       }
-      if (type === "month" && isAtMonthlyLimit) {
+      if (category === Categories_Event.SOMEDAY_MONTH && isAtMonthlyLimit) {
         alert(SOMEDAY_MONTH_LIMIT_MSG);
         return;
       }
 
+      await createSomedayDraft(
+        category,
+        startOfView,
+        endOfView,
+        "createShortcut",
+        dispatch,
+      );
+
       if (tab !== "tasks") {
         dispatch(viewSlice.actions.updateSidebarTab("tasks"));
       }
-
-      const eventType =
-        type === "week"
-          ? Categories_Event.SOMEDAY_WEEK
-          : Categories_Event.SOMEDAY_MONTH;
-
-      const somedayDefault = await assembleDefaultEvent(
-        Categories_Event.SOMEDAY_WEEK,
-      );
-      dispatch(
-        draftSlice.actions.start({
-          activity: "createShortcut",
-          eventType,
-          event: {
-            ...somedayDefault,
-            startDate: startOfView.format(YEAR_MONTH_FORMAT),
-            endDate: endOfView.format(YEAR_MONTH_FORMAT),
-          },
-        }),
-      );
-    };
-
-    const _createTimedDraft = () => {
-      const { startDate, endDate } = getDraftTimes(isCurrentWeek, startOfView);
-
-      const event: Schema_GridEvent = {
-        startDate,
-        endDate,
-        priority: Priorities.UNASSIGNED,
-        isAllDay: false,
-        position: {
-          isOverlapping: false,
-          widthMultiplier: 1,
-          horizontalOrder: 1,
-        },
-      };
-
-      dispatch(
-        draftSlice.actions.start({
-          activity: "createShortcut",
-          eventType: Categories_Event.TIMED,
-          event,
-        }),
-      );
     };
 
     const _discardDraft = () => {
@@ -137,7 +100,13 @@ export const useShortcuts = ({
 
       const handlersByKey = {
         [Key.OpenBracket]: () => dispatch(viewSlice.actions.toggleSidebar()),
-        [Key.C]: () => _createTimedDraft(),
+        [Key.C]: () =>
+          createTimedDraft(
+            isCurrentWeek,
+            startOfView,
+            "createShortcut",
+            dispatch,
+          ),
         [Key.T]: () => {
           scrollUtil.scrollToNow();
           _discardDraft();
@@ -151,8 +120,8 @@ export const useShortcuts = ({
           _discardDraft();
           util.incrementWeek();
         },
-        [Key.M]: () => _createSomedayDraft("month"),
-        [Key.W]: () => _createSomedayDraft("week"),
+        [Key.M]: () => _createSomedayDraft(Categories_Event.SOMEDAY_MONTH),
+        [Key.W]: () => _createSomedayDraft(Categories_Event.SOMEDAY_WEEK),
         [Key.Z]: () => {
           navigate(ROOT_ROUTES.LOGOUT);
         },
diff --git a/packages/web/src/views/CmdPalette/CmdPalette.tsx b/packages/web/src/views/CmdPalette/CmdPalette.tsx
index c12d4542..5b58b8d1 100644
--- a/packages/web/src/views/CmdPalette/CmdPalette.tsx
+++ b/packages/web/src/views/CmdPalette/CmdPalette.tsx
@@ -12,10 +12,9 @@ import {
 } from "@core/constants/core.constants";
 import { Categories_Event } from "@core/types/event.types";
 import { ROOT_ROUTES } from "@web/common/constants/routes";
-import { Schema_GridEvent } from "@web/common/types/web.event.types";
 import { isEventFormOpen } from "@web/common/utils";
-import { getDraftTimes } from "@web/common/utils/draft/draft.util";
-import { assembleDefaultEvent } from "@web/common/utils/event.util";
+import { createTimedDraft } from "@web/common/utils/draft/draft.util";
+import { createSomedayDraft } from "@web/common/utils/draft/someday.draft.util";
 import {
   selectIsAtMonthlyLimit,
   selectIsAtWeeklyLimit,
@@ -30,6 +29,7 @@ const CmdPalette = ({
   today,
   isCurrentWeek,
   startOfView,
+  endOfView,
   util,
   scrollUtil,
 }: ShortcutProps) => {
@@ -50,42 +50,24 @@ const CmdPalette = ({
 
   useHandleOpenCommandPalette(setOpen);
 
-  const _createSomedayDraft = async (type: "week" | "month") => {
-    if (type === "week" && isAtWeeklyLimit) {
+  const handleCreateSomedayDraft = async (
+    category: Categories_Event.SOMEDAY_WEEK | Categories_Event.SOMEDAY_MONTH,
+  ) => {
+    if (category === Categories_Event.SOMEDAY_WEEK && isAtWeeklyLimit) {
       alert(SOMEDAY_WEEK_LIMIT_MSG);
       return;
     }
-    if (type === "month" && isAtMonthlyLimit) {
+    if (category === Categories_Event.SOMEDAY_MONTH && isAtMonthlyLimit) {
       alert(SOMEDAY_MONTH_LIMIT_MSG);
       return;
     }
 
-    const eventType =
-      type === "week"
-        ? Categories_Event.SOMEDAY_WEEK
-        : Categories_Event.SOMEDAY_MONTH;
-
-    dispatch(
-      draftSlice.actions.start({
-        activity: "createShortcut",
-        eventType,
-      }),
-    );
-  };
-
-  const _createTimedDraft = async () => {
-    const { startDate, endDate } = getDraftTimes(isCurrentWeek, startOfView);
-    const event = (await assembleDefaultEvent(
-      Categories_Event.TIMED,
-      startDate,
-      endDate,
-    )) as Schema_GridEvent;
-    dispatch(
-      draftSlice.actions.start({
-        activity: "createShortcut",
-        eventType: Categories_Event.TIMED,
-        event,
-      }),
+    await createSomedayDraft(
+      category,
+      startOfView,
+      endOfView,
+      "createShortcut",
+      dispatch,
     );
   };
 
@@ -105,19 +87,27 @@ const CmdPalette = ({
             id: "create-event",
             children: "Create Event [c]",
             icon: "PlusIcon",
-            onClick: () => _createTimedDraft(),
+            onClick: () =>
+              createTimedDraft(
+                isCurrentWeek,
+                startOfView,
+                "createShortcut",
+                dispatch,
+              ),
           },
           {
             id: "create-someday-week-event",
             children: "Create Week Event [w]",
             icon: "PlusIcon",
-            onClick: () => _createSomedayDraft("week"),
+            onClick: () =>
+              handleCreateSomedayDraft(Categories_Event.SOMEDAY_WEEK),
           },
           {
             id: "create-someday-month-event",
             children: "Create Month Event [m]",
             icon: "PlusIcon",
-            onClick: () => _createSomedayDraft("month"),
+            onClick: () =>
+              handleCreateSomedayDraft(Categories_Event.SOMEDAY_MONTH),
           },
           {
             id: "today",


Test patch:
diff --git a/packages/web/src/common/utils/draft/draft.util.test.ts b/packages/web/src/common/utils/draft/draft.util.test.ts
new file mode 100644
index 00000000..03c47f95
--- /dev/null
+++ b/packages/web/src/common/utils/draft/draft.util.test.ts
@@ -0,0 +1,28 @@
+import { Categories_Event } from "@core/types/event.types";
+import { assembleDefaultEvent } from "../event.util";
+
+jest.mock("@web/auth/auth.util", () => ({
+  getUserId: jest.fn().mockResolvedValue("mock-user-id"),
+}));
+describe("assembleDefaultEvent", () => {
+  it("should include dates for someday event when provided", async () => {
+    const startDate = "2024-01-01";
+    const endDate = "2024-01-07";
+    const eventWithDates = await assembleDefaultEvent(
+      Categories_Event.SOMEDAY_WEEK,
+      startDate,
+      endDate,
+    );
+
+    expect(eventWithDates).toHaveProperty("startDate", startDate);
+    expect(eventWithDates).toHaveProperty("endDate", endDate);
+  });
+  it("dates should be empty for someday event when not provided", async () => {
+    const eventWithoutDates = await assembleDefaultEvent(
+      Categories_Event.SOMEDAY_WEEK,
+    );
+
+    expect(eventWithoutDates).toHaveProperty("startDate", "");
+    expect(eventWithoutDates).toHaveProperty("endDate", "");
+  });
+});