fix: course columns on calendar (#587)
* fix: course columns on calendar * test: new tests for course cell columns, extract calls to help function * fix: gracefully handle async courses * refactor: split course cell column logic into multiple functions, add comments, and derive fields * chore: comments, for-index to for-of * chore: fix typo * fix: don't use sentry in storybook contexts * fix: silence, brand * refactor: don't rely on calculating columns, find as you go --------- Co-authored-by: doprz <52579214+doprz@users.noreply.github.com>
This commit is contained in:
@@ -2,14 +2,18 @@ import type { Course } from '@shared/types/Course';
|
||||
import CalendarCourseCell from '@views/components/calendar/CalendarCourseCell';
|
||||
import Text from '@views/components/common/Text/Text';
|
||||
import { ColorPickerProvider } from '@views/contexts/ColorPickerContext';
|
||||
import { useSentryScope } from '@views/contexts/SentryContext';
|
||||
import type { CalendarGridCourse } from '@views/hooks/useFlattenedCourseSchedule';
|
||||
import React, { Fragment } from 'react';
|
||||
|
||||
import CalendarCell from './CalendarGridCell';
|
||||
import { calculateCourseCellColumns } from './utils';
|
||||
|
||||
const daysOfWeek = ['MON', 'TUE', 'WED', 'THU', 'FRI'];
|
||||
const hoursOfDay = Array.from({ length: 14 }, (_, index) => index + 8);
|
||||
|
||||
const IS_STORYBOOK = import.meta.env.STORYBOOK;
|
||||
|
||||
interface Props {
|
||||
courseCells?: CalendarGridCourse[];
|
||||
saturdayClass?: boolean;
|
||||
@@ -106,6 +110,12 @@ interface AccountForCourseConflictsProps {
|
||||
// TODO: Possibly refactor to be more concise
|
||||
// TODO: Deal with react strict mode (wacky movements)
|
||||
function AccountForCourseConflicts({ courseCells, setCourse }: AccountForCourseConflictsProps): JSX.Element[] {
|
||||
// Sentry is not defined in storybook.
|
||||
// This is a valid use case for a condition hook, since IS_STORYBOOK is determined at build time,
|
||||
// it doesn't change between renders.
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
const [sentryScope] = IS_STORYBOOK ? [undefined] : useSentryScope();
|
||||
|
||||
// Groups by dayIndex to identify overlaps
|
||||
const days = courseCells.reduce(
|
||||
(acc, cell: CalendarGridCourse) => {
|
||||
@@ -120,31 +130,15 @@ function AccountForCourseConflicts({ courseCells, setCourse }: AccountForCourseC
|
||||
);
|
||||
|
||||
// Check for overlaps within each day and adjust gridColumnIndex and totalColumns
|
||||
Object.values(days).forEach((dayCells: CalendarGridCourse[]) => {
|
||||
// Sort by start time to ensure proper columnIndex assignment
|
||||
dayCells.sort((a, b) => a.calendarGridPoint.startIndex - b.calendarGridPoint.startIndex);
|
||||
|
||||
dayCells.forEach((cell, _, arr) => {
|
||||
let columnIndex = 1;
|
||||
cell.totalColumns = 1;
|
||||
// Check for overlaps and adjust columnIndex as needed
|
||||
for (let otherCell of arr) {
|
||||
if (otherCell !== cell) {
|
||||
const isOverlapping =
|
||||
otherCell.calendarGridPoint.startIndex < cell.calendarGridPoint.endIndex &&
|
||||
otherCell.calendarGridPoint.endIndex > cell.calendarGridPoint.startIndex;
|
||||
if (isOverlapping) {
|
||||
// Adjust columnIndex to not overlap with the otherCell
|
||||
if (otherCell.gridColumnStart && otherCell.gridColumnStart >= columnIndex) {
|
||||
columnIndex = otherCell.gridColumnStart + 1;
|
||||
}
|
||||
cell.totalColumns += 1;
|
||||
}
|
||||
}
|
||||
Object.values(days).forEach((dayCells: CalendarGridCourse[], idx) => {
|
||||
try {
|
||||
calculateCourseCellColumns(dayCells);
|
||||
} catch (error) {
|
||||
console.error(`Error calculating course cell columns ${idx}`, error);
|
||||
if (sentryScope) {
|
||||
sentryScope.captureException(error);
|
||||
}
|
||||
cell.gridColumnStart = columnIndex;
|
||||
cell.gridColumnEnd = columnIndex + 1;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return courseCells
|
||||
|
||||
Reference in New Issue
Block a user