Repository: SwitchbackTech/compass
Pull request #242 (2025-01-31 14:23:45)

🐛Fix: All-day Drag position
 Fixes bug from #240, which caused all-day events to lose their position during drags.

Also does minor follow-ups to #236 , which also cleans up surrounding code for readability

This pull request includes significant changes aimed at refactoring and simplifying the codebase, specifically around event positioning and width calculations in the calendar grid. The changes involve moving several utility functions to a new file and removing redundant code.

### Refactoring and Simplification:

* [`packages/web/src/common/utils/grid.util.ts`](diffhunk://#diff-a3e9fc209b5db78cdf2e17ee9c97a27e489691d6afc042445b154e22b00161bfL83-L126): Removed multiple methods related to event positioning and width calculations, such as `getAllDayEventWidth`, `getEventCategory`, `getLeftPosition`, and `widthMinusPadding`. These methods were moved to a new file for better organization. [[1]](diffhunk://#diff-a3e9fc209b5db78cdf2e17ee9c97a27e489691d6afc042445b154e22b00161bfL83-L126) [[2]](diffhunk://#diff-a3e9fc209b5db78cdf2e17ee9c97a27e489691d6afc042445b154e22b00161bfL381-L486) [[3]](diffhunk://#diff-a3e9fc209b5db78cdf2e17ee9c97a27e489691d6afc042445b154e22b00161bfL538-L551) [[4]](diffhunk://#diff-a3e9fc209b5db78cdf2e17ee9c97a27e489691d6afc042445b154e22b00161bfL619-L634)
* [`packages/web/src/common/utils/position.util.ts`](diffhunk://#diff-77387e951136aed29321b4d39a8102ffe74ecbac361773cdb367d92c942b582cR1-R291): Added a new file that now contains the methods for calculating event positions and widths, such as `getAbsoluteLeftPosition`, `getAllDayEventWidth`, `getEventCategory`, and `getLeftPosition`. This helps in organizing the code better and making it more modular.

### File Renaming and Import Adjustments:

* [`packages/web/src/__tests__/utils/grid.util/grid.util2.test.ts`](diffhunk://#diff-9d43c35f027e98689cbce5e0aa50259b37a7c3b5be3a74d3e04b4776f98b6236R2-R8): Renamed to `packages/web/src/common/utils/position.util.test.ts` to reflect the new organization of utility functions.
* `packages/web/src/views/Calendar/components/Event/Grid/GridEvent/GridEvent.tsx` and `packages/web/src/views/Calendar/components/Grid/AllDayRow/AllDayEvent.tsx`: Updated imports to use the newly created `position.util.ts` file for event positioning functions. [[1]](diffhunk://#diff-5721933c4be83998cce8f7358189dbf22f9cc59124295b6df4feccd9e6e5d370L20-R26) [[2]](diffhunk://#diff-dc322dbb8cd8aed86555214c94c8f3ce0041417b701633cd1c06789663e08f19R7-L9)

### Removal of Redundant Files:

* `packages/web/src/views/Calendar/hooks/event/getPosition.ts` and `packages/web/src/views/Calendar/hooks/event/useEventPosition.ts`: Removed these files as their functionality has been moved to the new `position.util.ts` file. [[1]](diffhunk://#diff-5fba5bce1c1d439e93de7cfd4ebed3002d88d5b2bdba292f547205b3ffe9e352L1-L79) [[2]](diffhunk://#diff-acb931a47cef8bb2b94c57d9e97e09dd74aa3cbbe3d64a5545033633ba857221L1-L54)

### Layout Constants Adjustment:

* [`packages/web/src/views/Calendar/layout.constants.ts`](diffhunk://#diff-7f2ff4e19c8d748141a97d943eb1632436d0d2d4c617df62ba2b0a0abd209475L33): Removed the constant `GRID_EVENT_OVERLAPPING_HORIZONTAL_MARGIN` as it has been moved to the new `position.util.ts` file.


Patch:
diff --git a/packages/web/src/common/utils/grid.util.ts b/packages/web/src/common/utils/grid.util.ts
index 374156f3..0236d2b5 100644
--- a/packages/web/src/common/utils/grid.util.ts
+++ b/packages/web/src/common/utils/grid.util.ts
@@ -5,19 +5,14 @@ import weekPlugin from "dayjs/plugin/weekOfYear";
 import dayOfYear from "dayjs/plugin/dayOfYear";
 import { Schema_Event } from "@core/types/event.types";
 import {
-  EVENT_PADDING_RIGHT,
   FLEX_EQUAL,
   FLEX_TMRW,
   FLEX_TODAY,
   AFTER_TMRW_MULTIPLE,
-  GRID_MARGIN_LEFT,
-  GRID_EVENT_OVERLAPPING_HORIZONTAL_MARGIN,
 } from "@web/views/Calendar/layout.constants";
 import { AssignResult, WidthPercentages } from "@web/common/types/util.types";
-import { Category } from "@web/ducks/events/event.types";
 import {
   DIVIDER_GRID,
-  GRID_X_PADDING_TOTAL,
   SIDEBAR_OPEN_WIDTH,
 } from "@web/views/Calendar/layout.constants";
 import { Schema_GridEvent } from "@web/common/types/web.event.types";
@@ -80,50 +75,6 @@ export const assignEventsToRow = (
   return { rowsCount: rows.length, allDayEvents: orderedAllDayEvents };
 };
 
-export const getAllDayEventWidth = (
-  category: Category,
-  startIndex: number,
-  start: Dayjs,
-  end: Dayjs,
-  startOfWeek: Dayjs,
-  widths: number[]
-) => {
-  let width: number;
-
-  switch (category) {
-    case Category.ThisWeekOnly: {
-      let duration = end.diff(start, "days");
-      if (duration === 0) {
-        // if only one day, then use original width
-        width = widths[startIndex];
-        duration = 1; // prevents width from being 0
-      }
-      width = _sumEventWidths(duration, startIndex, widths);
-      break;
-    }
-    case Category.ThisToFutureWeek: {
-      width = _sumEventWidths(7 - startIndex, startIndex, widths);
-      break;
-    }
-    case Category.PastToThisWeek: {
-      const daysThisWeek = end.diff(startOfWeek, "days");
-      // start at 0 because event carries over from last week
-      width = _sumEventWidths(daysThisWeek, 0, widths);
-      break;
-    }
-    case Category.PastToFutureWeek: {
-      width = _sumEventWidths(7, 0, widths);
-      break;
-    }
-    default: {
-      console.log("Logic error while parsing date width");
-      width = -666;
-    }
-  }
-
-  return widthMinusPadding(width);
-};
-
 export const getBeforeAfterPercentages = (
   percentRemaining: number,
   todayIndex: number,
@@ -152,7 +103,6 @@ export const getCurrentPercentOfDay = () => {
   return (getCurrentMinute() / 1440) * 100;
 };
 
-// ++ separate past-future from current (?)
 export const getColumnWidthPercentages = (
   todayIndex: number
 ): WidthPercentages => {
@@ -378,112 +328,6 @@ export const getFlexBasis = (day: Dayjs, week: number, today: Dayjs) => {
   return prevDayFlex * AFTER_TMRW_MULTIPLE;
 };
 
-export const getEventCategory = (
-  start: Dayjs,
-  end: Dayjs,
-  startOfWeek: Dayjs,
-  endOfWeek: Dayjs
-): Category => {
-  const startsThisWeek = start.isBetween(startOfWeek, endOfWeek, "day", "[]");
-  const endsThisWeek = end.isBetween(startOfWeek, endOfWeek, "day", "[]");
-
-  if (startsThisWeek && endsThisWeek) {
-    return Category.ThisWeekOnly;
-  }
-  if (startsThisWeek && !endsThisWeek) {
-    return Category.ThisToFutureWeek;
-  }
-  if (!startsThisWeek && endsThisWeek) {
-    return Category.PastToThisWeek;
-  }
-  if (!startsThisWeek && !endsThisWeek) {
-    return Category.PastToFutureWeek;
-  }
-
-  console.log("Logic error while getting event category");
-  return Category.ThisWeekOnly;
-};
-
-export const getLeftPosition = (
-  category: Category,
-  startIndex: number,
-  colWidths: number[],
-  event?: Schema_GridEvent,
-  eventWidth?: number,
-  isDraft?: boolean
-) => {
-  let left = getAbsoluteLeftPosition(
-    category,
-    startIndex,
-    colWidths,
-    event,
-    eventWidth,
-    isDraft
-  );
-
-  if (isDraft || !event?.isAllDay) {
-    left += GRID_MARGIN_LEFT;
-  }
-
-  if (event?.position?.isOverlapping) {
-    const isFirstEventInRow = event.position.horizontalOrder === 1;
-    left +=
-      // Increase the left margin of the overlapping event if it not the first event in the row
-      isFirstEventInRow
-        ? 0
-        : GRID_EVENT_OVERLAPPING_HORIZONTAL_MARGIN *
-          (event.position.horizontalOrder - 1);
-  }
-
-  return left;
-};
-
-export const getAbsoluteLeftPosition = (
-  category: Category,
-  startIndex: number,
-  colWidths: number[],
-  event?: Schema_GridEvent,
-  eventWidth?: number,
-  isDraft?: boolean
-) => {
-  let positionStart: number;
-  switch (category) {
-    case Category.PastToThisWeek:
-    case Category.PastToFutureWeek: {
-      positionStart = 0;
-      break;
-    }
-    case Category.ThisWeekOnly:
-    case Category.ThisToFutureWeek:
-      {
-        // add up from 0 index to startIndex
-        positionStart = colWidths.reduce((accum, width, index) => {
-          return index < startIndex ? accum + width : accum;
-        }, 0);
-
-        if (!event || !eventWidth) {
-          return positionStart;
-        }
-
-        if (
-          !isDraft &&
-          !event.isAllDay &&
-          event.position.isOverlapping &&
-          event.position.horizontalOrder > 1
-        ) {
-          positionStart += eventWidth * (event.position.horizontalOrder - 1);
-        }
-      }
-      break;
-    default: {
-      console.log("Logic error while parsing left position of date");
-      positionStart = -666;
-    }
-  }
-
-  return positionStart;
-};
-
 export const getLineClamp = (height: number) => {
   const min = 1;
   const computed = Math.round((height - 7) / 16);
@@ -505,16 +349,6 @@ export const getPrevDayWidth = (today: Dayjs) => {
 export const getWidthBuffer = (startIndex: number) =>
   startIndex * (DIVIDER_GRID * 2);
 
-export const getWidthInPixels = (
-  percent: number, //eg 21.4 for 21.4%
-  windowWidth: number
-) => {
-  const gridWidth = windowWidth - GRID_X_PADDING_TOTAL;
-
-  const widthInPixels = gridWidth * (percent * 0.01);
-  return Math.floor(widthInPixels);
-};
-
 export const getX = (e: MouseEvent | number, isSidebarOpen: boolean) => {
   const x = typeof e === "number" ? e : e.clientX;
 
@@ -535,20 +369,6 @@ const normalizeDayNums = (days: number[]) => {
   });
 };
 
-export const removeSomedayProperties = (event: Schema_Event): Schema_Event => {
-  const { order, recurrence, ...eventWithoutSomedayProps } = event;
-  return eventWithoutSomedayProps;
-};
-
-export const widthMinusPadding = (width: number) => {
-  const adjustedWidth = width - EVENT_PADDING_RIGHT;
-
-  if (adjustedWidth < 0) {
-    return width;
-  }
-  return adjustedWidth;
-};
-
 const _anySharedValues = (arr1: number[], arr2: number[]) => {
   return arr1.some((v) => arr2.indexOf(v) >= 0);
 };
@@ -616,19 +436,3 @@ const _range = (start: number, end: number) => {
     .fill(null)
     .map((_, idx) => start + idx);
 };
-
-const _sumEventWidths = (
-  duration: number,
-  startIndex: number,
-  widths: number[]
-) => {
-  // create array of numbers, one for each day, setting each to 0 by default,
-  // then set values based on the widths of the days of the event
-  const eventWidths: number[] = Array(duration || 0)
-    .fill(0)
-    .map((_, index) => widths[index + startIndex] || 0);
-
-  // add up width of each day of the event
-  const eventWidth = eventWidths.reduce((accum, value) => accum + value, 0);
-  return eventWidth;
-};
diff --git a/packages/web/src/common/utils/position.util.ts b/packages/web/src/common/utils/position.util.ts
new file mode 100644
index 00000000..820969a0
--- /dev/null
+++ b/packages/web/src/common/utils/position.util.ts
@@ -0,0 +1,291 @@
+import dayjs, { Dayjs } from "dayjs";
+import isBetween from "dayjs/plugin/isBetween";
+import weekPlugin from "dayjs/plugin/weekOfYear";
+import dayOfYear from "dayjs/plugin/dayOfYear";
+import { MS_IN_HR } from "@core/constants/core.constants";
+import { HOURS_AM_FORMAT } from "@core/constants/date.constants";
+import { Measurements_Grid } from "@web/views/Calendar/hooks/grid/useGridLayout";
+import {
+  EVENT_ALLDAY_HEIGHT,
+  DRAFT_PADDING_BOTTOM,
+  GRID_EVENT_OVERLAPPING_HORIZONTAL_MARGIN,
+  EVENT_PADDING_RIGHT,
+  GRID_MARGIN_LEFT,
+} from "@web/views/Calendar/layout.constants";
+import { Category } from "@web/ducks/events/event.types";
+import { ACCEPTED_TIMES } from "../constants/web.constants";
+import { Schema_GridEvent } from "../types/web.event.types";
+
+dayjs.extend(dayOfYear);
+dayjs.extend(weekPlugin);
+dayjs.extend(isBetween);
+
+export const getAbsoluteLeftPosition = (
+  category: Category,
+  startIndex: number,
+  colWidths: number[],
+  event?: Schema_GridEvent,
+  eventWidth?: number,
+  isDraft?: boolean
+) => {
+  let positionStart: number;
+
+  switch (category) {
+    case Category.PastToThisWeek:
+    case Category.PastToFutureWeek: {
+      positionStart = 0;
+      break;
+    }
+    case Category.ThisWeekOnly:
+    case Category.ThisToFutureWeek:
+      {
+        // add up from 0 index to startIndex
+        positionStart = colWidths.reduce((accum, width, index) => {
+          return index < startIndex ? accum + width : accum;
+        }, 0);
+
+        if (!event || !eventWidth) {
+          return positionStart;
+        }
+
+        if (
+          !isDraft &&
+          !event.isAllDay &&
+          event.position.isOverlapping &&
+          event.position.horizontalOrder > 1
+        ) {
+          positionStart += eventWidth * (event.position.horizontalOrder - 1);
+        }
+      }
+      break;
+    default: {
+      console.log("Logic error while parsing left position of date");
+      positionStart = -666;
+    }
+  }
+
+  return positionStart;
+};
+
+export const getAllDayEventWidth = (
+  category: Category,
+  startIndex: number,
+  start: Dayjs,
+  end: Dayjs,
+  startOfWeek: Dayjs,
+  widths: number[]
+) => {
+  let width: number;
+
+  switch (category) {
+    case Category.ThisWeekOnly: {
+      let duration = end.diff(start, "days");
+      if (duration === 0) {
+        // if only one day, then use original width
+        width = widths[startIndex];
+        duration = 1; // prevents width from being 0
+      }
+      width = _sumEventWidths(duration, startIndex, widths);
+      break;
+    }
+    case Category.ThisToFutureWeek: {
+      width = _sumEventWidths(7 - startIndex, startIndex, widths);
+      break;
+    }
+    case Category.PastToThisWeek: {
+      const daysThisWeek = end.diff(startOfWeek, "days");
+      // start at 0 because event carries over from last week
+      width = _sumEventWidths(daysThisWeek, 0, widths);
+      break;
+    }
+    case Category.PastToFutureWeek: {
+      width = _sumEventWidths(7, 0, widths);
+      break;
+    }
+    default: {
+      console.log("Logic error while parsing date width");
+      width = -666;
+    }
+  }
+
+  return widthMinusPadding(width);
+};
+
+export const getEventCategory = (
+  start: Dayjs,
+  end: Dayjs,
+  startOfWeek: Dayjs,
+  endOfWeek: Dayjs
+): Category => {
+  const startsThisWeek = start.isBetween(startOfWeek, endOfWeek, "day", "[]");
+  const endsThisWeek = end.isBetween(startOfWeek, endOfWeek, "day", "[]");
+
+  if (startsThisWeek && endsThisWeek) {
+    return Category.ThisWeekOnly;
+  }
+  if (startsThisWeek && !endsThisWeek) {
+    return Category.ThisToFutureWeek;
+  }
+  if (!startsThisWeek && endsThisWeek) {
+    return Category.PastToThisWeek;
+  }
+  if (!startsThisWeek && !endsThisWeek) {
+    return Category.PastToFutureWeek;
+  }
+
+  console.log("Logic error while getting event category");
+  return Category.ThisWeekOnly;
+};
+
+export const getPosition = (
+  event: Schema_GridEvent,
+  startOfView: Dayjs,
+  endOfView: Dayjs,
+  measurements: Measurements_Grid,
+  isDraft: boolean
+) => {
+  const { colWidths } = measurements;
+  const start = dayjs(event.startDate);
+  const end = dayjs(event.endDate);
+
+  const category = getEventCategory(start, end, startOfView, endOfView);
+  const startIndex = start.get("day");
+
+  let height: number;
+  let top: number;
+  let width: number;
+  let left: number;
+
+  if (event.isAllDay) {
+    height = EVENT_ALLDAY_HEIGHT;
+    top = 23 * (event?.row || 1); // found by experimenting with what 'looked right'
+    width = getAllDayEventWidth(
+      category,
+      startIndex,
+      start,
+      end,
+      startOfView,
+      colWidths
+    );
+  } else {
+    width = getTimedEventWidth(
+      colWidths,
+      startIndex,
+      event.position.widthMultiplier,
+      isDraft
+    );
+    const startTime = ACCEPTED_TIMES.indexOf(start.format(HOURS_AM_FORMAT)) / 4;
+
+    const hourHeight = measurements.hourHeight;
+    top = hourHeight * startTime;
+
+    const duration = end.diff(start);
+    const durationHours = duration * MS_IN_HR;
+    height = hourHeight * durationHours;
+    height -= DRAFT_PADDING_BOTTOM;
+  }
+
+  left = getLeftPosition(
+    category,
+    startIndex,
+    colWidths,
+    event,
+    width,
+    isDraft
+  );
+
+  const position = { height, left, top, width };
+  return position;
+};
+
+const getRelativeLeftPosition = (
+  initialLeft: number,
+  event?: Schema_GridEvent,
+  isDraft?: boolean
+) => {
+  let adjustment = 0;
+  const GRID_EVENT_OVERLAPPING_HORIZONTAL_MARGIN = 4;
+
+  if (!isDraft && event?.position?.isOverlapping) {
+    const isNotFirstInRow = event.position.horizontalOrder !== 1;
+    if (isNotFirstInRow) {
+      adjustment +=
+        GRID_EVENT_OVERLAPPING_HORIZONTAL_MARGIN *
+        (event.position.horizontalOrder - 1);
+    }
+  }
+
+  const isTimedEvent = event?.isAllDay === false;
+  if (isTimedEvent) {
+    adjustment += GRID_MARGIN_LEFT;
+  }
+
+  const relativeLeft = initialLeft + adjustment;
+  return relativeLeft;
+};
+
+export const getTimedEventWidth = (
+  colWidths: number[],
+  startIndex: number,
+  widthMultiplier: number,
+  isDraft: boolean
+) => {
+  let width = isDraft
+    ? // If we are drafting an event, we want the event to be full width of the column
+      colWidths[startIndex]
+    : // Else, we want the width to be whatever the event's width multiplier is
+      colWidths[startIndex] * widthMultiplier;
+
+  const BUFFER_WIDTH = 11;
+  width -= BUFFER_WIDTH;
+  return width;
+};
+
+export const getLeftPosition = (
+  category: Category,
+  startIndex: number,
+  colWidths: number[],
+  event?: Schema_GridEvent,
+  eventWidth?: number,
+  isDraft?: boolean
+) => {
+  let left = getAbsoluteLeftPosition(
+    category,
+    startIndex,
+    colWidths,
+    event,
+    eventWidth,
+    isDraft
+  );
+
+  left = getRelativeLeftPosition(left, event, isDraft);
+
+  return left;
+};
+
+export const getWidth = () => {};
+
+export const widthMinusPadding = (width: number) => {
+  const adjustedWidth = width - EVENT_PADDING_RIGHT;
+
+  if (adjustedWidth < 0) {
+    return width;
+  }
+  return adjustedWidth;
+};
+
+const _sumEventWidths = (
+  duration: number,
+  startIndex: number,
+  widths: number[]
+) => {
+  // create array of numbers, one for each day, setting each to 0 by default,
+  // then set values based on the widths of the days of the event
+  const eventWidths: number[] = Array(duration || 0)
+    .fill(0)
+    .map((_, index) => widths[index + startIndex] || 0);
+
+  // add up width of each day of the event
+  const eventWidth = eventWidths.reduce((accum, value) => accum + value, 0);
+  return eventWidth;
+};
diff --git a/packages/web/src/views/Calendar/components/Event/Grid/GridEvent/GridEvent.tsx b/packages/web/src/views/Calendar/components/Event/Grid/GridEvent/GridEvent.tsx
index 7ecfe7d4..3abb2e45 100644
--- a/packages/web/src/views/Calendar/components/Event/Grid/GridEvent/GridEvent.tsx
+++ b/packages/web/src/views/Calendar/components/Event/Grid/GridEvent/GridEvent.tsx
@@ -17,13 +17,13 @@ import {
   FlexDirections,
   FlexWrap,
 } from "@web/components/Flex/styled";
-import { getPosition } from "@web/views/Calendar/hooks/event/getPosition";
 import { getLineClamp } from "@web/common/utils/grid.util";
 import { getTimesLabel } from "@web/common/utils/web.date.util";
 import { ZIndex } from "@web/common/constants/web.constants";
 import { Text } from "@web/components/Text";
 
 import { StyledEvent, StyledEventScaler, StyledEventTitle } from "../../styled";
+import { getPosition } from "@web/common/utils/position.util";
 
 interface Props {
   event: Schema_GridEvent;
diff --git a/packages/web/src/views/Calendar/components/Grid/AllDayRow/AllDayEvent.tsx b/packages/web/src/views/Calendar/components/Grid/AllDayRow/AllDayEvent.tsx
index fc36ff86..faf46161 100644
--- a/packages/web/src/views/Calendar/components/Grid/AllDayRow/AllDayEvent.tsx
+++ b/packages/web/src/views/Calendar/components/Grid/AllDayRow/AllDayEvent.tsx
@@ -4,9 +4,9 @@ import { Priorities } from "@core/constants/core.constants";
 import { Flex } from "@web/components/Flex";
 import { Schema_GridEvent } from "@web/common/types/web.event.types";
 import { isOptimisticEvent } from "@web/common/utils/event.util";
+import { getPosition } from "@web/common/utils/position.util";
 import { AlignItems, FlexDirections } from "@web/components/Flex/styled";
 import { SpaceCharacter } from "@web/components/SpaceCharacter";
-import { getPosition } from "@web/views/Calendar/hooks/event/getPosition";
 import { Measurements_Grid } from "@web/views/Calendar/hooks/grid/useGridLayout";
 import { WeekProps } from "@web/views/Calendar/hooks/useWeek";
 import { Text } from "@web/components/Text";
diff --git a/packages/web/src/views/Calendar/hooks/event/getPosition.ts b/packages/web/src/views/Calendar/hooks/event/getPosition.ts
deleted file mode 100644
index b6d5848b..00000000
--- a/packages/web/src/views/Calendar/hooks/event/getPosition.ts
+++ /dev/null
@@ -1,79 +0,0 @@
-import dayjs, { Dayjs } from "dayjs";
-import { MS_IN_HR } from "@core/constants/core.constants";
-import { HOURS_AM_FORMAT } from "@core/constants/date.constants";
-import {
-  getAllDayEventWidth,
-  getEventCategory,
-  getLeftPosition,
-} from "@web/common/utils/grid.util";
-import { ACCEPTED_TIMES } from "@web/common/constants/web.constants";
-import { Schema_GridEvent } from "@web/common/types/web.event.types";
-import {
-  DRAFT_PADDING_BOTTOM,
-  EVENT_ALLDAY_HEIGHT,
-} from "@web/views/Calendar/layout.constants";
-import { Measurements_Grid } from "@web/views/Calendar/hooks/grid/useGridLayout";
-
-export const getPosition = (
-  event: Schema_GridEvent,
-  startOfView: Dayjs,
-  endOfView: Dayjs,
-  measurements: Measurements_Grid,
-  isDraft: boolean
-) => {
-  const { colWidths } = measurements;
-  const start = dayjs(event.startDate);
-  const end = dayjs(event.endDate);
-
-  const category = getEventCategory(start, end, startOfView, endOfView);
-  const startIndex = start.get("day");
-
-  let height: number;
-  let top: number;
-  let width: number;
-  let left: number;
-
-  if (event.isAllDay) {
-    height = EVENT_ALLDAY_HEIGHT;
-    top = 23 * (event?.row || 1); // found by experimenting with what 'looked right'
-    width = getAllDayEventWidth(
-      category,
-      startIndex,
-      start,
-      end,
-      startOfView,
-      colWidths
-    );
-  } else {
-    width = isDraft
-      ? // If we are drafting an event, we want the event to be full width of the column
-        colWidths[startIndex]
-      : // Else, we want the width to be whatever the event's width multiplier is
-        colWidths[startIndex] * event.position.widthMultiplier;
-
-    const widthBuffer = 11;
-    width -= widthBuffer;
-
-    const startTime = ACCEPTED_TIMES.indexOf(start.format(HOURS_AM_FORMAT)) / 4;
-
-    const hourHeight = measurements.hourHeight;
-    top = hourHeight * startTime;
-
-    const duration = end.diff(start);
-    const durationHours = duration * MS_IN_HR;
-    height = hourHeight * durationHours;
-    height -= DRAFT_PADDING_BOTTOM;
-  }
-
-  left = getLeftPosition(
-    category,
-    startIndex,
-    colWidths,
-    event,
-    width,
-    isDraft
-  );
-
-  const position = { height, left, top, width };
-  return position;
-};
diff --git a/packages/web/src/views/Calendar/hooks/event/useEventPosition.ts b/packages/web/src/views/Calendar/hooks/event/useEventPosition.ts
deleted file mode 100644
index 4866d92a..00000000
--- a/packages/web/src/views/Calendar/hooks/event/useEventPosition.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-import { useMemo } from "react";
-import { Dayjs } from "dayjs";
-import { Schema_GridEvent } from "@web/common/types/web.event.types";
-import { Measurements_Grid } from "@web/views/Calendar/hooks/grid/useGridLayout";
-
-import { getPosition } from "./getPosition";
-
-export const useEventPosition = (
-  draft: Schema_GridEvent | null,
-  startOfView: Dayjs,
-  endOfView: Dayjs,
-  measurements: Measurements_Grid
-) => {
-  const position = useMemo(() => {
-    const calculatePosition = () => {
-      const _missingProps = () => {
-        const requiredProps = [
-          draft?.startDate,
-          draft?.endDate,
-          draft?.isAllDay,
-          measurements,
-        ];
-
-        return (
-          requiredProps.includes(null) || requiredProps.includes(undefined)
-        );
-      };
-
-      if (_missingProps()) {
-        return;
-      }
-      const position = getPosition(
-        draft,
-        startOfView,
-        endOfView,
-        measurements,
-        true
-      );
-      return position;
-    };
-
-    return calculatePosition();
-  }, [
-    draft?.startDate,
-    draft?.endDate,
-    draft?.isAllDay,
-    draft?.row,
-    startOfView,
-    endOfView,
-    measurements,
-  ]);
-
-  return position;
-};
diff --git a/packages/web/src/views/Calendar/layout.constants.ts b/packages/web/src/views/Calendar/layout.constants.ts
index 12aec766..b500ee26 100644
--- a/packages/web/src/views/Calendar/layout.constants.ts
+++ b/packages/web/src/views/Calendar/layout.constants.ts
@@ -30,7 +30,6 @@ export const GRID_Y_START =
   PAGE_MARGIN_TOP + HEADER_HEIGHT + WEEK_DAYS_HEIGHT + WEEK_DAYS_MARGIN_Y;
 export const GRID_X_PADDING_TOTAL =
   PAGE_MARGIN_X * 2 + GRID_MARGIN_LEFT + SCROLLBAR_WIDTH;
-export const GRID_EVENT_OVERLAPPING_HORIZONTAL_MARGIN = 4;
 
 export const SIDEBAR_MONTH_HEIGHT = 275;
 export const SIDEBAR_OPEN_WIDTH = 350;


Test patch:
diff --git a/packages/web/src/__tests__/utils/grid.util/grid.util2.test.ts b/packages/web/src/common/utils/position.util.test.ts
similarity index 98%
rename from packages/web/src/__tests__/utils/grid.util/grid.util2.test.ts
rename to packages/web/src/common/utils/position.util.test.ts
index 229df135..8f31f3ff 100644
--- a/packages/web/src/__tests__/utils/grid.util/grid.util2.test.ts
+++ b/packages/web/src/common/utils/position.util.test.ts
@@ -1,10 +1,11 @@
 import dayjs from "dayjs";
+
 import {
-  getAllDayEventWidth,
   getEventCategory,
+  getAllDayEventWidth,
   getLeftPosition,
-} from "@web/common/utils/grid.util";
-import { widthMinusPadding } from "@web/common/utils/grid.util";
+  widthMinusPadding,
+} from "@web/common/utils/position.util";
 
 describe("getAllDayEventWidth", () => {
   it("is never wider than 1 week", () => {