Skip to content

Commit

Permalink
Collapsing side bar (#638)
Browse files Browse the repository at this point in the history
* Collapsing side bar

* update SideBar test to expect svg in first button

* sidebar: inline setState logic, edit test comment

* sidebar: simplify tnoodle icon markup
  • Loading branch information
JonEsparaz committed Dec 24, 2020
1 parent af0b9c1 commit b16eed4
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 59 deletions.
16 changes: 14 additions & 2 deletions tnoodle-ui/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,18 @@ nav li {
padding-top: 10px;
}

#side-bar {
height: 100vh;
@media (min-width: 992px) {
#side-bar {
height: 100vh;
position: sticky;
top: 0;
z-index: 1020;
}
}

@media (max-width: 991.98px) {
#title {
margin-bottom: 0;
margin-left: 12px;
}
}
4 changes: 2 additions & 2 deletions tnoodle-ui/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ class App extends Component {
<div className="App container-fluid">
<div className="row">
<div
className="col-3 bg-dark sticky-top overflow-auto"
className="col-lg-3 bg-dark overflow-auto"
id="side-bar"
>
<SideBar />
</div>
<div className="col-9 m-0 p-0">
<div className="col-lg-9 m-0 p-0">
<Main />
</div>
</div>
Expand Down
152 changes: 100 additions & 52 deletions tnoodle-ui/src/main/components/SideBar.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { Component } from "react";
import { connect } from "react-redux";
import Loading from "./Loading";
import { Collapse } from "react-bootstrap";
import {
updateWcif,
updateEditingStatus,
Expand Down Expand Up @@ -67,6 +68,7 @@ const SideBar = connect(
loadingCompetitions: false,
loadingCompetitionInformation: false,
competitionId: null,
isOpen: true,
};
}
margin = 1; // Margin for login button and "Manual Selection"
Expand Down Expand Up @@ -107,8 +109,19 @@ const SideBar = connect(
if (competitionId != null) {
this.handleCompetitionSelection(competitionId);
}

this.setIsOpen();
window.addEventListener("resize", this.setIsOpen);
}

componentWillUnmount() {
window.removeEventListener("resize", this.setIsOpen);
}

setIsOpen = () => {
this.setState({ isOpen: window.innerWidth > 992 });
};

setLoadingUser = (flag) => {
this.setState({ ...this.state, loadingUser: flag });
};
Expand Down Expand Up @@ -337,59 +350,94 @@ const SideBar = connect(

render() {
return (
<div className="h-100">
<img
className="tnoodle-logo mt-2"
src={require("../assets/tnoodle_logo.svg")}
alt="TNoodle logo"
/>
<h1 className="display-3" id="title">
TNoodle
</h1>
<div>
<ul className="list-group">
<li>
{(this.state.competitions != null &&
this.state.competitions.length) > 0 && (
<button
type="button"
className={`btn btn-primary btn-lg btn-block btn-outline-light mb-${this.margin}`}
onClick={this.handleManualSelection}
disabled={
this.props.generatingScrambles
}
>
Manual Selection
</button>
)}
</li>
{this.state.competitions != null &&
this.state.competitions.map(
(competition, i) => (
<li key={i}>
<button
type="button"
className="btn btn-primary btn-lg btn-block m-1"
disabled={
this.props
.generatingScrambles
}
onClick={(_) =>
this.handleCompetitionSelection(
competition.id
)
}
>
{competition.name}
</button>
</li>
)
)}
</ul>

{this.loadingArea()}
<div className="h-100 pb-2">
<div className="d-flex flex-lg-column align-items-center overflow-hidden">
<img
className="tnoodle-logo mt-2"
src={require("../assets/tnoodle_logo.svg")}
alt="TNoodle logo"
/>
<h1 className="display-3" id="title">
TNoodle
</h1>
<button
type="button"
className="btn btn-primary btn-lg btn-outline-light ml-auto d-lg-none"
onClick={() =>
this.setState({ isOpen: !this.state.isOpen })
}
disabled={this.props.generatingScrambles}
aria-label="Toggle menu"
aria-expanded={this.state.isOpen}
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 30 30"
width={30}
height={30}
>
<path
stroke="currentColor"
strokeWidth={2}
strokeLinecap="round"
strokeMiterlimit={10}
d="M4 7h22M4 15h22M4 23h22"
/>
</svg>
</button>
</div>
{this.logInButton()}
<Collapse in={this.state.isOpen}>
<div className="pt-2">
<div>
<ul className="list-group">
<li>
{this.state.competitions != null &&
this.state.competitions.length >
0 && (
<button
type="button"
className={`btn btn-primary btn-lg btn-block btn-outline-light mb-${this.margin}`}
onClick={
this
.handleManualSelection
}
disabled={
this.props
.generatingScrambles
}
>
Manual Selection
</button>
)}
</li>
{this.state.competitions != null &&
this.state.competitions.map(
(competition, i) => (
<li key={i}>
<button
type="button"
className="btn btn-primary btn-lg btn-block m-1"
disabled={
this.props
.generatingScrambles
}
onClick={(_) =>
this.handleCompetitionSelection(
competition.id
)
}
>
{competition.name}
</button>
</li>
)
)}
</ul>
{this.loadingArea()}
</div>
{this.logInButton()}
</div>
</Collapse>
</div>
);
}
Expand Down
11 changes: 8 additions & 3 deletions tnoodle-ui/src/test/SideBar.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,20 @@ it("Each competition fetched from the website must become a button", async () =>

const buttons = Array.from(container.querySelectorAll("button"));

// First button should be manual selection
expect(buttons[0].innerHTML).toBe("Manual Selection");
// First button should be the collapse button
expect(buttons[0].innerHTML).toBe(
`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30" width="30" height="30"><path stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-miterlimit="10" d="M4 7h22M4 15h22M4 23h22"></path></svg>`
);

// Second button should be manual selection
expect(buttons[1].innerHTML).toBe("Manual Selection");

// Last button should be Log Out
expect(buttons[buttons.length - 1].innerHTML).toBe("Log Out");

// Each competition must have a button
for (let i = 0; i < competitions.length; i++) {
expect(competitions[i].name).toBe(buttons[i + 1].innerHTML);
expect(competitions[i].name).toBe(buttons[i + 2].innerHTML);
}

// We should welcome the user
Expand Down

0 comments on commit b16eed4

Please sign in to comment.