Skip to content

Commit

Permalink
Matching bug fixes (#687)
Browse files Browse the repository at this point in the history
* Updated position-list to use classNames
* Updated forms for filter inputs and modals
* Removed no-longer-needed form imports
  • Loading branch information
elaine-huynh authored Aug 17, 2022
1 parent 1dec73b commit ef130af
Show file tree
Hide file tree
Showing 10 changed files with 143 additions and 95 deletions.
1 change: 1 addition & 0 deletions frontend/src/views/admin/matching/applicant-view/body.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export function ApplicantViewBody({
applicantSummaries={applicantSummaries}
/>
)}
<div className="applicant-view-filler"></div>
<div className="applicant-count">{applicantCountString}</div>
</div>
);
Expand Down
25 changes: 11 additions & 14 deletions frontend/src/views/admin/matching/applicant-view/grid/modals.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from "react";
import { Application } from "../../../../../api/defs/types";
import { MatchableAssignment } from "../../types";
import { Form, Modal, Button } from "react-bootstrap";
import { Modal, Button } from "react-bootstrap";
import { ApplicationDetails } from "../../../applications/application-details";
import { upsertMatch } from "../../actions";
import { useThunkDispatch } from "../../../../../libs/thunk-dispatch";
Expand Down Expand Up @@ -67,19 +67,16 @@ export function AdjustHourModal({
<Modal.Title>Update Hours</Modal.Title>
</Modal.Header>
<Modal.Body>
<Form>
<Form.Group className="mb-3">
<Form.Control
type="number"
defaultValue={
match && match.hoursAssigned > 0
? match.hoursAssigned
: 0
}
onChange={(e) => setHoursAssigned(e.target.value)}
/>
</Form.Group>
</Form>
<input
className="form-control"
type="number"
defaultValue={
match && match.hoursAssigned > 0
? match.hoursAssigned
: 0
}
onChange={(e) => setHoursAssigned(e.target.value)}
/>
</Modal.Body>
<Modal.Footer>
<Button
Expand Down
10 changes: 5 additions & 5 deletions frontend/src/views/admin/matching/applicant-view/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useSelector } from "react-redux";
import { useThunkDispatch } from "../../../../libs/thunk-dispatch";
import { setApplicantViewMode, applicantViewModeSelector } from "../actions";
import { FaFilter, FaTable, FaTh } from "react-icons/fa";
import { Form, ToggleButton, ToggleButtonGroup } from "react-bootstrap";
import { ToggleButton, ToggleButtonGroup } from "react-bootstrap";
import { SortBar } from "../sorts";
import { SortListItem } from "../sorts/sorts";
import { FilterModal } from "../filters";
Expand Down Expand Up @@ -33,14 +33,14 @@ export function ApplicantViewHeader({
return (
<div className="matching-course-header">
<div className="search-container">
<Form inline>
<Form.Control
<div className="form-inline">
<input
className="form-control mr-sm-2 search-bar"
type="text"
placeholder="Filter by name/UTORid..."
className="mr-sm-2"
onChange={(e) => setFilterString(e.target.value)}
/>
</Form>
</div>
<ApplicantFilterButton
filterList={filterList}
setFilterList={setFilterList}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,26 @@ const DEFAULT_COLUMNS = [
{ Header: "UTORid", accessor: "utorid" },
{ Header: "Department", accessor: "department" },
{ Header: "Program", accessor: "program" },
{ Header: "YIP", accessor: "yip" },
{ Header: "GPA", accessor: "gpa" },
{ Header: "TA Rating", accessor: "taPreference" },
{ Header: "Instructor Rating", accessor: "instructorPreference" },
{ Header: "YIP", accessor: "yip", width: 64 },
{ Header: "GPA", accessor: "gpa", width: 64 },
{ Header: "TA Rating", accessor: "taPreference", width: 64 },
{
Header: "Instructor Rating",
accessor: "instructorPreference",
width: 64,
},
{ Header: "Assignments", accessor: "assignments" },
{ Header: "Hours Assigned", accessor: "totalHoursAssigned" },
{ Header: "Hours Previously Assigned", accessor: "previousHoursFulfilled" },
{ Header: "Total Guaranteed Hours", accessor: "guaranteedHours" },
{ Header: "Assigned Hours", accessor: "totalHoursAssigned", width: 64 },
{
Header: "Previously Assigned Hours",
accessor: "previousHoursFulfilled",
width: 64,
},
{
Header: "Total Guaranteed Hours",
accessor: "guaranteedHours",
width: 64,
},
];

/**
Expand Down Expand Up @@ -105,8 +117,8 @@ export function TableView({
? programCodes[summary.application?.program]["full"]
: `Other (${summary.application?.program})`
: "",
yip: summary.application?.yip,
gpa: summary.application?.gpa,
yip: summary.application?.yip || "",
gpa: summary.application?.gpa || "",
taPreference: positionPrefsByApplicantId[summary.applicant.id],
instructorPreference: avgInstructorRating,
assignments: formatAssignedCourses(summary),
Expand Down
5 changes: 2 additions & 3 deletions frontend/src/views/admin/matching/filters/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,8 @@ export function FilterModal({
return (
<Modal
show={showFilters}
onHide={() => {
setShowFilters(false);
}}
onHide={() => setShowFilters(false)}
size="xl"
dialogClassName="filter-modal"
>
<Modal.Header>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,13 @@ export function ImportGuaranteesButton() {
className="footer-button"
onClick={() => setAddDialog(true)}
>
Import Appt. Data
Import Sub. Appt. Data
</Button>
<Modal show={addDialog}>
<Modal show={addDialog} onHide={() => setAddDialog(false)}>
<Modal.Header>
<Modal.Title>Import Appointment Guarantee Data</Modal.Title>
<Modal.Title>
Import Subsequent Appointment Data
</Modal.Title>
</Modal.Header>
<Modal.Body>
<Form>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ export function ImportMatchingDataButton() {
>
Import Data
</Button>
<Modal show={addDialog}>
<Modal show={addDialog} onHide={() => setAddDialog(false)}>
<Modal.Header>
<Modal.Title>Import Matching Data</Modal.Title>
</Modal.Header>
Expand Down
31 changes: 21 additions & 10 deletions frontend/src/views/admin/matching/position-list.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React from "react";
import classNames from "classnames";
import { useThunkDispatch } from "../../../libs/thunk-dispatch";
import { round } from "../../../libs/utils";
import { PositionSummary } from "./types";
import { setSelectedMatchingPosition } from "./actions";
import { Form } from "react-bootstrap";

/**
* A searchable list of position codes.
Expand Down Expand Up @@ -36,15 +36,14 @@ export function PositionList({
return (
<div className="position-sidebar">
<div className="search-container position-search">
<Form inline>
<Form.Control
<div className="form-inline">
<input
className="form-control mr-sm-2 search-bar"
type="text"
placeholder="Filter by position code..."
style={{ width: "100%" }}
className="mr-sm-2"
onChange={(e) => setFilterString(e.target.value)}
/>
</Form>
</div>
</div>
<div className="position-list">
{filteredList.map((summary) => (
Expand Down Expand Up @@ -92,17 +91,20 @@ function PositionRow({

return (
<div
className="position-row noselect"
className={classNames(
"position-row",
"noselect",
positionSummary.filledStatus,
{ selected: focused }
)}
onClick={() =>
dispatch(
setSelectedMatchingPosition(positionSummary.position.id)
)
}
>
<div
className={`status-sidebar ${positionSummary.filledStatus} ${
focused ? "selected" : ""
}`}
className={`status-sidebar ${positionSummary.filledStatus}`}
></div>
<div className="position-row-body">
<div className="position-row-background">
Expand All @@ -118,6 +120,15 @@ function PositionRow({
<span className="position-hours-filled">
{positionSummary.hoursAssigned} / {targetHours} h
</span>
{focused && (
<span className="position-row-detail">
{positionSummary.applicantSummaries.length}{" "}
applicant
{positionSummary.applicantSummaries.length === 1
? ""
: "s"}
</span>
)}
</div>
</div>
</div>
Expand Down
47 changes: 25 additions & 22 deletions frontend/src/views/admin/matching/sorts/sorts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export function applySorts(
) {
// Return early if any inputs aren't defined
if (applicantSummaries.length === 0 || sortList.length === 0) {
return [];
return [...applicantSummaries];
}

const ret: ApplicantSummary[] = [...applicantSummaries];
Expand Down Expand Up @@ -77,7 +77,7 @@ function flipIfDescending(val: number, asc: boolean) {
// Sorting functions -- all of these do in-place sorting
function sortByFirstName(applicantSummaries: ApplicantSummary[], asc = true) {
applicantSummaries.sort((a, b) => {
return `${a.applicant.first_name}, ${a.applicant.last_name}`.toLowerCase() <
return `${a.applicant.first_name}, ${a.applicant.last_name}`.toLowerCase() <=
`${b.applicant.first_name}, ${b.applicant.last_name}`.toLowerCase()
? flipIfDescending(-1, asc)
: flipIfDescending(1, asc);
Expand All @@ -86,7 +86,7 @@ function sortByFirstName(applicantSummaries: ApplicantSummary[], asc = true) {

function sortByLastName(applicantSummaries: ApplicantSummary[], asc = true) {
applicantSummaries.sort((a, b) => {
return `${a.applicant.last_name}, ${a.applicant.first_name}`.toLowerCase() <
return `${a.applicant.last_name}, ${a.applicant.first_name}`.toLowerCase() <=
`${b.applicant.last_name}, ${b.applicant.first_name}`.toLowerCase()
? flipIfDescending(-1, asc)
: flipIfDescending(1, asc);
Expand Down Expand Up @@ -128,18 +128,18 @@ function sortByProgram(applicantSummaries: ApplicantSummary[], asc = true) {
function sortByGpa(applicantSummaries: ApplicantSummary[], asc = true) {
applicantSummaries.sort((a, b) => {
if (!a.application?.gpa) {
return flipIfDescending(1, asc);
return flipIfDescending(-1, asc);
}

if (!b.application?.gpa) {
return flipIfDescending(-1, asc);
return flipIfDescending(1, asc);
}

if (a.application?.gpa === b.application?.gpa) {
return 0;
}

return a.application?.gpa > b.application?.gpa
return a.application?.gpa <= b.application?.gpa
? flipIfDescending(-1, asc)
: flipIfDescending(1, asc);
});
Expand All @@ -148,11 +148,11 @@ function sortByGpa(applicantSummaries: ApplicantSummary[], asc = true) {
function sortByYip(applicantSummaries: ApplicantSummary[], asc = true) {
applicantSummaries.sort((a, b) => {
if (!a.application?.yip) {
return 1;
return flipIfDescending(-1, asc);
}

if (!b.application?.yip) {
return -1;
return flipIfDescending(1, asc);
}

if (a.application?.yip === b.application?.yip) {
Expand All @@ -168,11 +168,15 @@ function sortByYip(applicantSummaries: ApplicantSummary[], asc = true) {
function sortByDepartment(applicantSummaries: ApplicantSummary[], asc = true) {
applicantSummaries.sort((a, b) => {
if (!a.application?.department) {
return flipIfDescending(1, asc);
return flipIfDescending(-1, asc);
}

if (!b.application?.department) {
return flipIfDescending(-1, asc);
return flipIfDescending(1, asc);
}

if (a.application?.department === b.application?.department) {
return 0;
}

return a.application?.department < b.application?.department
Expand Down Expand Up @@ -265,11 +269,11 @@ function sortByTotalHoursAssigned(
) {
applicantSummaries.sort((a, b) => {
if (!a.matches) {
return 1;
return flipIfDescending(-1, asc);
}

if (!b.matches) {
return -1;
return flipIfDescending(1, asc);
}

const aHours = a.hoursAssigned;
Expand Down Expand Up @@ -308,23 +312,22 @@ function sortByRemainingHoursOwed(
asc = true
) {
applicantSummaries.sort((a, b) => {
if (!a.matches || !a.guarantee) {
return 1;
}
const aHoursOwed = a.guarantee?.minHoursOwed || 0;
const bHoursOwed = a.guarantee?.minHoursOwed || 0;

if (!b.matches || !b.guarantee) {
return -1;
// Neither applicant has a guarantee to worry about
if (aHoursOwed === bHoursOwed) {
return 0;
}

let aHoursRemaining =
(a.guarantee?.minHoursOwed || 0) -
aHoursOwed -
(a.guarantee?.previousHoursFulfilled || 0) -
a.hoursAssigned;

(a.hoursAssigned || 0);
let bHoursRemaining =
(b.guarantee?.minHoursOwed || 0) -
bHoursOwed -
(b.guarantee?.previousHoursFulfilled || 0) -
b.hoursAssigned;
(b.hoursAssigned || 0);

if (aHoursRemaining === bHoursRemaining) {
return 0;
Expand Down
Loading

0 comments on commit ef130af

Please sign in to comment.