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
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@

### 🔧 Internal changes

- Migrated `Sidebar.js`, `FocusBar.js`, and `NavBar.js.jsx` to TypeScript
- Removed `Time'` data type in favour of `(MeetingId -> Times)` function type in `Database.Tables`
- Refactored `Database.Tables.MeetTime'` into `Models.Meeting` and renamed it to `MeetingData`
- Refactored `Database.Tables.Time` into `Models.Time` and renamed it to `TimeData`
- Refactored `parseReqs` into a new module `Models.Requirement` and updated its input type from `String` to `Text`
- Added a test case for the getGraphJSON function in `Controllers/Graph`
- Migrated JS package manager from yarn to pnpm
- Updated `react-leaflet` to v5.0.0 and `@eslint/compat` to v2.1.0
- Added peer dependency overrides for `eslint-plugin-react` (for `eslint` v10) and `@babel/plugin-syntax-*` (for `@babel/core` v8.0.1
- Added peer dependency overrides for `eslint-plugin-react` (for `eslint` v10) and `@babel/plugin-syntax-*` (for `@babel/core` v8.0.1)
- Set `NODE_ENV=production` for webpack `build` command
- Fixed dynamic graph centering bug by updating `parseTransform` in `app/Svg/Parser.hs` to parse multiple transform functions and removing `getShapesMinXY` in `js/components/graph/Graph.js`
- Switched CI provider from CircleCI to GitHub Actions
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,29 @@
import React from "react"
import { useState } from "react"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { faDownload } from "@fortawesome/free-solid-svg-icons"
import { Tooltip } from "react-tooltip"
import GraphDropdown from "../graph/GraphDropdown"
import { Graph } from "../graph/types"

interface NavBarProps {
selected_page: string
open_modal?: () => void
graphs?: Graph[]
updateGraph?: (graphName: string) => void
}
/**
* NavBar component.
*/
export function NavBar({ selected_page, open_modal, graphs = [], updateGraph }) {
const isActive = page => (page === selected_page ? "selected-page" : undefined)
const [showGraphDropdown, setShowGraphDropdown] = React.useState(false)
const [dropdownTimeouts, setDropdownTimeouts] = React.useState([])
export function NavBar({
selected_page,
open_modal,
graphs = [],
updateGraph,
}: NavBarProps) {
const isActive = (page: string) =>
page === selected_page ? "selected-page" : undefined
const [showGraphDropdown, setShowGraphDropdown] = useState(false)
const [dropdownTimeouts, setDropdownTimeouts] = useState<number[]>([])

const clearDropdownTimeouts = () => {
dropdownTimeouts.forEach(timeout => clearTimeout(timeout))
Expand Down Expand Up @@ -56,7 +69,7 @@ export function NavBar({ selected_page, open_modal, graphs = [], updateGraph })
{selected_page === "graph" && (
<GraphDropdown
showGraphDropdown={showGraphDropdown}
onMouseMove={handleShowGraphDropdown}
onMouseEnter={handleShowGraphDropdown}
onMouseLeave={handleHideGraphDropdown}
graphs={graphs}
updateGraph={updateGraph}
Expand Down Expand Up @@ -88,12 +101,7 @@ export function NavBar({ selected_page, open_modal, graphs = [], updateGraph })
>
<FontAwesomeIcon icon={faDownload} />
</button>
<Tooltip
id="Export"
className="export-tooltip"
place="left"
variant="float"
/>
<Tooltip id="Export" className="export-tooltip" place="left" float />
</>
)}
</div>
Expand Down
2 changes: 1 addition & 1 deletion js/components/common/__tests__/NavBar.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react"
import { render, screen, cleanup } from "@testing-library/react"
import { NavBar } from "../NavBar.js.jsx"
import { NavBar } from "../NavBar"
import userEvent from "@testing-library/user-event"

describe("test that navbar logo and items render correctly", () => {
Expand Down
2 changes: 1 addition & 1 deletion js/components/generate/GenerateForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { faWandSparkles } from "@fortawesome/free-solid-svg-icons"
import { Tooltip } from "react-tooltip"
import { Graph, populateHybridRelatives } from "../graph/Graph"
import Disclaimer from "../common/Disclaimer"
import { NavBar } from "../common/NavBar.js.jsx"
import { NavBar } from "../common/NavBar"
import AutocompleteDropdown from "./AutocompleteDropdown"

export default class GenerateForm extends React.Component {
Expand Down
2 changes: 1 addition & 1 deletion js/components/graph/Container.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import PropTypes from "prop-types"
import Disclaimer from "../common/Disclaimer"
import { Graph } from "./Graph"
import FocusBar from "./FocusBar"
import { NavBar } from "../common/NavBar.js.jsx"
import { NavBar } from "../common/NavBar"
import { ExportModal } from "../common/export"
import GraphFallback from "./GraphFallback"
import { ErrorBoundary } from "react-error-boundary"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import React from "react"
import PropTypes from "prop-types"
import { useState } from "react"
import FocusTab from "./FocusTab"

interface FocusBarProps {
focusBarEnabled: boolean
highlightFocus: (id: string) => void
currFocus: string | null
}

// These lists are in reverse order to what ends up appearing on the screen
const computerScienceFocusLabels = [
["ASFOC1689J", "Web Technologies"],
Expand All @@ -18,8 +23,12 @@ const computerScienceFocusLabels = [
/**
* React component representing the focus menu bar
*/
export default function FocusBar({ focusBarEnabled, highlightFocus, currFocus }) {
const [open, setOpen] = React.useState(false)
export default function FocusBar({
focusBarEnabled,
highlightFocus,
currFocus,
}: FocusBarProps) {
const [open, setOpen] = useState(false)

/**
* Changes whether the focus bar is open or not
Expand Down Expand Up @@ -61,9 +70,3 @@ export default function FocusBar({ focusBarEnabled, highlightFocus, currFocus })
</div>
)
}

FocusBar.propTypes = {
focusBarEnabled: PropTypes.bool,
highlightFocus: PropTypes.func,
currFocus: PropTypes.string,
}
8 changes: 3 additions & 5 deletions js/components/graph/GraphDropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
interface Graph {
title: string
}
import { Graph } from "./types"

interface GraphDropdownProps {
showGraphDropdown?: boolean
onMouseEnter?: () => void
onMouseLeave?: () => void
graphs?: Graph[]
updateGraph: (title: string) => void
updateGraph?: (graphName: string) => void
}

export default function GraphDropdown({
Expand All @@ -32,7 +30,7 @@ export default function GraphDropdown({
<li
key={i}
className="graph-dropdown-item"
onClick={() => updateGraph(graph.title)}
onClick={() => updateGraph?.(graph.title)}
data-testid={"test-graph-" + i}
>
{graph.title}
Expand Down
61 changes: 31 additions & 30 deletions js/components/graph/Sidebar.js → js/components/graph/Sidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
import React from "react"
import PropTypes from "prop-types"
import { useState } from "react"
import Button from "./Button"

type Course = [courseId: string, courseLabel: string]

interface SidebarProps {
fceCount: number
reset?: () => void
activeCourses: Set<string>
courses: Course[]
courseClick?: (courseId: string | null) => void
xClick?: (courseId: string | null) => void
sidebarItemClick?: () => void
onHover?: () => void
onMouseLeave?: () => void
}

export default function Sidebar({
fceCount,
reset,
Expand All @@ -12,15 +25,15 @@ export default function Sidebar({
sidebarItemClick,
onHover,
onMouseLeave,
}) {
const [collapsed, setCollapsed] = React.useState(true)
const [results, setResults] = React.useState([])
}: SidebarProps): React.JSX.Element {
const [collapsed, setCollapsed] = useState(true)
const [results, setResults] = useState<Course[] | undefined>([])

const toggleSidebar = () => {
const toggleSidebar = (): void => {
setCollapsed(!collapsed)
}

const filteredSearch = query => {
const filteredSearch = (query: string): Course[] | undefined => {
if (!query || !courses) {
return
}
Expand All @@ -41,9 +54,9 @@ export default function Sidebar({
* If an invalid course label is supplied, `null` will be returned.
* e.g. "CSC263/265" will resolve to "csc263265"
* "CSC999" will resolve to `null`
* @return {string} course node id
* @return course node id
*/
const courseIdFromLabel = courseLabel => {
const courseIdFromLabel = (courseLabel: string): string | null => {
for (let i = 0; i < courses.length; i++) {
if (courses[i][1] === courseLabel) {
return courses[i][0]
Expand All @@ -55,9 +68,9 @@ export default function Sidebar({
// Sidebar rendering methods
/**
* Render the FCE counter above the sidebar on the left side.
* @return {HTMLDivElement} FCE to the DOM
* @return FCE to the DOM
*/
const renderFCE = () => {
const renderFCE = (): React.JSX.Element => {
const fceString = Number.isInteger(fceCount) ? fceCount + ".0" : fceCount

return (
Expand All @@ -69,9 +82,9 @@ export default function Sidebar({

/**
* Render the dropdown results within the sidebar dropdown.
* @return {HTMLDivElement} Searchbar to the DOM
* @return Searchbar to the DOM
*/
const renderDropdown = () => {
const renderDropdown = (): React.JSX.Element | undefined => {
if (courses) {
const showDropdown = results ? "" : "hidden"
const masterDropdown = `${showDropdown} search-dropdown`
Expand All @@ -97,9 +110,9 @@ export default function Sidebar({

/**
* Render courses that are in the sidebar.
* @return {HTMLBodyElement} list of div's for each course that is active
* @return list of div's for each course that is active
*/
const renderActiveCourses = () => {
const renderActiveCourses = (): React.JSX.Element => {
const temp = activeCourses ? [...activeCourses] : []
// sort the list of rendered courses, alphabetically
temp.sort((a, b) => a.localeCompare(b))
Expand All @@ -111,14 +124,14 @@ export default function Sidebar({
key={`active ${course}`}
data-testid={`test ${course}`}
onClick={() => {
courseClick(courseIdFromLabel(course))
courseClick?.(courseIdFromLabel(course))
}}
className="course-selection"
onMouseEnter={onHover}
onMouseLeave={onMouseLeave}
>
{course}
<Button text="X" mouseDown={() => xClick(courseIdFromLabel(course))} />
<Button text="X" mouseDown={() => xClick?.(courseIdFromLabel(course))} />
</div>
)
})}
Expand Down Expand Up @@ -158,7 +171,7 @@ export default function Sidebar({
<button
className="reset-selections"
data-testid="test-reset"
onClick={() => reset()}
onClick={() => reset?.()}
>
Reset Selections
</button>
Expand All @@ -173,15 +186,3 @@ export default function Sidebar({
</div>
)
}

Sidebar.propTypes = {
fceCount: PropTypes.number,
reset: PropTypes.func,
activeCourses: PropTypes.instanceOf(Set),
courses: PropTypes.array,
courseClick: PropTypes.func,
xClick: PropTypes.func,
sidebarItemClick: PropTypes.func,
onHover: PropTypes.func,
onMouseLeave: PropTypes.func,
}
5 changes: 5 additions & 0 deletions js/components/graph/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/** Basic metadata for a course graph option. */
export interface Graph {
title: string
}

/** A single line of text rendered inside a node/bool shape. */
export interface GraphTextTag {
pos: [number, number]
Expand Down
2 changes: 1 addition & 1 deletion js/components/grid/grid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
ModuleRegistry,
provideGlobalGridOptions,
} from "ag-grid-community"
import { NavBar } from "../common/NavBar.js.jsx"
import { NavBar } from "../common/NavBar"

// Register all community features
ModuleRegistry.registerModules([AllCommunityModule])
Expand Down
Loading