From bcae60190a0153b2d8ba365c4d0ad8e3f44abdf9 Mon Sep 17 00:00:00 2001 From: Remco Tukker <remco.tukker@geant.org> Date: Fri, 21 Apr 2023 11:18:26 +0200 Subject: [PATCH] the filter component now returns two styled dropdown boxes instead of a long list of checkboxes --- webapp/src/components/graphing/Filter.tsx | 88 +++++++++++++++-------- webapp/src/scss/layout/_components.scss | 32 ++++++++- 2 files changed, 88 insertions(+), 32 deletions(-) diff --git a/webapp/src/components/graphing/Filter.tsx b/webapp/src/components/graphing/Filter.tsx index 3391b9f7..3440c0e5 100644 --- a/webapp/src/components/graphing/Filter.tsx +++ b/webapp/src/components/graphing/Filter.tsx @@ -1,14 +1,15 @@ import React, {ReactElement} from 'react'; -import {Button, Row} from 'react-bootstrap'; +import {Button, Dropdown, ButtonToolbar} from 'react-bootstrap'; import {FilterSelection} from "../../Schema"; interface inputProps { filterOptions: { availableNrens: string[], availableYears: number[] } filterSelection: FilterSelection setFilterSelection: React.Dispatch<React.SetStateAction<FilterSelection>> + max1year?: boolean } -function Filter({ filterOptions, filterSelection, setFilterSelection }: inputProps): ReactElement { +function Filter({ filterOptions, filterSelection, setFilterSelection, max1year = false }: inputProps): ReactElement { const handleNrenClick = (nren: string) => { if (filterSelection.selectedNrens.includes(nren)) { @@ -32,7 +33,7 @@ function Filter({ filterOptions, filterSelection, setFilterSelection }: inputPro }); } else { setFilterSelection({ - selectedYears: [...filterSelection.selectedYears, year], + selectedYears: max1year ? [year] : [...filterSelection.selectedYears, year], selectedNrens: [...filterSelection.selectedNrens] }); } @@ -52,37 +53,62 @@ function Filter({ filterOptions, filterSelection, setFilterSelection }: inputPro }); } + // flex wrap in the column direction causes issues so we prepare the columns ourselves: + const nrOfColumns = 2; + const nrOfRows = Math.ceil(filterOptions.availableNrens.length / nrOfColumns); + const grid: string[][] = Array.from(Array(nrOfColumns), () => []); + filterOptions.availableNrens.sort().forEach((nren, idx) => { + const col = Math.floor(idx / nrOfRows); + grid[col].push(nren); + }); + return ( - <> - <Row> - {filterOptions.availableYears.sort().map((year) => ( - <div key={year} onClick={() => (handleYearClick(year))}> - <input - type="checkbox" - checked={filterSelection.selectedYears.includes(year)} - readOnly - /> - {year} + <ButtonToolbar className="d-flex justify-content-end gap-2 m-2"> + + <Dropdown autoClose="outside"> + <Dropdown.Toggle id="nren-dropdown-toggle" variant="compendium">Select NRENs</Dropdown.Toggle> + <Dropdown.Menu> + <div className="d-flex fit-max-content"> + {grid.map((column, columnIndex) => ( + <div key={columnIndex} className="flex-fill"> + {column.map((nren) => ( + <div className="filter-dropdown-item flex-fill" key={nren} onClick={() => (handleNrenClick(nren))}> + <input + type="checkbox" + checked={filterSelection.selectedNrens.includes(nren)} + readOnly + /> {nren} + </div> + ))} + </div> + ))} </div> - ))} - </Row> - <Row> - {filterOptions.availableNrens.sort().map((nren) => ( - <div key={nren} onClick={() => (handleNrenClick(nren))}> - <input - type="checkbox" - checked={filterSelection.selectedNrens.includes(nren)} - readOnly - /> - {nren} + <div className="d-flex fit-max-content gap-2 mx-2 mt-3"> + <Button variant="compendium" className="flex-fill" onClick={handleSelectAllNrensClick}>Select all NRENs</Button> + <Button variant="compendium" className="flex-fill" onClick={handleDeselectAllNrensClick}>Unselect all NRENs</Button> </div> - ))} - </Row> - <Row> - <Button onClick={handleSelectAllNrensClick}>Select all NRENs</Button> - <Button onClick={handleDeselectAllNrensClick}>Deselect all NRENs</Button> - </Row> - </> + </Dropdown.Menu> + </Dropdown> + + { filterOptions.availableYears.length > 0 && + <Dropdown autoClose="outside"> + <Dropdown.Toggle id="year-dropdown-toggle" variant="compendium">Select years</Dropdown.Toggle> + <Dropdown.Menu> + {filterOptions.availableYears.sort().map((year) => ( + <div className="filter-dropdown-item" key={year} onClick={() => (handleYearClick(year))}> + <input + type="checkbox" + checked={filterSelection.selectedYears.includes(year)} + readOnly + /> {year} + </div> + ))} + </Dropdown.Menu> + </Dropdown> + } + + </ButtonToolbar> + ); } diff --git a/webapp/src/scss/layout/_components.scss b/webapp/src/scss/layout/_components.scss index 607885d9..58a20fb6 100644 --- a/webapp/src/scss/layout/_components.scss +++ b/webapp/src/scss/layout/_components.scss @@ -113,4 +113,34 @@ align-items: center; padding-top: 20px; background-color: #3b536b; -} \ No newline at end of file +} + +.filter-dropdown-item { + padding-left: 1rem; + cursor: pointer; +} + +.filter-dropdown-item:hover { + background-color: var(--bs-dropdown-link-hover-bg); +} + +.btn-compendium { + --bs-btn-color:#fff; + --bs-btn-bg:#003753; + --bs-btn-border-color:#003753; + --bs-btn-hover-color:#fff; + --bs-btn-hover-bg:#3b536b; + --bs-btn-hover-border-color:#3b536b; + --bs-btn-focus-shadow-rgb:49,132,253; + --bs-btn-active-color:#f5f5f5; + --bs-btn-active-bg:#3b536b; + --bs-btn-active-border-color:#003753; + --bs-btn-active-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125); + --bs-btn-disabled-color:#fff; + --bs-btn-disabled-bg:#0d6efd; + --bs-btn-disabled-border-color:#0d6efd +} + +.fit-max-content { + min-width: max-content; +} -- GitLab