From 836f5d35cd808f31c037328d78963a821999e32a Mon Sep 17 00:00:00 2001
From: Wilson Chua <wwc4618@ic.ac.uk>
Date: Mon, 24 Aug 2020 17:34:41 +0800
Subject: [PATCH] ModuleResources: Support link resource type, but still
 missing banner for the card

---
 .../molecules/CategoryList/index.tsx          | 21 +---------
 .../molecules/CurrentDirectoryRow/index.tsx   | 22 ++--------
 .../molecules/QuickAccessRow/index.tsx        | 22 ++--------
 .../pages/ModuleResources/index.tsx           | 40 +++++++++++++++++--
 4 files changed, 44 insertions(+), 61 deletions(-)

diff --git a/src/components/molecules/CategoryList/index.tsx b/src/components/molecules/CategoryList/index.tsx
index 7d431b8ff..e61877f0d 100644
--- a/src/components/molecules/CategoryList/index.tsx
+++ b/src/components/molecules/CategoryList/index.tsx
@@ -6,14 +6,9 @@ import Row from "react-bootstrap/esm/Row";
 import Col from "react-bootstrap/esm/Col";
 import Badge from "react-bootstrap/Badge";
 import { faSquare, faCheckSquare } from "@fortawesome/free-regular-svg-icons";
