course conflict highlighting and calculations
This commit is contained in:
@@ -20,4 +20,5 @@ export const userScheduleStore = createLocalStore<IUserScheduleStore>({
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
debugStore({ userScheduleStore });
|
debugStore({ userScheduleStore });
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* eslint-disable max-classes-per-file */
|
/* eslint-disable max-classes-per-file */
|
||||||
import { Serialized } from 'chrome-extension-toolkit';
|
import { Serialized } from 'chrome-extension-toolkit';
|
||||||
import { capitalize } from '../util/string';
|
import { CourseMeeting } from './CourseMeeting';
|
||||||
import { CourseSchedule } from './CourseSchedule';
|
import { CourseSchedule } from './CourseSchedule';
|
||||||
import Instructor from './Instructor';
|
import Instructor from './Instructor';
|
||||||
|
|
||||||
@@ -74,6 +74,24 @@ export class Course {
|
|||||||
this.schedule = new CourseSchedule(course.schedule);
|
this.schedule = new CourseSchedule(course.schedule);
|
||||||
this.instructors = course.instructors.map(i => new Instructor(i));
|
this.instructors = course.instructors.map(i => new Instructor(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a list of all the conflicts between this course and another course (i.e. if they have a meeting at the same time)
|
||||||
|
* @param other another course to compare this course to
|
||||||
|
* @returns a list of all the conflicts between this course and the other course as a tuple of the two conflicting meetings
|
||||||
|
*/
|
||||||
|
getConflicts(other: Course): [CourseMeeting, CourseMeeting][] {
|
||||||
|
const conflicts: [CourseMeeting, CourseMeeting][] = [];
|
||||||
|
for (const meeting of this.schedule.meetings) {
|
||||||
|
for (const otherMeeting of other.schedule.meetings) {
|
||||||
|
if (meeting.isConflicting(otherMeeting)) {
|
||||||
|
conflicts.push([meeting, otherMeeting]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return conflicts;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -41,6 +41,22 @@ export class CourseMeeting {
|
|||||||
Object.assign(this, meeting);
|
Object.assign(this, meeting);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether or not this meeting conflicts with another meeting
|
||||||
|
* MWF 10:00 am - 11:00 am conflicts with a F 10:00 am - 10:30 am
|
||||||
|
* @param meeting the meeting to check for conflicts with
|
||||||
|
* @returns true if the given meeting conflicts with this meeting, false otherwise
|
||||||
|
*/
|
||||||
|
isConflicting(meeting: CourseMeeting): boolean {
|
||||||
|
const { days, startTime, endTime } = this;
|
||||||
|
const { days: otherDays, startTime: otherStartTime, endTime: otherEndTime } = meeting;
|
||||||
|
|
||||||
|
const hasDayConflict = days.some(day => otherDays.includes(day));
|
||||||
|
const hasTimeConflict = startTime < otherEndTime && endTime > otherStartTime;
|
||||||
|
|
||||||
|
return hasDayConflict && hasTimeConflict;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the string representation of the days of the week that this meeting is taught
|
* Return the string representation of the days of the week that this meeting is taught
|
||||||
* @param options options for the string representation
|
* @param options options for the string representation
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ export default function CourseCatalogMain({ support }: Props) {
|
|||||||
key={row.course.uniqueId}
|
key={row.course.uniqueId}
|
||||||
row={row}
|
row={row}
|
||||||
isSelected={row.course.uniqueId === selectedCourse?.uniqueId}
|
isSelected={row.course.uniqueId === selectedCourse?.uniqueId}
|
||||||
isInActiveSchedule={Boolean(activeSchedule?.containsCourse(row.course))}
|
activeSchedule={activeSchedule}
|
||||||
onClick={handleRowButtonClick(row.course)}
|
onClick={handleRowButtonClick(row.course)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import {
|
|||||||
queryAggregateDistribution,
|
queryAggregateDistribution,
|
||||||
querySemesterDistribution,
|
querySemesterDistribution,
|
||||||
} from 'src/views/lib/database/queryDistribution';
|
} from 'src/views/lib/database/queryDistribution';
|
||||||
import { bMessenger } from 'src/shared/messages';
|
|
||||||
import styles from './GradeDistribution.module.scss';
|
import styles from './GradeDistribution.module.scss';
|
||||||
|
|
||||||
enum DataStatus {
|
enum DataStatus {
|
||||||
@@ -137,7 +136,6 @@ export default function GradeDistribution({ course }: Props) {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
queryAggregateDistribution(course)
|
queryAggregateDistribution(course)
|
||||||
.then(([distribution, semesters]) => {
|
.then(([distribution, semesters]) => {
|
||||||
console.log('.then -> distribution, semesters:', distribution, semesters);
|
|
||||||
setSemesters(semesters);
|
setSemesters(semesters);
|
||||||
updateChart(distribution);
|
updateChart(distribution);
|
||||||
setStatus(DataStatus.FOUND);
|
setStatus(DataStatus.FOUND);
|
||||||
|
|||||||
@@ -21,7 +21,8 @@
|
|||||||
|
|
||||||
.isConflict {
|
.isConflict {
|
||||||
* {
|
* {
|
||||||
color: $speedway_brick !important;
|
color: $speedway_brick;
|
||||||
text-decoration: line-through !important;
|
text-decoration: line-through !important;
|
||||||
|
font-weight: normal !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,9 +50,21 @@ export default function TableRow({ row, isSelected, activeSchedule, onClick }: P
|
|||||||
}, [activeSchedule, element.classList]);
|
}, [activeSchedule, element.classList]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// if (!activeSchedule || !course) return;
|
if (!activeSchedule || !course) {
|
||||||
// TODO: handle conflicts here
|
return;
|
||||||
}, []);
|
}
|
||||||
|
|
||||||
|
let hasConflicts = activeSchedule.courses.find(c => {
|
||||||
|
let conflicts = course.getConflicts(c);
|
||||||
|
return conflicts.length > 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
element.classList[hasConflicts ? 'add' : 'remove'](styles.isConflict);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
element.classList.remove(styles.isConflict);
|
||||||
|
};
|
||||||
|
}, [activeSchedule, course]);
|
||||||
|
|
||||||
if (!container) {
|
if (!container) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
Reference in New Issue
Block a user