Skip to content

Commit 0606741

Browse files
authored
♻️ Refactor: Update overlapping event type safety (#238)
* ✨ Feat: Add isOptimisticEvent utility and integrate into GridEvent and AllDayEvent components * ✨ Feat: Refactor event handling to use Schema_GridEvent and improve type safety
1 parent c2eb33d commit 0606741

File tree

7 files changed

+41
-24
lines changed

7 files changed

+41
-24
lines changed

packages/web/src/common/utils/event.util.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ export const getCategory = (event: Schema_Event) => {
8888
export const assembleGridEvent = (
8989
event: Partial<Schema_GridEvent>
9090
): Schema_GridEvent => {
91-
// TODO: Maybe move to a constants file?
9291
const DEFAULT_POSITION = {
9392
isOverlapping: false,
9493
widthMultiplier: 1,
@@ -203,6 +202,11 @@ export const isEventInRange = (
203202
return isStartDateInRange || isEndDateInRange;
204203
};
205204

205+
export const isOptimisticEvent = (event: Schema_GridEvent) => {
206+
const isOptimistic = event._id?.startsWith(ID_OPTIMISTIC_PREFIX) || false;
207+
return isOptimistic;
208+
};
209+
206210
export const prepEvtAfterDraftDrop = (
207211
category: Categories_Event,
208212
dropItem: DropResult,

packages/web/src/common/utils/grid.util.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,12 @@ export const assignEventToRow = (
4343
return { fits, rowNum };
4444
};
4545

46-
export const assignEventsToRow = (allDayEvents: Schema_Event[]) => {
46+
export const assignEventsToRow = (
47+
allDayEvents: Schema_Event[]
48+
): {
49+
rowsCount: number;
50+
allDayEvents: Schema_GridEvent[];
51+
} => {
4752
const rows: number[][] = [];
4853
// makes copy of all event objects to allow for adding a 'row' field
4954
// can likely be optimized using immer's `produce` and `draft`
@@ -442,7 +447,8 @@ export const getAbsoluteLeftPosition = (
442447
}
443448

444449
if (
445-
event.position?.isOverlapping &&
450+
!event.isAllDay &&
451+
event.position.isOverlapping &&
446452
event.position.horizontalOrder > 1
447453
) {
448454
positionStart += eventWidth * (event.position.horizontalOrder - 1);

packages/web/src/ducks/events/selectors/event.selectors.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,18 @@ import { assignEventsToRow } from "@web/common/utils/grid.util";
55
import { Schema_GridEvent } from "@web/common/types/web.event.types";
66
import { assembleGridEvent } from "@web/common/utils/event.util";
77

8+
type Schema_GridEvent_NoPosition = Omit<Schema_GridEvent, "position">;
9+
810
export const selectAllDayEvents = createSelector(
911
(state: RootState) => state.events.entities.value || {},
1012
(state: RootState) => state.events.getWeekEvents.value || [],
1113
(entities, weekIds) => {
1214
if (!("data" in weekIds) || weekIds.data.length === 0) return [];
1315

14-
const weekEvents: Schema_Event[] = weekIds.data.map(
16+
const weekEvents: Schema_GridEvent_NoPosition[] = weekIds.data.map(
1517
(_id: string) => entities[_id]
1618
);
17-
const _allDayEvents: Schema_Event[] = weekEvents.filter(
19+
const _allDayEvents: Schema_GridEvent_NoPosition[] = weekEvents.filter(
1820
(e: Schema_Event) => e !== undefined && e.isAllDay
1921
);
2022
const { allDayEvents } = assignEventsToRow(_allDayEvents);

packages/web/src/views/Calendar/components/Event/Grid/GridEvent/GridEvent.tsx

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ import React, {
66
useMemo,
77
} from "react";
88
import dayjs from "dayjs";
9+
import { Priorities } from "@core/constants/core.constants";
910
import { Schema_GridEvent } from "@web/common/types/web.event.types";
11+
import { isOptimisticEvent } from "@web/common/utils/event.util";
1012
import { Measurements_Grid } from "@web/views/Calendar/hooks/grid/useGridLayout";
1113
import { WeekProps } from "@web/views/Calendar/hooks/useWeek";
1214
import { Flex } from "@web/components/Flex";
@@ -18,10 +20,7 @@ import {
1820
import { getPosition } from "@web/views/Calendar/hooks/event/getPosition";
1921
import { getLineClamp } from "@web/common/utils/grid.util";
2022
import { getTimesLabel } from "@web/common/utils/web.date.util";
21-
import {
22-
ID_OPTIMISTIC_PREFIX,
23-
ZIndex,
24-
} from "@web/common/constants/web.constants";
23+
import { ZIndex } from "@web/common/constants/web.constants";
2524
import { Text } from "@web/components/Text";
2625

2726
import { StyledEvent, StyledEventScaler, StyledEventTitle } from "../../styled";
@@ -59,8 +58,8 @@ const _GridEvent = (
5958
const { component } = weekProps;
6059

6160
const isInPast = dayjs().isAfter(dayjs(_event.endDate));
62-
const isOptimistic = _event._id?.startsWith(ID_OPTIMISTIC_PREFIX);
6361
const event = _event;
62+
const isOptimistic = isOptimisticEvent(event);
6463

6564
const position = getPosition(
6665
event,
@@ -78,7 +77,7 @@ const _GridEvent = (
7877
return (
7978
<StyledEvent
8079
allDay={event.isAllDay || false}
81-
className={isDraft ? "active" : null}
80+
className={isDraft ? "active" : undefined}
8281
height={position.height || 0}
8382
isDragging={isDragging}
8483
isInPast={isInPast}
@@ -92,7 +91,7 @@ const _GridEvent = (
9291

9392
onEventMouseDown(event, e);
9493
}}
95-
priority={event.priority}
94+
priority={event.priority || Priorities.UNASSIGNED}
9695
ref={ref}
9796
role="button"
9897
tabindex="0"
@@ -111,7 +110,10 @@ const _GridEvent = (
111110
<>
112111
{(isDraft || !isInPast) && (
113112
<Text role="textbox" size="xs" zIndex={ZIndex.LAYER_3}>
114-
{getTimesLabel(event.startDate, event.endDate)}
113+
{getTimesLabel(
114+
event.startDate as string,
115+
event.endDate as string
116+
)}
115117
</Text>
116118
)}
117119
<>

packages/web/src/views/Calendar/components/Grid/AllDayRow/AllDayEvent.tsx

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import dayjs from "dayjs";
22
import React, { memo, MouseEvent } from "react";
3-
import { Schema_Event } from "@core/types/event.types";
3+
import { Priorities } from "@core/constants/core.constants";
44
import { Flex } from "@web/components/Flex";
5+
import { Schema_GridEvent } from "@web/common/types/web.event.types";
6+
import { isOptimisticEvent } from "@web/common/utils/event.util";
57
import { AlignItems, FlexDirections } from "@web/components/Flex/styled";
68
import { SpaceCharacter } from "@web/components/SpaceCharacter";
79
import { getPosition } from "@web/views/Calendar/hooks/event/getPosition";
@@ -12,12 +14,12 @@ import { Text } from "@web/components/Text";
1214
import { StyledEvent } from "../../Event/styled";
1315

1416
interface Props {
15-
event: Schema_Event;
17+
event: Schema_GridEvent;
1618
isPlaceholder: boolean;
1719
measurements: Measurements_Grid;
1820
startOfView: WeekProps["component"]["startOfView"];
1921
endOfView: WeekProps["component"]["endOfView"];
20-
onMouseDown: (e: MouseEvent, event: Schema_Event) => void;
22+
onMouseDown: (e: MouseEvent, event: Schema_GridEvent) => void;
2123
}
2224

2325
const AllDayEvent = ({
@@ -36,18 +38,21 @@ const AllDayEvent = ({
3638
false
3739
);
3840

41+
const isOptimistic = isOptimisticEvent(event);
42+
3943
return (
4044
<StyledEvent
41-
allDay={event.isAllDay}
45+
allDay={event.isAllDay || true}
4246
height={position.height}
4347
isDragging={false}
4448
isInPast={dayjs().isAfter(dayjs(event.endDate))}
4549
isPlaceholder={isPlaceholder}
50+
isOptimistic={isOptimistic}
4651
isResizing={false}
4752
left={position.left}
4853
lineClamp={1}
4954
onMouseDown={(e) => onMouseDown(e, event)}
50-
priority={event.priority}
55+
priority={event.priority || Priorities.UNASSIGNED}
5156
role="button"
5257
top={position.top}
5358
width={position.width}

packages/web/src/views/Calendar/components/Grid/AllDayRow/AllDayEvents.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React, { MouseEvent } from "react";
2-
import { Schema_Event } from "@core/types/event.types";
32
import { ID_GRID_EVENTS_ALLDAY } from "@web/common/constants/web.constants";
3+
import { Schema_GridEvent } from "@web/common/types/web.event.types";
44
import { Measurements_Grid } from "@web/views/Calendar/hooks/grid/useGridLayout";
55
import { WeekProps } from "@web/views/Calendar/hooks/useWeek";
66
import { useAppDispatch, useAppSelector } from "@web/store/store.hooks";
@@ -26,7 +26,7 @@ export const AllDayEvents = ({
2626
const draftId = useAppSelector(selectDraftId);
2727
const dispatch = useAppDispatch();
2828

29-
const onMouseDown = (e: MouseEvent, event: Schema_Event) => {
29+
const onMouseDown = (e: MouseEvent, event: Schema_GridEvent) => {
3030
e.stopPropagation();
3131

3232
if (isSomedayEventFormOpen()) {
@@ -38,7 +38,7 @@ export const AllDayEvents = ({
3838

3939
return (
4040
<StyledEvents id={ID_GRID_EVENTS_ALLDAY}>
41-
{allDayEvents.map((event: Schema_Event, i) => {
41+
{allDayEvents.map((event: Schema_GridEvent, i) => {
4242
return (
4343
<AllDayEventMemo
4444
key={`${event.title}-${i}`}

packages/web/src/views/Calendar/hooks/event/getPosition.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,12 @@ import { GRID_MARGIN_LEFT } from "@web/views/Calendar/layout.constants";
1616
import { Measurements_Grid } from "@web/views/Calendar/hooks/grid/useGridLayout";
1717

1818
export const getPosition = (
19-
event: Schema_GridEvent | null,
19+
event: Schema_GridEvent,
2020
startOfView: Dayjs,
2121
endOfView: Dayjs,
2222
measurements: Measurements_Grid,
2323
isDraft: boolean
2424
) => {
25-
if (!event) return null; // TS Guard
26-
2725
const { colWidths } = measurements;
2826
const start = dayjs(event.startDate);
2927
const end = dayjs(event.endDate);

0 commit comments

Comments
 (0)