-import {
-  faFileAlt,
-  IconDefinition,
-  faFilePdf,
-  faFileVideo,
-} from "@fortawesome/free-solid-svg-icons";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { SelectionProps } from "components/molecules/SelectionView";
+import { resourceTypeToIcon } from "../../pages/ModuleResources"
 
 const CategoryList: React.FC<{ select: SelectionProps }> = ({
   select,
@@ -21,25 +16,13 @@ const CategoryList: React.FC<{ select: SelectionProps }> = ({
   return (
       <>
       {select.selectionItems.map(({ title, type, tags, id }) => {
-        let normalIcon: IconDefinition;
         if (type === undefined || tags === undefined) return null;
-        switch (type) {
-          case "pdf":
-            normalIcon = faFilePdf;
-            break;
-          case "video":
-            normalIcon = faFileVideo;
-            break;
-          default:
-            normalIcon = faFileAlt;
-            break;
-        }
 
         let icon = select.isAnySelected() || select.state.isHoveringOver[id]
           ? select.state.isSelected[id]
             ? faCheckSquare
             : faSquare
-          : normalIcon;
+          : resourceTypeToIcon(type);
 
         return (
           <Row
diff --git a/src/components/molecules/CurrentDirectoryRow/index.tsx b/src/components/molecules/CurrentDirectoryRow/index.tsx
index e3d51b5cd..a606063ad 100644
--- a/src/components/molecules/CurrentDirectoryRow/index.tsx
+++ b/src/components/molecules/CurrentDirectoryRow/index.tsx
@@ -4,13 +4,8 @@ import Row from "react-bootstrap/esm/Row";
 import Col from "react-bootstrap/esm/Col";
 import FileCard from "components/atoms/FileCard";
 import { faSquare, faCheckSquare } from "@fortawesome/free-regular-svg-icons";
-import {
-  faFileAlt,
-  IconDefinition,
-  faFilePdf,
-  faFileVideo,
-} from "@fortawesome/free-solid-svg-icons";
 import { SelectionProps } from "components/molecules/SelectionView";
+import { resourceTypeToIcon } from "../../pages/ModuleResources"
 
 const CurrentDirectoryRow: React.FC<{ select: SelectionProps }> = ({
   select,
@@ -20,19 +15,8 @@ const CurrentDirectoryRow: React.FC<{ select: SelectionProps }> = ({
       style={{ marginTop: "10px", marginLeft: "-10px", marginRight: "-10px" }}
     >
       {select.selectionItems.map(({ title, type, tags, id }) => {
-        let normalIcon: IconDefinition;
         if (type === undefined || tags === undefined) return null;
-        switch (type) {
-          case "pdf":
-            normalIcon = faFilePdf;
-            break;
-          case "video":
-            normalIcon = faFileVideo;
-            break;
-          default:
-            normalIcon = faFileAlt;
-            break;
-        }
+
         return (
           <Col
             xs={6}
@@ -57,7 +41,7 @@ const CurrentDirectoryRow: React.FC<{ select: SelectionProps }> = ({
                   ? select.state.isSelected[id]
                     ? faCheckSquare
                     : faSquare
-                  : normalIcon
+                  : resourceTypeToIcon(type)
               }
               onClick={() => select.handleCardClick(id)}
               onIconClick={(e) => {
diff --git a/src/components/molecules/QuickAccessRow/index.tsx b/src/components/molecules/QuickAccessRow/index.tsx
index 884f21a20..34d1ab888 100644
--- a/src/components/molecules/QuickAccessRow/index.tsx
+++ b/src/components/molecules/QuickAccessRow/index.tsx
@@ -6,13 +6,8 @@ import Row from "react-bootstrap/esm/Row";
 import Col from "react-bootstrap/esm/Col";
 import FileCard from "components/atoms/FileCard";
 import { faSquare, faCheckSquare } from "@fortawesome/free-regular-svg-icons";
-import {
-  faFileAlt,
-  IconDefinition,
-  faFilePdf,
-  faFileVideo,
-} from "@fortawesome/free-solid-svg-icons";
 import { SelectionProps } from "components/molecules/SelectionView";
+import { resourceTypeToIcon } from "../../pages/ModuleResources"
 
 const QuickAccessRow: React.FC<{ select: SelectionProps }> = ({
   select,
@@ -27,19 +22,8 @@ const QuickAccessRow: React.FC<{ select: SelectionProps }> = ({
       )}
     >
       {select.selectionItems.map(({ title, type, tags, id }) => {
-        let normalIcon: IconDefinition;
         if (type === undefined || tags === undefined) return null;
-        switch (type) {
-          case "pdf":
-            normalIcon = faFilePdf;
-            break;
-          case "video":
-            normalIcon = faFileVideo;
-            break;
-          default:
-            normalIcon = faFileAlt;
-            break;
-        }
+
         return (
           <Col
             xs={7}
@@ -64,7 +48,7 @@ const QuickAccessRow: React.FC<{ select: SelectionProps }> = ({
                   ? select.state.isSelected[id]
                     ? faCheckSquare
                     : faSquare
-                  : normalIcon
+                  : resourceTypeToIcon(type)
               }
               onClick={() => select.handleCardClick(id)}
               onIconClick={(e) => {
diff --git a/src/components/pages/ModuleResources/index.tsx b/src/components/pages/ModuleResources/index.tsx
index 28cde2d4e..d7cd9cb42 100644
--- a/src/components/pages/ModuleResources/index.tsx
+++ b/src/components/pages/ModuleResources/index.tsx
@@ -7,6 +7,13 @@ import CurrentDirectoryView from "./components/CurrentDirectoryView";
 import FoldersView from "./components/FoldersView";
 import ListView from "./components/ListView";
 import TopSection from "./components/TopSection";
+import {
+  faFileAlt,
+  faFilePdf,
+  faFileVideo,
+  faLink,
+  IconDefinition,
+} from "@fortawesome/free-solid-svg-icons";
 
 export interface Resource {
   title: string;
@@ -14,6 +21,7 @@ export interface Resource {
   tags: string[];
   folder: string;
   id: number;
+  path?: string;
 }
 
 export interface Folder {
@@ -35,6 +43,19 @@ export interface ResourceState {
   searchText: string;
 }
 
+export function resourceTypeToIcon(type: string): IconDefinition {
+  switch (type) {
+    case "pdf":
+      return faFilePdf;
+    case "video":
+      return faFileVideo;
+    case "link":
+      return faLink;
+    default:
+      return faFileAlt;
+  }
+}
+
 class ModuleResources extends React.Component<ResourcesProps, ResourceState> {
   moduleCode = this.props.moduleID.startsWith("CO")
     ? this.props.moduleID.slice(2)
@@ -65,6 +86,7 @@ class ModuleResources extends React.Component<ResourcesProps, ResourceState> {
             tags: resource.tags,
             folder: resource.category,
             id: resource.id,
+            path: resource.path,
           } as Resource);
         }
         this.setState({ resources: resourceArr, isLoaded: true });
@@ -128,7 +150,17 @@ class ModuleResources extends React.Component<ResourcesProps, ResourceState> {
     });
   }
 
-  handleFileClick(id: number) {
+  handleResourceClick(id: number) {
+    let resource = this.state.resources.find(resource => resource.id === id);
+    if (resource === undefined) {
+      return;
+    }
+    if (resource.type === "link") {
+      window.open(resource.path, "_blank");
+      return;
+    }
+
+    // Resource is of file type, get from Materials
     const onSuccess = (data: any) => {
       // TODO: Try to navigate straight to the endpoint url instead of creating an object url
       data.blob().then((blob: any) => {
@@ -218,7 +250,7 @@ class ModuleResources extends React.Component<ResourcesProps, ResourceState> {
               scope={scope}
               searchText={this.state.searchText}
               onDownloadClick={(ids) => this.handleFileDownload(ids)}
-              onItemClick={(id) => this.handleFileClick(id)}
+              onItemClick={(id) => this.handleResourceClick(id)}
               includeInSearchResult={this.includeInSearchResult}
             />
 
@@ -227,7 +259,7 @@ class ModuleResources extends React.Component<ResourcesProps, ResourceState> {
               scope={scope}
               searchText={this.state.searchText}
               onDownloadClick={(ids) => this.handleFileDownload(ids)}
-              onItemClick={(id) => this.handleFileClick(id)}
+              onItemClick={(id) => this.handleResourceClick(id)}
             />
           </>
         );
@@ -239,7 +271,7 @@ class ModuleResources extends React.Component<ResourcesProps, ResourceState> {
               searchText={this.state.searchText}
               onDownloadClick={(ids) => this.handleFileDownload(ids)}
               onSectionDownloadClick={(category) => this.handleSectionDownload(category)}
-              onItemClick={(id) => this.handleFileClick(id)}
+              onItemClick={(id) => this.handleResourceClick(id)}
               includeInSearchResult={this.includeInSearchResult}
             />
           </>
-- 
GitLab