From a53f2c4087f354c8293fab64fcee5d1b00997755 Mon Sep 17 00:00:00 2001 From: Wilson Chua <wwc4618@ic.ac.uk> Date: Sat, 22 Aug 2020 00:27:10 +0800 Subject: [PATCH] ModuleResources List view: Convert section download button to select section checkbox --- src/assets/scss/global.scss | 48 +++++++++++++++++ .../molecules/CategoryHeader/index.tsx | 34 ++++++------ .../CategoryHeader/style.module.scss | 48 +---------------- .../molecules/CategoryList/index.tsx | 6 +-- .../SectionHeader/style.module.scss | 52 +------------------ .../molecules/SelectionView/index.tsx | 2 + .../ModuleResources/components/ListView.tsx | 28 ++++++++-- 7 files changed, 98 insertions(+), 120 deletions(-) diff --git a/src/assets/scss/global.scss b/src/assets/scss/global.scss index 2f9b6ca2b..575583219 100644 --- a/src/assets/scss/global.scss +++ b/src/assets/scss/global.scss @@ -20,4 +20,52 @@ $teal-tag-background: transparentize($teal-100, 0.5); .tagTeal { color: $teal-700; background: $teal-tag-background; +} + +// Section header with checkbox settings +.sectionHeaderContainer { + display: flex; + justify-content: space-between; + margin-top: 1.875rem; + align-items: center; +} + +.sectionHeader { + font-weight: 500; + font-size: 20px; + text-transform: uppercase; +} + +.sectionHeaderButton { + background-color: $white; + color: $gray-500; + border-width: 0px; + border-radius: 8px; + margin-left: 20px; + justify-content: space-between; + height: 2.25rem; + transition: 0.2s background-color; + -webkit-transition: 0.2s background-color; + -moz-transition: 0.2s background-color; + font-size: 1.05rem; +} + +.buttonIcon { + margin-top: 0.22rem; +} + +.sectionHeaderButton:global(.active), +.sectionHeaderButton:active { + background: $gray-400 !important; + font-weight: 500; + text-align: left; + border-width: 0rem; + height: 2.25rem; + line-height: 1.375rem; +} + +.sectionHeaderButton:hover, .sectionHeaderButton:focus { + background-color: $gray-200; + color: $gray-700 !important; + box-shadow: none !important; } \ No newline at end of file diff --git a/src/components/molecules/CategoryHeader/index.tsx b/src/components/molecules/CategoryHeader/index.tsx index 25082f656..8aa7ac14d 100644 --- a/src/components/molecules/CategoryHeader/index.tsx +++ b/src/components/molecules/CategoryHeader/index.tsx @@ -3,16 +3,20 @@ import styles from "./style.module.scss"; import Button from "react-bootstrap/Button"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { faDownload } from "@fortawesome/free-solid-svg-icons"; +import { IconDefinition } from "@fortawesome/free-solid-svg-icons"; export interface CategoryHeaderProps { heading: string; - onDownloadClick: (event: React.MouseEvent) => void; + onSelectAllClick: (event: React.MouseEvent) => void; + selectAllIcon: IconDefinition; + checkBoxColor: string; } const CategoryHeader: React.FC<CategoryHeaderProps> = ({ heading, - onDownloadClick, + onSelectAllClick, + selectAllIcon, + checkBoxColor }: CategoryHeaderProps) => { return ( <> @@ -21,19 +25,17 @@ const CategoryHeader: React.FC<CategoryHeaderProps> = ({ {heading} </span> <div className={styles.sectionHeaderButtonGroup}> - <span id="download-button"> - <Button - variant="secondary" - className={styles.sectionHeaderButton} - onClick={onDownloadClick} - > - <FontAwesomeIcon - className={styles.buttonIcon} - icon={faDownload} - /> - Download Section - </Button> - </span> + <Button + style={{ color: checkBoxColor }} + className={styles.sectionHeaderButton} + onClick={onSelectAllClick} + variant="secondary" + > + <FontAwesomeIcon + className={styles.buttonIcon} + icon={selectAllIcon} + /> + </Button> </div> </div> </> diff --git a/src/components/molecules/CategoryHeader/style.module.scss b/src/components/molecules/CategoryHeader/style.module.scss index 359988885..e2a1338b5 100644 --- a/src/components/molecules/CategoryHeader/style.module.scss +++ b/src/components/molecules/CategoryHeader/style.module.scss @@ -1,48 +1,2 @@ @import "assets/scss/custom"; - -.sectionHeaderContainer { - display: flex; - justify-content: space-between; - margin-top: 1.875rem; - align-items: center; -} - -.sectionHeader { - font-size: 20px; - text-transform: uppercase; -} - -.sectionHeaderButton { - background-color: $white; - color: $gray-500; - border-width: 0px; - border-radius: 8px; - margin-left: 20px; - justify-content: space-between; - height: 2.25rem; - transition: 0.2s background-color; - -webkit-transition: 0.2s background-color; - -moz-transition: 0.2s background-color; - font-size: 1.05rem; -} - -.buttonIcon { - margin-top: 0.22rem; - margin-right: 0.22rem; -} - -.sectionHeaderButton:global(.active), -.sectionHeaderButton:active { - background: $gray-400 !important; - font-weight: 500; - text-align: left; - border-width: 0rem; - height: 2.25rem; - line-height: 1.375rem; -} - -.sectionHeaderButton:hover, .sectionHeaderButton:focus { - background-color: $gray-200; - color: $gray-700 !important; - box-shadow: none !important; -} +@import "assets/scss/global"; diff --git a/src/components/molecules/CategoryList/index.tsx b/src/components/molecules/CategoryList/index.tsx index f74bd0675..7d431b8ff 100644 --- a/src/components/molecules/CategoryList/index.tsx +++ b/src/components/molecules/CategoryList/index.tsx @@ -43,7 +43,7 @@ const CategoryList: React.FC<{ select: SelectionProps }> = ({ return ( <Row - style={{ marginTop: "10px", marginLeft: "-10px", marginRight: "-10px", cursor: "pointer" }} + style={{ marginTop: "10px", marginLeft: "0px", marginRight: "0px", cursor: "pointer" }} onClick={() => select.handleCardClick(id)} onMouseOver={() => select.handleMouseOver(id)} onMouseOut={() => select.handleMouseOut(id)} @@ -62,9 +62,9 @@ const CategoryList: React.FC<{ select: SelectionProps }> = ({ </Badge> ))} </Col> - <Col md="auto"> + <Col md="auto" className="px-0"> <FontAwesomeIcon - style={{ fontSize: "1.125rem" }} + style={{ fontSize: "1.125rem", marginRight: "0.5rem" }} icon={icon} onClick={(e) => { e.stopPropagation(); diff --git a/src/components/molecules/SelectionView/components/SectionHeader/style.module.scss b/src/components/molecules/SelectionView/components/SectionHeader/style.module.scss index c74607afb..9fee92a78 100644 --- a/src/components/molecules/SelectionView/components/SectionHeader/style.module.scss +++ b/src/components/molecules/SelectionView/components/SectionHeader/style.module.scss @@ -1,55 +1,5 @@ @import "assets/scss/custom"; - -.sectionHeaderContainer { - display: flex; - justify-content: space-between; - margin-top: 1.875rem; - align-items: center; -} - -.sectionHeader { - font-weight: 500; - font-size: 20px; - cursor: pointer; -} - -.sectionHeaderButton { - background-color: $white; - color: $gray-500; - border-width: 0px; - border-radius: 8px; - margin-left: 20px; - justify-content: space-between; - height: 2.25rem; - transition: 0.2s background-color; - -webkit-transition: 0.2s background-color; - -moz-transition: 0.2s background-color; - font-size: 1.05rem; -} - -.buttonIcon { - margin-top: 0.22rem; -} - -.buttonCheckbox :global(.form-check-input) { - margin: 0px; -} - -.sectionHeaderButton:global(.active), -.sectionHeaderButton:active { - background: $gray-400 !important; - font-weight: 500; - text-align: left; - border-width: 0rem; - height: 2.25rem; - line-height: 1.375rem; -} - -.sectionHeaderButton:hover, .sectionHeaderButton:focus { - background-color: $gray-200; - color: $gray-700 !important; - box-shadow: none !important; -} +@import "assets/scss/global"; .alert-enter { opacity: 0; diff --git a/src/components/molecules/SelectionView/index.tsx b/src/components/molecules/SelectionView/index.tsx index ffdda456e..b920facb1 100644 --- a/src/components/molecules/SelectionView/index.tsx +++ b/src/components/molecules/SelectionView/index.tsx @@ -15,6 +15,7 @@ type idBooleanMap = { [key: number]: boolean }; export interface SelectionProps { selectionItems: SelectionItem[]; state: MyState; + setIsSelected: (selection: idBooleanMap) => void; isAnySelected: () => boolean; handleCardClick: (id: number) => void; handleIconClick: (id: number) => void; @@ -126,6 +127,7 @@ class SelectionView extends React.Component<MyProps, MyState> { let selection: SelectionProps = { selectionItems: this.props.selectionItems, state: this.state, + setIsSelected: (selection) => this.setState({ isSelected: selection }), isAnySelected: () => this.isAnySelected(), handleCardClick: (id: number) => this.handleCardClick(id), handleIconClick: (id: number) => this.handleIconClick(id), diff --git a/src/components/pages/ModuleResources/components/ListView.tsx b/src/components/pages/ModuleResources/components/ListView.tsx index 34e2db1b5..8ac1e2167 100644 --- a/src/components/pages/ModuleResources/components/ListView.tsx +++ b/src/components/pages/ModuleResources/components/ListView.tsx @@ -5,6 +5,7 @@ import SelectionView, { } from "components/molecules/SelectionView"; import CategoryList from "components/molecules/CategoryList"; import CategoryHeader from "components/molecules/CategoryHeader"; +import { faSquare, faCheckSquare } from "@fortawesome/free-regular-svg-icons"; export interface ListViewProps { folders: Folder[]; @@ -20,8 +21,7 @@ const ListView: React.FC<ListViewProps> = ({ folders, resources, searchText, - onDownloadClick, - onSectionDownloadClick, + onDownloadClick, onItemClick, includeInSearchResult }) => { @@ -44,14 +44,36 @@ const ListView: React.FC<ListViewProps> = ({ let categorySelect : SelectionProps = { selectionItems: select.selectionItems.filter(res => res.folder === title), state: select.state, + setIsSelected: select.setIsSelected, isAnySelected: select.isAnySelected, handleCardClick: select.handleCardClick, handleIconClick: select.handleIconClick, handleMouseOver: select.handleMouseOver, handleMouseOut: select.handleMouseOut } + + function isAllSelected() : boolean { + let isSelected = categorySelect.state.isSelected; + return categorySelect.selectionItems.every(item => isSelected[item.id]); + } + + function onSelectAllClick() { + let setValue = !isAllSelected(); + let isSelected = JSON.parse(JSON.stringify(select.state.isSelected)); + let items = categorySelect.selectionItems; + for (let item in items) { + isSelected[items[item].id] = setValue; + } + select.setIsSelected(isSelected); + } + return (<> - <CategoryHeader heading={title} onDownloadClick={() => onSectionDownloadClick(title)}/> + <CategoryHeader + heading={title} + onSelectAllClick={onSelectAllClick} + selectAllIcon={isAllSelected() ? faCheckSquare : faSquare} + checkBoxColor={select.isAnySelected() ? "#495057" : "#e9ecef"} + /> <CategoryList select={categorySelect} /> </>) })} -- GitLab