From 8b7393023323b6c52aae0264af98ff3a9db1380d Mon Sep 17 00:00:00 2001
From: danieldeng2 <danieldeng223@gmail.com>
Date: Wed, 12 Aug 2020 00:35:13 +0100
Subject: [PATCH] Add select all logic to both quick access and folders

---
 .../src/components/atoms/FileCard/index.tsx   |  14 +-
 .../atoms/FileCard/style.module.scss          |   6 +-
 .../atoms/FolderCard/style.module.scss        |   6 +-
 .../molecules/QuickAccess/index.tsx           | 143 ++++++++++++++----
 .../molecules/ResourceFolders/index.tsx       |  26 +++-
 .../molecules/ResourceSectionHeader/index.tsx |  40 +++--
 6 files changed, 172 insertions(+), 63 deletions(-)

diff --git a/frontend/src/components/atoms/FileCard/index.tsx b/frontend/src/components/atoms/FileCard/index.tsx
index 8eb6924f3..1835a9930 100644
--- a/frontend/src/components/atoms/FileCard/index.tsx
+++ b/frontend/src/components/atoms/FileCard/index.tsx
@@ -7,27 +7,29 @@ import graphIllustration from "assets/images/graph-illustration.svg";
 import Badge from "react-bootstrap/Badge";
 import Card from "react-bootstrap/Card";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { faFile } from "@fortawesome/free-solid-svg-icons";
