wrote all course/schedule background messages with handlers

This commit is contained in:
Sriram Hariharan
2023-09-17 20:58:22 -05:00
parent 6061295e0a
commit 52431747ee
12 changed files with 159 additions and 7 deletions

View File

@@ -2,7 +2,12 @@ import { MessageHandler } from 'chrome-extension-toolkit';
import { UserScheduleMessages } from 'src/shared/messages/UserScheduleMessages';
import { Course } from 'src/shared/types/Course';
import addCourse from '../lib/addCourse';
import clearCourses from '../lib/clearCourses';
import createSchedule from '../lib/createSchedule';
import deleteSchedule from '../lib/deleteSchedule';
import removeCourse from '../lib/removeCourse';
import renameSchedule from '../lib/renameSchedule';
import switchSchedule from '../lib/switchSchedule';
const userScheduleHandler: MessageHandler<UserScheduleMessages> = {
addCourse({ data, sendResponse }) {
@@ -11,6 +16,21 @@ const userScheduleHandler: MessageHandler<UserScheduleMessages> = {
removeCourse({ data, sendResponse }) {
removeCourse(data.scheduleName, new Course(data.course)).then(sendResponse);
},
clearCourses({ data, sendResponse }) {
clearCourses(data.scheduleName).then(sendResponse);
},
switchSchedule({ data, sendResponse }) {
switchSchedule(data.scheduleName).then(sendResponse);
},
createSchedule({ data, sendResponse }) {
createSchedule(data.scheduleName).then(sendResponse);
},
deleteSchedule({ data, sendResponse }) {
deleteSchedule(data.scheduleName).then(sendResponse);
},
renameSchedule({ data, sendResponse }) {
renameSchedule(data.scheduleName, data.newName).then(sendResponse);
},
};
export default userScheduleHandler;

View File

@@ -11,7 +11,6 @@ export default async function addCourse(scheduleName: string, course: Course): P
throw new Error('Schedule not found');
}
activeSchedule.creditHours += course.creditHours;
activeSchedule.courses.push(course);
await UserScheduleStore.set('schedules', schedules);

View File

@@ -0,0 +1,11 @@
import { UserScheduleStore } from 'src/shared/storage/UserScheduleStore';
export default async function clearCourses(scheduleName: string): Promise<void> {
const schedules = await UserScheduleStore.get('schedules');
const schedule = schedules.find(schedule => schedule.name === scheduleName);
if (!schedule) {
throw new Error(`Schedule ${scheduleName} does not exist`);
}
schedule.courses = [];
await UserScheduleStore.set('schedules', schedules);
}

View File

@@ -0,0 +1,21 @@
import { UserScheduleStore } from 'src/shared/storage/UserScheduleStore';
/**
* Creates a new schedule with the given name
* @param scheduleName the name of the schedule to create
* @returns undefined if successful, otherwise an error message
*/
export default async function createSchedule(scheduleName: string): Promise<string | undefined> {
const schedules = await UserScheduleStore.get('schedules');
if (schedules.find(schedule => schedule.name === scheduleName)) {
return `Schedule ${scheduleName} already exists`;
}
schedules.push({
name: scheduleName,
courses: [],
});
await UserScheduleStore.set('schedules', schedules);
return undefined;
}

View File

@@ -0,0 +1,20 @@
import { UserScheduleStore } from 'src/shared/storage/UserScheduleStore';
export default async function deleteSchedule(scheduleName: string): Promise<string | undefined> {
const [schedules, activeIndex] = await Promise.all([
UserScheduleStore.get('schedules'),
UserScheduleStore.get('activeIndex'),
]);
const scheduleIndex = schedules.findIndex(schedule => schedule.name === scheduleName);
if (scheduleIndex === -1) {
return `Schedule ${scheduleName} does not exist`;
}
if (scheduleIndex === activeIndex) {
return 'Cannot delete active schedule';
}
schedules.splice(scheduleIndex, 1);
await UserScheduleStore.set('schedules', schedules);
return undefined;
}

View File

@@ -11,7 +11,6 @@ export default async function removeCourse(scheduleName: string, course: Course)
throw new Error('Schedule not found');
}
activeSchedule.creditHours -= course.creditHours;
activeSchedule.courses = activeSchedule.courses.filter(c => c.uniqueId !== course.uniqueId);
await UserScheduleStore.set('schedules', schedules);

