Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
- Updated the Zoom In/Zoom Out buttons on the graph page to Awesome Icons from +/-
- Added the React ErrorBoundary library and implemented an ErrorBoundary for the Graph component in the Container component and `js/components/draw/main.js`
- Updated the export button on the graph and grid pages to Awesome Icons; also added highlight effect and tooltip popup on hover
- Added an autocomplete feature to the search bar `js/components/generate/GenerateForm`, also rewrote tests related to this feature

### 🐛 Bug fixes

Expand Down
68 changes: 68 additions & 0 deletions js/components/generate/AutocompleteDropdown.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import React, { useEffect, useState } from "react"
import Autocomplete from "@mui/material/Autocomplete"
import Chip from "@mui/material/Chip"
import { useField } from "formik"
import PropTypes from "prop-types"

export default function AutocompleteDropdown({
name,
placeholder,
id,
onSelectedChange,
...props
}) {
const [, , helpers] = useField(name)
const { setValue } = helpers
const [optionList, setOptionList] = useState([])

useEffect(() => {
fetch("/courses")
.then(response => response.text())
.then(data => {
const courses = data.split("\n").map(course => course.substring(0, 8))
setOptionList(courses)
})
}, [])

return (
<Autocomplete
multiple
onChange={(event, newValues) => {
onSelectedChange(newValues)
setValue(newValues.join(", "))
}}
options={optionList}
includeInputInList
disableClearable
disableCloseOnSelect
popupIcon={null}
sx={{ width: "100%" }}
renderValue={(value, getItemProps) =>
value.map((option, index) => {
const { key, ...itemProps } = getItemProps({ index })
return <Chip variant="outlined" label={option} key={key} {...itemProps} />
})
}
renderInput={params => (
<div ref={params.InputProps.ref}>
<input
aria-label={name}
className="autocomplete-input"
type="text"
{...params.inputProps}
placeholder={placeholder}
id={id}
/>
</div>
)}
{...props}
/>
)
}

AutocompleteDropdown.propTypes = {
name: PropTypes.string,
placeholder: PropTypes.string,
id: PropTypes.string,
onSelectedChange: PropTypes.func,
}
18 changes: 15 additions & 3 deletions js/components/generate/GenerateForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ import { Tooltip } from "react-tooltip"
import { Graph, populateHybridRelatives } from "../graph/Graph"
import Disclaimer from "../common/Disclaimer"
import { NavBar } from "../common/NavBar.js.jsx"
import AutocompleteDropdown from "./AutocompleteDropdown.js"

export default class GenerateForm extends React.Component {
constructor(props) {
super(props)
this.state = {
fceCount: 0,
selectedCourses: [],
}

this.graph = React.createRef()
Expand All @@ -25,6 +27,10 @@ export default class GenerateForm extends React.Component {
this.setState({ fceCount: this.state.fceCount + credits })
}

handleCoursesChange = newCourse => {
this.setState({ selectedCourses: newCourse })
}

handleSubmit = (values, { setErrors }) => {
const data = {}

Expand Down Expand Up @@ -330,7 +336,7 @@ export default class GenerateForm extends React.Component {
courses: "",
programs: "",
taken: "",
departments: "CSC, MAT, STA",
departments: "",
maxDepth: 0,
location: ["utsg"],
includeRaws: false,
Expand Down Expand Up @@ -377,19 +383,25 @@ export default class GenerateForm extends React.Component {
></a>
<Tooltip id="courses-tooltip" place="right" />
</div>
<Field
<AutocompleteDropdown
id="courses"
aria-label="courses"
name="courses"
type="text"
placeholder="e.g., CSC207H1, CSC324H1"
onSelectedChange={this.handleCoursesChange}
className="autocomplete"
/>
<div className="error-container">
<ErrorMessage
className="error-message"
name="courses"
type="text"
component="div"
/>
</div>
<h1 className="chosen-courses">
Selected Courses: {this.state.selectedCourses.join(", ")}
</h1>
</>
)}

Expand Down
Loading