lot of refactoring, reorganized course buttons. Now linking to professors directory page

This commit is contained in:
Sriram Hariharan
2023-03-07 21:49:41 -06:00
parent 04a82fb6a6
commit 353c43c987
26 changed files with 556 additions and 311 deletions

View File

@@ -1,17 +1,7 @@
import { Serialized } from 'chrome-extension-toolkit';
import { capitalize } from '../util/string';
import { CourseSchedule } from './CourseSchedule';
/**
* A professor's name, first name, and initial (if applicable)
* Also includes a link to their RateMyProfessor page
*/
export type Instructor = {
fullName: string;
firstName: string;
lastName: string;
middleInitial?: string;
};
import Instructor from './Instructor';
/**
* Whether the class is taught online, in person, or a hybrid of the two
@@ -41,6 +31,7 @@ export type Semester = {
/**
* The internal representation of a course for the extension
*/
export class Course {
/** Every course has a uniqueId within UT's registrar system corresponding to each course section */
uniqueId: number;
@@ -73,40 +64,10 @@ export class Course {
/** Which semester is the course from */
semester: Semester;
constructor(course: Serialized<Course>) {
constructor(course: Serialized<Course> | Course) {
Object.assign(this, course);
this.schedule = new CourseSchedule(course.schedule);
}
/**
* Get a string representation of the instructors for this course
* @param options - the options for how to format the instructor string
* @returns
*/
getInstructorString(options: InstructorFormatOptions): string {
const { max = 3, format, prefix = '' } = options;
if (!this.instructors.length) {
return `${prefix} TBA`;
}
const instructors = this.instructors.slice(0, max);
if (format === 'abbr') {
return prefix + instructors.map(i => `${capitalize(i.firstName[0])}. ${capitalize(i.lastName)}`).join(', ');
}
if (format === 'full_name') {
return prefix + instructors.map(i => capitalize(i.fullName)).join(', ');
}
if (format === 'first_last') {
return prefix + instructors.map(i => `${capitalize(i.firstName)} ${capitalize(i.lastName)}`).join(', ');
}
if (format === 'last') {
return prefix + instructors.map(i => i.lastName).join(', ');
}
throw new Error(`Invalid Instructor String format: ${format}`);
this.instructors = course.instructors.map(i => new Instructor(i));
}
}
@@ -117,15 +78,3 @@ export type ScrapedRow = {
element: HTMLTableRowElement;
course: Course | null;
};
/**
* Options for how to format the instructor string
*/
type InstructorFormatOptions = {
/** a prefix to add to the string, ex: "with" Mike Scott */
prefix?: string;
/** The maximum number of instructors to show */
max?: number;
/** How do you want the names of the professors formatted */
format: 'abbr' | 'first_last' | 'last' | 'full_name';
};

View File

@@ -37,7 +37,7 @@ export class CourseMeeting {
/** The location that the course is taught */
location?: Location;
constructor(meeting: Serialized<CourseMeeting>) {
constructor(meeting: Serialized<CourseMeeting> | CourseMeeting) {
Object.assign(this, meeting);
}

View File

@@ -7,7 +7,7 @@ import { CourseMeeting, Day, DAY_MAP } from './CourseMeeting';
export class CourseSchedule {
meetings: CourseMeeting[] = [];
constructor(courseSchedule?: Serialized<CourseSchedule>) {
constructor(courseSchedule?: Serialized<CourseSchedule> | CourseSchedule) {
if (!courseSchedule) {
return;
}

View File

@@ -0,0 +1,83 @@
import { Serialized } from 'chrome-extension-toolkit';
import { capitalize } from '../util/string';
/**
* A type representing an instructor for a course (who teaches it)
*/
export default class Instructor {
fullName: string;
firstName: string;
lastName: string;
middleInitial?: string;
constructor(instructor: Serialized<Instructor>) {
Object.assign(this, {
...instructor,
});
}
/**
* Get the URL to the instructor's directory page on the UT Directory website
* @returns a URL string to the instructor's directory page
*/
getDirectoryUrl(): string {
const name = this.toString({
format: 'full_name',
case: 'capitalize',
});
const url = new URL('https://directory.utexas.edu/index.php');
url.searchParams.set('q', name);
url.searchParams.set('scope', 'faculty/staff');
url.searchParams.set('submit', 'Search');
return url.toString();
}
/**
* Get a string representation of the instructor
* @param options the options for how to format the instructor string
* @returns a string representation of the instructor
*/
toString(options: InstructorFormatOptions): string {
const { firstName, lastName, fullName } = this;
const { format, case: caseType } = options;
const process = (str: string) => {
if (caseType === 'lowercase') {
return str.toLowerCase();
}
if (caseType === 'uppercase') {
return str.toUpperCase();
}
return capitalize(str);
};
if (format === 'abbr') {
return `${process(firstName[0])}. ${process(lastName)}`;
}
if (format === 'full_name') {
return process(fullName);
}
if (format === 'first_last') {
return `${process(firstName)} ${process(lastName)}`;
}
if (format === 'last') {
return process(lastName);
}
throw new Error(`Invalid Instructor String format: ${format}`);
}
}
/**
* Options for how to format the instructor string
*/
type InstructorFormatOptions = {
/** How do you want the names of the professors formatted */
format: 'abbr' | 'first_last' | 'last' | 'full_name';
/**
* What the case of the string should be
*/
case: 'capitalize' | 'lowercase' | 'uppercase';
};