View File

@@ -0,0 +1,17 @@
import { UserScheduleStore } from 'src/shared/storage/UserScheduleStore';
export default async function renameSchedule(scheduleName: string, newName: string): Promise<string | undefined> {
const schedules = await UserScheduleStore.get('schedules');
const scheduleIndex = schedules.findIndex(schedule => schedule.name === scheduleName);
if (scheduleIndex === -1) {
return `Schedule ${scheduleName} does not exist`;
}
if (schedules.find(schedule => schedule.name === newName)) {
return `Schedule ${newName} already exists`;
}
schedules[scheduleIndex].name = newName;
await UserScheduleStore.set('schedules', schedules);
return undefined;
}

View File

@@ -0,0 +1,12 @@
import { UserScheduleStore } from 'src/shared/storage/UserScheduleStore';
export default async function switchSchedule(scheduleName: string): Promise<void> {
const schedules = await UserScheduleStore.get('schedules');
const scheduleIndex = schedules.findIndex(schedule => schedule.name === scheduleName);
if (scheduleIndex === -1) {
throw new Error(`Schedule ${scheduleName} does not exist`);
}
await UserScheduleStore.set('activeIndex', scheduleIndex);
}

View File

@@ -1,7 +1,44 @@
import { Course } from '../types/Course';
export interface UserScheduleMessages {
/**
* Add a course to a schedule
* @param data the schedule name and course to add
*/
addCourse: (data: { scheduleName: string; course: Course }) => void;
/**
* Remove a course from a schedule
* @param data the schedule name and course to remove
*/
removeCourse: (data: { scheduleName: string; course: Course }) => void;
/**
* Clears all courses from a schedule
* @param data the name of the schedule to clear
*/
clearCourses: (data: { scheduleName: string }) => void;
/**
* Switches the active schedule to the one specified
* @param data the name of the schedule to switch to
*/
switchSchedule: (data: { scheduleName: string }) => void;
/**
* Creates a new schedule with the specified name
* @param data the name of the schedule to create
* @returns undefined if successful, otherwise an error message
*/
createSchedule: (data: { scheduleName: string }) => string | undefined;
/**
* Deletes a schedule with the specified name
* @param data the name of the schedule to delete
* @returns undefined if successful, otherwise an error message
*/
deleteSchedule: (data: { scheduleName: string }) => string | undefined;
/**
* Renames a schedule with the specified name
* @param data the name of the schedule to rename and the new name
* @returns undefined if successful, otherwise an error message
*/
renameSchedule: (data: { scheduleName: string; newName: string }) => string | undefined;
}

View File

@@ -14,7 +14,6 @@ export const UserScheduleStore = createLocalStore<IUserScheduleStore>({
new UserSchedule({
courses: [],
name: 'Schedule 1',
creditHours: 0,
}),
],
activeIndex: 0,

View File

@@ -7,11 +7,9 @@ import { Course } from './Course';
export class UserSchedule {
courses: Course[];
name: string;
creditHours: number;
constructor(schedule: Serialized<UserSchedule>) {
this.courses = schedule.courses.map(c => new Course(c));
this.creditHours = this.courses.reduce((acc, course) => acc + course.creditHours, 0);
this.name = schedule.name;
}

View File

@@ -1,6 +1,25 @@
import React from 'react';
import { bMessenger } from 'src/shared/messages';
import useSchedules from '../hooks/useSchedules';
import { Button } from './common/Button/Button';
import ExtensionRoot from './common/ExtensionRoot/ExtensionRoot';
const { clearCourses } = bMessenger;
export default function PopupMain() {
return <ExtensionRoot>Popup</ExtensionRoot>;
const [activeSchedule, schedules] = useSchedules();
// TODO: Add a button to to switch the active schedule
return (
<ExtensionRoot>
<Button
onClick={() => {
if (!activeSchedule) return;
clearCourses({ scheduleName: activeSchedule?.name });
}}
>
Clear Courses
</Button>
</ExtensionRoot>
);
}