refactor(UserSchedule): index by a unique id rather than name (#166)

* refactor(UserSchedule): index by a unique id rather than name

* refactor: Update parameter names in schedule function jsdocs

* refactor: change more instances of .name to .id

* refactor: Fix typo in variable name and update references

* refactor: Remove console.log statement

* fix(chromatic): Update ScheduleListItem story

* refactor: remove unused eslint rule
This commit is contained in:
Razboy20
2024-03-14 23:09:04 -05:00
committed by GitHub
parent 5714ed16d7
commit 85769e9d2c
31 changed files with 182 additions and 304 deletions

View File

@@ -1,5 +1,6 @@
import { UserScheduleStore } from '@shared/storage/UserScheduleStore';
import { UserSchedule } from '@shared/types/UserSchedule';
import { generateRandomId } from '@shared/util/random';
import type { Meta, StoryObj } from '@storybook/react';
import List from '@views/components/common/List/List';
import ScheduleDropdown from '@views/components/common/ScheduleDropdown/ScheduleDropdown';
@@ -14,6 +15,7 @@ const schedules: UserSchedule[] = new Array(10).fill(exampleSchedule).map(
(schedule: UserSchedule, index) =>
new UserSchedule({
...schedule,
id: generateRandomId(),
name: `Schedule ${index + 1}`,
})
);
@@ -61,10 +63,10 @@ const meta: Meta<typeof ScheduleDropdown> = {
<ScheduleDropdown {...args}>
<List
draggables={schedules}
equalityCheck={(a, b) => a.name === b.name}
itemKey={s => s.id}
onReordered={reordered => {
const activeSchedule = getActiveSchedule();
const activeIndex = reordered.findIndex(s => s.name === activeSchedule.name);
const activeIndex = reordered.findIndex(s => s.id === activeSchedule.id);
// don't care about the promise
UserScheduleStore.set('schedules', reordered);
@@ -74,9 +76,9 @@ const meta: Meta<typeof ScheduleDropdown> = {
>
{(schedule, handleProps) => (
<ScheduleListItem
name={schedule.name}
schedule={schedule}
onClick={() => {
switchSchedule(schedule.name);
switchSchedule(schedule.id);
}}
dragHandleProps={handleProps}
/>

View File

@@ -96,6 +96,7 @@ export const Default: Story = {
args: {
draggables: exampleCourses.map((course, i) => ({ course, colors: tailwindColorways[i] })),
children: generateCourseBlocks,
itemKey: (item: { course: Course }) => item.course.uniqueId,
gap: 12,
},
render: args => (

View File

@@ -1,37 +1,49 @@
/* eslint-disable jsdoc/require-jsdoc */
import { UserSchedule } from '@shared/types/UserSchedule';
import type { Meta, StoryObj } from '@storybook/react';
import ScheduleListItem from '@views/components/common/ScheduleListItem/ScheduleListItem';
import useSchedules from '@views/hooks/useSchedules';
import React from 'react';
export default {
import { exampleSchedule } from '../injected/mocked';
const meta = {
title: 'Components/Common/ScheduleListItem',
component: ScheduleListItem,
parameters: {
layout: 'centered',
tags: ['autodocs'],
},
argTypes: {
active: { control: 'boolean' },
name: { control: 'text' },
schedule: {
control: {
type: 'UserSchedule',
},
},
},
args: {
schedule: exampleSchedule,
},
tags: ['autodocs'],
} satisfies Meta<typeof ScheduleListItem>;
export default meta;
type Story = StoryObj<typeof meta>;
export const Active: Story = {
render(args) {
// eslint-disable-next-line react-hooks/rules-of-hooks
const [activeSchedule] = useSchedules();
return (
<ScheduleListItem
{...args}
schedule={
new UserSchedule({
...exampleSchedule,
id: activeSchedule.id,
})
}
/>
);
},
};
export const Default = args => <ScheduleListItem {...args} />;
Default.args = {
name: 'My Schedule',
active: true,
};
export const Active = args => <ScheduleListItem {...args} />;
Active.args = {
name: 'My Schedule',
active: true,
};
export const Inactive = args => <ScheduleListItem {...args} />;
Inactive.args = {
name: 'My Schedule',
active: false,
};
export const Inactive: Story = {};

View File

@@ -1,8 +1,3 @@
import { Course, Status } from '@shared/types/Course';
import { CourseMeeting, DAY_MAP } from '@shared/types/CourseMeeting';
import { CourseSchedule } from '@shared/types/CourseSchedule';
import Instructor from '@shared/types/Instructor';
import { UserSchedule } from '@shared/types/UserSchedule';
import type { Meta, StoryObj } from '@storybook/react';
import { CalendarSchedules } from '@views/components/calendar/CalendarSchedules/CalendarSchedules';
import React from 'react';
@@ -14,11 +9,7 @@ const meta = {
layout: 'centered',
tags: ['autodocs'],
},
argTypes: {
// dummySchedules: { control: 'object' },
// dummyActiveIndex: { control: 'number' },
},
render: (args: any) => (
render: args => (
<div>
<CalendarSchedules {...args} />
</div>
@@ -28,122 +19,4 @@ const meta = {
export default meta;
type Story = StoryObj<typeof meta>;
const schedules = [
new UserSchedule({
courses: [
new Course({
uniqueId: 123,
number: '311C',
fullName: "311C - Bevo's Default Course",
courseName: "Bevo's Default Course",
department: 'BVO',
creditHours: 3,
status: Status.WAITLISTED,
instructors: [new Instructor({ firstName: '', lastName: 'Bevo', fullName: 'Bevo' })],
isReserved: false,
url: '',
flags: [],
schedule: new CourseSchedule({
meetings: [
new CourseMeeting({
days: [DAY_MAP.M, DAY_MAP.W, DAY_MAP.F],
startTime: 480,
endTime: 570,
location: {
building: 'UTC',
room: '123',
},
}),
],
}),
instructionMode: 'In Person',
semester: {
year: 2024,
season: 'Fall',
},
scrapedAt: Date.now(),
}),
],
name: 'Main Schedule',
hours: 0,
updatedAt: Date.now(),
}),
new UserSchedule({
courses: [
new Course({
uniqueId: 123,
number: '311C',
fullName: "311C - Bevo's Default Course",
courseName: "Bevo's Default Course",
department: 'BVO',
creditHours: 3,
status: Status.WAITLISTED,
instructors: [new Instructor({ firstName: '', lastName: 'Bevo', fullName: 'Bevo' })],
isReserved: false,
url: '',
flags: [],
schedule: new CourseSchedule({
meetings: [
new CourseMeeting({
days: [DAY_MAP.M, DAY_MAP.W, DAY_MAP.F],
startTime: 480,
endTime: 570,
location: {
building: 'UTC',
room: '123',
},
}),
],
}),
instructionMode: 'In Person',
semester: {
year: 2024,
season: 'Spring',
},
scrapedAt: Date.now(),
}),
new Course({
uniqueId: 123,
number: '311C',
fullName: "311C - Bevo's Default Course",
courseName: "Bevo's Default Course",
department: 'BVO',
creditHours: 3,
status: Status.WAITLISTED,
instructors: [new Instructor({ firstName: '', lastName: 'Bevo', fullName: 'Bevo' })],
isReserved: false,
url: '',
flags: [],
schedule: new CourseSchedule({
meetings: [
new CourseMeeting({
days: [DAY_MAP.M, DAY_MAP.W, DAY_MAP.F],
startTime: 480,
endTime: 570,
location: {
building: 'UTC',
room: '123',
},
}),
],
}),
instructionMode: 'In Person',
semester: {
year: 2024,
season: 'Fall',
},
scrapedAt: Date.now(),
}),
],
name: 'Backup #3',
hours: 0,
updatedAt: Date.now(),
}),
];
export const Default: Story = {
args: {
// dummySchedules: schedules,
// dummyActiveIndex: 0,
},
};
export const Default: Story = {};

View File

@@ -1,11 +1,10 @@
import type { Course } from '@shared/types/Course';
import { Status } from '@shared/types/Course';
import { UserSchedule } from '@shared/types/UserSchedule';
import type { Meta, StoryObj } from '@storybook/react';
import CourseCatalogInjectedPopup from '@views/components/injected/CourseCatalogInjectedPopup/CourseCatalogInjectedPopup';
import React, { useState } from 'react';
import { bevoCourse, bevoScheule, MikeScottCS314Course, MikeScottCS314Schedule } from './mocked';
import { bevoCourse, mikeScottCS314Course } from './mocked';
const meta = {
title: 'Components/Injected/CourseCatalogInjectedPopup',
@@ -14,23 +13,7 @@ const meta = {
open: true,
onClose: () => {},
},
argTypes: {
course: {
control: {
type: 'object',
},
},
activeSchedule: {
control: {
type: 'object',
},
},
onClose: {
control: {
type: 'function',
},
},
},
tags: ['autodocs'],
render(args) {
// eslint-disable-next-line react-hooks/rules-of-hooks
const [isOpen, setIsOpen] = useState(args.open);
@@ -44,24 +27,21 @@ type Story = StoryObj<typeof meta>;
export const OpenCourse: Story = {
args: {
course: MikeScottCS314Course,
activeSchedule: MikeScottCS314Schedule,
course: mikeScottCS314Course,
},
};
export const ClosedCourse: Story = {
args: {
course: {
...MikeScottCS314Course,
...mikeScottCS314Course,
status: Status.CLOSED,
} as Course,
activeSchedule: new UserSchedule({ courses: [], name: '', hours: 0, updatedAt: Date.now() }),
},
};
export const CourseWithNoData: Story = {
args: {
course: bevoCourse,
activeSchedule: bevoScheule,
},
};

View File

@@ -55,6 +55,7 @@ export const exampleCourse: Course = new Course({
export const exampleSchedule: UserSchedule = new UserSchedule({
courses: [exampleCourse],
id: 'az372389blep',
name: 'Example Schedule',
hours: 3,
updatedAt: Date.now(),
@@ -105,14 +106,15 @@ export const bevoCourse: Course = new Course({
scrapedAt: Date.now(),
});
export const bevoScheule: UserSchedule = new UserSchedule({
export const bevoSchedule: UserSchedule = new UserSchedule({
courses: [bevoCourse],
id: 'bevoshenanigans52',
name: 'Bevo Schedule',
hours: 3,
updatedAt: Date.now(),
});
export const MikeScottCS314Course: Course = new Course({
export const mikeScottCS314Course: Course = new Course({
uniqueId: 50805,
number: '314',
fullName: 'C S 314 DATA STRUCTURES',
@@ -158,8 +160,9 @@ export const MikeScottCS314Course: Course = new Course({
scrapedAt: Date.now(),
});
export const MikeScottCS314Schedule: UserSchedule = new UserSchedule({
courses: [MikeScottCS314Course],
export const mikeScottCS314Schedule: UserSchedule = new UserSchedule({
courses: [mikeScottCS314Course],
id: 'omgitsmikescott314',
name: 'Mike Scott CS314 Schedule',
hours: 3,
updatedAt: Date.now(),