Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add badge to CourseListing showing number of seats open #319

Merged
merged 9 commits into from
Nov 20, 2020
12 changes: 12 additions & 0 deletions src/api/db/classinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ def get_classes_full(self, semester=None):
(
select
c1.crn,
c1.seats_open,
c1.seats_filled,
c1.seats_total,
c1.semester,
c1.min_credits,
c1.max_credits,
Expand Down Expand Up @@ -138,6 +141,9 @@ def get_classes_full(self, semester=None):
c1.crn,
c1.min_credits,
c1.max_credits,
c1.seats_open,
c1.seats_filled,
c1.seats_total,
c1.semester,
max(c1.department) as department,
max(c1.level) as level,
Expand Down Expand Up @@ -298,6 +304,9 @@ def get_classes_by_search(self, semester=None, search=None):
(
SELECT
c1.crn,
c1.seats_open,
c1.seats_filled,
c1.seats_total,
c1.semester,
MAX(c1.department) AS department,
MAX(c1.level) as level,
Expand Down Expand Up @@ -384,6 +393,9 @@ def get_classes_by_search(self, semester=None, search=None):
(
SELECT
c1.crn,
c1.seats_open,
c1.seats_filled,
c1.seats_total,
c1.semester,
MAX(c1.department) AS department,
MAX(c1.level) as level,
Expand Down
11 changes: 10 additions & 1 deletion src/api/db/courses.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@ def populate_from_csv(self, csv_text):
title,
raw_precoreqs,
school,
seats_open,
seats_filled,
seats_total,
tsv
)
VALUES (
Expand All @@ -139,6 +142,9 @@ def populate_from_csv(self, csv_text):
NULLIF(%(Title)s, ''),
NULLIF(%(RawPrecoreqText)s, ''),
%(School)s,
%(SeatsOpen)s,
%(SeatsFilled)s,
%(SeatsTotal)s,
setweight(to_tsvector(coalesce(%(FullTitle)s, '')), 'A') ||
setweight(to_tsvector(coalesce(%(Title)s, '')), 'A') ||
setweight(to_tsvector(coalesce(%(Department)s, '')), 'A') ||
Expand All @@ -163,7 +169,10 @@ def populate_from_csv(self, csv_text):
"Level": row['course_level'] if row['course_level'] and not row['course_level'].isspace() else None,
"Title": row['course_name'],
"RawPrecoreqText": row['raw_precoreqs'],
"School": row['school']
"School": row['school'],
"SeatsOpen": row['course_remained'],
"SeatsFilled": row['course_enrolled'],
"SeatsTotal": row['course_max_enroll']
}
)
# populate prereqs table, must come after course population b/c ref integrity
Expand Down
3 changes: 3 additions & 0 deletions src/data/schema/01_course.sql
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ create table course(
raw_precoreqs text,
frequency varchar(255),
school varchar(255),
seats_open int,
seats_filled int,
seats_total int,
tsv tsvector,
primary key (crn)
);
24 changes: 22 additions & 2 deletions src/web/src/components/CourseListing.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@
<b data-cy="name">{{ course.name }}</b>
({{ readableDate(course.date_start) }} -
{{ readableDate(course.date_end) }})

<br />
{{ course.title }}
<br />
<course-sections-open-badge :course="course" />
</div>
<div class="d-flex">
<slot
Expand Down Expand Up @@ -60,8 +63,18 @@
color: section.selected ? 'black' : 'var(--dark-text-primary)',
}"
>
{{ section.crn }} - {{ section.sessions[0].section }}
<br />
<b-row class="mb-2" align-h="between">
<b-col cols="auto">
{{ section.crn }} - {{ section.sessions[0].section }}
</b-col>
<b-col v-if="section.seats_total > 0" cols="auto">
<course-section-seats-badge
:seatsOpen="section.seats_open"
:seatsFilled="section.seats_filled"
:seatsTotal="section.seats_total"
/>
</b-col>
</b-row>

<span
v-for="courseSession in section.sessions"
Expand Down Expand Up @@ -97,6 +110,9 @@ import {
faChevronUp,
} from "@fortawesome/free-solid-svg-icons";

import CourseSectionSeatsBadge from "./CourseSectionSeatsBadge.vue";
import CourseSectionsOpenBadge from "./CourseSectionsOpenBadge.vue";