+import { IconDefinition } from "@fortawesome/free-solid-svg-icons";
 
 export interface FileCardProps {
   title: string;
   type: string;
-  tags: string[];
-  id: number;
+	tags: string[];
+	icon: IconDefinition;
+	onIconClick: (event: React.MouseEvent) => void;
 }
 
 const FileCard: React.FC<FileCardProps> = ({
   title,
   type,
-  tags,
-  id,
+	tags,
+	icon,
+	onIconClick,
 }: FileCardProps) => {
   return (
     <Card className={styles.quickViewCard}>
       <Card.Img variant="top" src={graphIllustration} />
       <Card.Body>
         <Card.Title>{title}</Card.Title>
-        <FontAwesomeIcon style={{ fontSize: "1.125rem" }} icon={faFile} />
+        <FontAwesomeIcon style={{ fontSize: "1.125rem" }} icon={icon} onClick={onIconClick}/>
       </Card.Body>
       <Card.Footer>
 				{
diff --git a/frontend/src/components/atoms/FileCard/style.module.scss b/frontend/src/components/atoms/FileCard/style.module.scss
index 4c3395e6c..dc20d13cf 100644
--- a/frontend/src/components/atoms/FileCard/style.module.scss
+++ b/frontend/src/components/atoms/FileCard/style.module.scss
@@ -8,9 +8,9 @@
   margin-bottom: 10px;
 }
 
-.quickViewCard:hover {
-  transform: scale(1.03);
-}
+// .quickViewCard:hover {
+//   transform: scale(1.03);
+// }
 
 .quickViewCard :global(.card-body) {
   padding: 0.5rem;
diff --git a/frontend/src/components/atoms/FolderCard/style.module.scss b/frontend/src/components/atoms/FolderCard/style.module.scss
index 7b3d07224..eb6316295 100644
--- a/frontend/src/components/atoms/FolderCard/style.module.scss
+++ b/frontend/src/components/atoms/FolderCard/style.module.scss
@@ -6,9 +6,9 @@
   margin-top: 0.67rem;
 }
 
-.folderCard:hover {
-  transform: scale(1.03);
-}
+// .folderCard:hover {
+//   transform: scale(1.03);
+// }
 
 .folderCard :global(.card-body) {
   display: flex;
diff --git a/frontend/src/components/molecules/QuickAccess/index.tsx b/frontend/src/components/molecules/QuickAccess/index.tsx
index f0739ff84..23900dba5 100644
--- a/frontend/src/components/molecules/QuickAccess/index.tsx
+++ b/frontend/src/components/molecules/QuickAccess/index.tsx
@@ -6,6 +6,9 @@ import Row from "react-bootstrap/esm/Row";
 import Col from "react-bootstrap/esm/Col";
 import ResourceSectionHeader from "../ResourceSectionHeader";
 import FileCard from "components/atoms/FileCard";
+import { faSquare, faCheckSquare } from "@fortawesome/free-regular-svg-icons";
+import { faFile } from "@fortawesome/free-solid-svg-icons";
+
 export interface QuickAccessProps {
   quickAccessItems: {
     title: string;
@@ -15,37 +18,113 @@ export interface QuickAccessProps {
   }[];
 }
 
-const QuickAccess: React.FC<QuickAccessProps> = ({
-  quickAccessItems,
-}: QuickAccessProps) => {
-  return (
-    <>
-      <ResourceSectionHeader heading="Quick Access" />
-
-      <Row
-        className={classNames(
-          "d-flex",
-          "flex-row",
-          "flex-nowrap",
-          styles.quickAccessRow
-        )}
-      >
-        {quickAccessItems.map(({ title, type, tags, id }) => (
-          <Col
-            xs={7}
-            sm={5}
-            md={5}
-            lg={4}
-            xl={3}
-            key={id}
-            style={{ marginBottom: ".5rem" }}
-          >
-            <FileCard title={title} type={type} tags={tags} id={id} />
-          </Col>
-        ))}
-      </Row>
-    </>
-  );
-};
+type idBooleanMap = { [key: number]: boolean };
+interface MyState {
+  isSelected: idBooleanMap;
+}
+
+class QuickAccess extends React.Component<QuickAccessProps, MyState> {
+  constructor(props: QuickAccessProps) {
+    super(props);
+    let isSelected: idBooleanMap = [];
+    this.state = { isSelected };
+  }
+
+  componentDidMount() {
+    let isSelected: idBooleanMap = [];
+    this.props.quickAccessItems.forEach(({ id }: { id: number }) => {
+      isSelected[id] = false;
+    });
+    this.setState({ isSelected });
+  }
+
+  isAnySelected(): boolean {
+    let items = this.props.quickAccessItems;
+    let isSelected = this.state.isSelected;
+    for (let item in items) {
+      if (isSelected[items[item].id]) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  isAllSelected(): boolean {
+    let items = this.props.quickAccessItems;
+    let isSelected = this.state.isSelected;
+    for (let item in items) {
+      if (!isSelected[items[item].id]) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  handleIconClick(id: number) {
+    let isSelected = JSON.parse(JSON.stringify(this.state.isSelected));
+    isSelected[id] = !isSelected[id];
+    this.setState({ isSelected });
+  }
+
+  handleSelectAllClick() {
+    let items = this.props.quickAccessItems;
+    let isSelected = JSON.parse(JSON.stringify(this.state.isSelected));
+    let setValue = !this.isAllSelected();
+    for (let item in items) {
+      isSelected[items[item].id] = setValue;
+    }
+    this.setState({ isSelected });
+  }
+
+  render() {
+    return (
+      <>
+        <ResourceSectionHeader
+					heading="Quick Access"
+					showDownload={this.isAnySelected()}
+          onSelectAllClick={() => this.handleSelectAllClick()}
+          selectAllIcon={this.isAllSelected() ? faCheckSquare : faSquare}
+        />
+
+        <Row
+          className={classNames(
+            "d-flex",
+            "flex-row",
+            "flex-nowrap",
+            styles.quickAccessRow
+          )}
+        >
+          {this.props.quickAccessItems.map(({ title, type, tags, id }) => (
+            <Col
+              xs={7}
+              sm={5}
+              md={5}
+              lg={4}
+              xl={3}
+              key={id}
+              style={{ marginBottom: ".5rem" }}
+            >
+              <FileCard
+                title={title}
+                type={type}
+                tags={tags}
+                icon={
+                  this.isAnySelected()
+                    ? this.state.isSelected[id]
+                      ? faCheckSquare
+                      : faSquare
+                    : faFile
+                }
+                onIconClick={() => {
+                  this.handleIconClick(id);
+                }}
+              />
+            </Col>
+          ))}
+        </Row>
+      </>
+    );
+  }
+}
 
 export default QuickAccess;
diff --git a/frontend/src/components/molecules/ResourceFolders/index.tsx b/frontend/src/components/molecules/ResourceFolders/index.tsx
index 5ca493d02..28de847f1 100644
--- a/frontend/src/components/molecules/ResourceFolders/index.tsx
+++ b/frontend/src/components/molecules/ResourceFolders/index.tsx
@@ -3,13 +3,8 @@ import Row from "react-bootstrap/esm/Row";
 import Col from "react-bootstrap/esm/Col";
 import ResourceSectionHeader from "../ResourceSectionHeader";
 import FolderCard from "components/atoms/FolderCard";
-import {
-  faSquare,
-  faCheckSquare,
-} from "@fortawesome/free-regular-svg-icons";
-import {
-  faFolder
-} from "@fortawesome/free-solid-svg-icons";
+import { faSquare, faCheckSquare } from "@fortawesome/free-regular-svg-icons";
+import { faFolder } from "@fortawesome/free-solid-svg-icons";
 export interface ResourceFoldersProps {
   folderItems: {
     title: string;
@@ -65,10 +60,25 @@ class ResourceFolders extends React.Component<ResourceFoldersProps, MyState> {
     this.setState({ isSelected });
   }
 
+  handleSelectAllClick() {
+    let items = this.props.folderItems;
+    let isSelected = JSON.parse(JSON.stringify(this.state.isSelected));
+    let setValue = !this.isAllSelected();
+    for (let item in items) {
+      isSelected[items[item].id] = setValue;
+    }
+    this.setState({ isSelected });
+  }
+
   render() {
     return (
       <>
-        <ResourceSectionHeader heading="Folders" />
+        <ResourceSectionHeader
+					heading="Folders"
+					showDownload={this.isAnySelected()}
+          onSelectAllClick={() => this.handleSelectAllClick()}
+          selectAllIcon={this.isAllSelected() ? faCheckSquare : faSquare}
+        />
 
         <Row style={{ marginTop: "10px" }}>
           {this.props.folderItems.map(({ title, id }) => (
diff --git a/frontend/src/components/molecules/ResourceSectionHeader/index.tsx b/frontend/src/components/molecules/ResourceSectionHeader/index.tsx
index 1f772ff7c..e0a0774f2 100644
--- a/frontend/src/components/molecules/ResourceSectionHeader/index.tsx
+++ b/frontend/src/components/molecules/ResourceSectionHeader/index.tsx
@@ -3,26 +3,44 @@ 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 { faSquare , faCheckSquare} from "@fortawesome/free-regular-svg-icons";
+import { faDownload, IconDefinition } from "@fortawesome/free-solid-svg-icons";
 
 export interface SectionHeaderProps {
   heading: string;
+  selectAllIcon: IconDefinition;
+  showDownload: boolean;
+  onSelectAllClick: (event: React.MouseEvent) => void;
 }
 
-const ResourceSectionHeader: React.FC<SectionHeaderProps> = ({heading}: SectionHeaderProps) => {
+const ResourceSectionHeader: React.FC<SectionHeaderProps> = ({
+  heading,
+  onSelectAllClick,
+  showDownload,
+  selectAllIcon,
+}: SectionHeaderProps) => {
   return (
     <>
       <div className={styles.sectionHeaderContainer}>
-        <span className={styles.sectionHeader}>{heading}</span>
+        <span className={styles.sectionHeader} onClick={onSelectAllClick}>
+          {heading}
+        </span>
         <div className={styles.sectionHeaderButtonGroup}>
-          <Button className={styles.sectionHeaderButton}>
-            <FontAwesomeIcon className={styles.buttonIcon} icon={faDownload} />
-          </Button>
-          <Button className={styles.sectionHeaderButton}> 
-            <FontAwesomeIcon className={styles.buttonIcon} icon={faSquare} />
+          {showDownload ? (
+            <Button className={styles.sectionHeaderButton}>
+              <FontAwesomeIcon
+                className={styles.buttonIcon}
+                icon={faDownload}
+              />
+            </Button>
+          ) : null}
+          <Button
+            className={styles.sectionHeaderButton}
+            onClick={onSelectAllClick}
+          >
+            <FontAwesomeIcon
+              className={styles.buttonIcon}
+              icon={selectAllIcon}
+            />
           </Button>
         </div>
       </div>
-- 
GitLab