// Course Listing by default is a collapsible display of a course and its
// sections and sessions
// However, there are slots available to customize the information displayed
Expand All @@ -105,6 +121,10 @@ import {
// 2) collapseContent { course }
export default {
name: "CourseListing",
components: {
CourseSectionSeatsBadge,
CourseSectionsOpenBadge,
},
props: {
course: Object,

Expand Down
38 changes: 38 additions & 0 deletions src/web/src/components/CourseSectionSeatsBadge.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<template functional>
<b-badge
:variant="$options.getSeatStatusVariant(props.seatsOpen, props.seatsTotal)"
>
<slot
:seatsOpen="props.seatsOpen"
:seatsFilled="props.seatsFilled"
:seatsTotal="props.seatsTotal"
>
{{ props.seatsOpen }} / {{ props.seatsTotal }}
{{ $options.getSeatStatusText(props.seatsOpen) }}
</slot>
</b-badge>
</template>

<script>
export default {
props: {
seatsOpen: Number,
seatsFilled: Number,
seatsTotal: Number,
},
getSeatStatusText(seatsOpen) {
return seatsOpen <= 0 ? "Full" : "Open";
},
getSeatStatusVariant(seatsOpen, seatsTotal) {
if (seatsOpen <= 0) {
return "danger";
} else if (seatsOpen <= seatsTotal * 0.2) {
return "warning";
} else {
return "success";
}
},
};
</script>

<style></style>
24 changes: 24 additions & 0 deletions src/web/src/components/CourseSectionsOpenBadge.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<template functional>
<b-badge
v-if="$options.getNumOpenSections(props.course) > 0"
variant="success"
>
{{ $options.getNumOpenSections(props.course) }}/{{
props.course.sections.length
}}
Sections Open
</b-badge>
<b-badge v-else variant="danger">
All Sections Full
</b-badge>
</template>
<script>
export default {
props: {
course: Object,
},
getNumOpenSections(course) {
return course.sections.filter((section) => section.seats_open > 0).length;
},
};
</script>
8 changes: 7 additions & 1 deletion src/web/src/pages/CoursePage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@
<b-row>
<b-col>
<h1 class="mt-4">{{ courseTitle }}</h1>
<h4 class="mb-1">{{ courseName }}</h4>
<h4 class="mb-1 d-inline">{{ courseName }}</h4>
&nbsp;
<div class="d-inline">
<course-sections-open-badge :course="courseObj" />
</div>
</b-col>
</b-row>
<b-row>
Expand All @@ -32,8 +36,10 @@
import { getCourses } from "../services/YacsService";
import { getDefaultSemester } from "@/services/AdminService";
import { generateRequirementsText } from "@/utils";
import CourseSectionsOpenBadge from "../components/CourseSectionsOpenBadge.vue";

export default {
components: { CourseSectionsOpenBadge },
name: "CoursePage",
data() {
return {
Expand Down
19 changes: 12 additions & 7 deletions src/web/src/pages/SubjectExplorer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@
>
{{ course.title }}
<br />
{{ course.department }}
{{ course.level }}
<br />
<span class="d-inline">
{{ course.department }}
{{ course.level }}
</span>
<course-sections-open-badge :course="course" />
</b-button>
</b-col>
</b-row>
Expand All @@ -56,9 +58,11 @@
>
{{ course.title }}
<br />
{{ course.department }}
{{ course.level }}
<br />
<span class="d-inline">
{{ course.department }}
{{ course.level }}
</span>
<course-sections-open-badge :course="course" />
</b-button>
</b-col>
</b-row>
Expand All @@ -74,10 +78,11 @@
<script>
import { getCourses } from "../services/YacsService";
import { getDefaultSemester } from "@/services/AdminService";
import CourseSectionsOpenBadge from "../components/CourseSectionsOpenBadge.vue";

export default {
name: "SubjectExplorer",
components: {},
components: { CourseSectionsOpenBadge },
props: {
selectedSemester: String,
},
Expand Down
3 changes: 3 additions & 0 deletions src/web/src/typedef.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
* @property {string} semester
* @property {CourseSession[]} sessions
* @property {boolean} selected
* @property {number} seats_open
* @property {number} seats_filled
* @property {number} seats_total
*/
/**
* @typedef Course
Expand Down