From 31533d77d869ba697b54fd78b2103cf6477bec40 Mon Sep 17 00:00:00 2001
From: Wilson Chua <wwc4618@ic.ac.uk>
Date: Fri, 21 Aug 2020 16:57:44 +0800
Subject: [PATCH] ModuleResources: Connect folder download endpoints

---
 .../components/FoldersView.tsx                |  10 +-
 .../ModuleResources/components/ListView.tsx   |   7 +-
 .../pages/ModuleResources/index.tsx           | 118 ++++++++++--------
 3 files changed, 74 insertions(+), 61 deletions(-)

diff --git a/src/components/pages/ModuleResources/components/FoldersView.tsx b/src/components/pages/ModuleResources/components/FoldersView.tsx
index 44dfdb879..48455eb46 100644
--- a/src/components/pages/ModuleResources/components/FoldersView.tsx
+++ b/src/components/pages/ModuleResources/components/FoldersView.tsx
@@ -1,4 +1,5 @@
 import React from "react";
+import { Folder } from "../index";
 import SelectionView, {
   SelectionProps,
 } from "components/molecules/SelectionView";
@@ -6,18 +7,17 @@ import FoldersRow from "components/molecules/FoldersRow";
 import { useHistory, useLocation } from "react-router-dom";
 
 export interface FoldersViewProps {
-  folders: {
-    title: string;
-    id: number;
-  }[];
+  folders: Folder[];
   scope: string;
   searchText: string;
+  handleFolderDownload: (ids: number[]) => void;
 }
 
 const FoldersView: React.FC<FoldersViewProps> = ({
   folders,
   scope,
   searchText,
+  handleFolderDownload
 }) => {
   let history = useHistory();
   let location = useLocation();
@@ -31,7 +31,7 @@ const FoldersView: React.FC<FoldersViewProps> = ({
     return (
       <SelectionView
         heading="Folders"
-        onDownloadClick={() => {}}
+        onDownloadClick={handleFolderDownload}
         onItemClick={handleFolderClick}
         selectionItems={folders}
         render={(select: SelectionProps) => <FoldersRow select={select} />}
diff --git a/src/components/pages/ModuleResources/components/ListView.tsx b/src/components/pages/ModuleResources/components/ListView.tsx
index dc8d50456..34e2db1b5 100644
--- a/src/components/pages/ModuleResources/components/ListView.tsx
+++ b/src/components/pages/ModuleResources/components/ListView.tsx
@@ -1,5 +1,5 @@
 import React from "react";
-import { Resource } from "../index";
+import { Resource, Folder } from "../index";
 import SelectionView, {
   SelectionProps,
 } from "components/molecules/SelectionView";
@@ -7,10 +7,7 @@ import CategoryList from "components/molecules/CategoryList";
 import CategoryHeader from "components/molecules/CategoryHeader";
 
 export interface ListViewProps {
-  folders: {
-	title: string;
-	id: number;
-  }[];
+  folders: Folder[];
   resources: Resource[];
   searchText: string;
 	onDownloadClick: (identifiers: number[]) => void;
diff --git a/src/components/pages/ModuleResources/index.tsx b/src/components/pages/ModuleResources/index.tsx
index 2312c4980..28cde2d4e 100644
--- a/src/components/pages/ModuleResources/index.tsx
+++ b/src/components/pages/ModuleResources/index.tsx
@@ -16,6 +16,11 @@ export interface Resource {
   id: number;
 }
 
+export interface Folder {
+  title: string;
+  id: number;
+}
+
 export interface ResourcesProps {
   year: string;
   moduleID: string;
@@ -77,6 +82,13 @@ class ModuleResources extends React.Component<ResourcesProps, ResourceState> {
     });
   }
 
+  // Gets the unique categories/folders that have been assigned for the resources
+  folders(): Folder[] {
+    return Array.from(new Set<string>(
+      this.state.resources.map((res: Resource) => res.folder))
+    ).map((title, id) => ({ title: title, id: id }));
+  }
+
   handleFileDownload(indices: number[]) {
     if (indices.length === 1) {
       // Only one file to download, call single file endpoint
@@ -94,6 +106,20 @@ class ModuleResources extends React.Component<ResourcesProps, ResourceState> {
     }
   }
 
+  handleFolderDownload(ids: number[]) {
+    let categories = this.folders().filter(folder => folder.id in ids)
+      .map(folder => folder.title);
+    if (categories.length === 1) {
+      this.handleSectionDownload(categories[0]);
+    } else {
+      // No endpoint for multiple category download, reuse zipped selection instead
+      let resourceIds = this.state.resources
+        .filter(resource => resource.folder in categories)
+        .map(resource => resource.id);
+      this.handleFileDownload(resourceIds);
+    }
+  }
+
   handleSectionDownload(category: string) {
     download(api.MATERIALS_ZIPPED, methods.GET, category + ".zip", {
       year: this.props.year,
@@ -176,58 +202,48 @@ class ModuleResources extends React.Component<ResourcesProps, ResourceState> {
   render() {
     let scope = this.props.scope || "";
 
-    let folders: { title: string; id: number }[] = Array.from(
-      new Set<string>(this.state.resources.map((res: Resource) => res.folder))
-    ).map((title: string, id: number) => ({
-      title: title,
-      id: id,
-    }));
-
     const view = () => {
-      switch (this.state.view) {
-        case "folder":
-          return (
-            <>
-              <FoldersView
-                folders={folders}
-                scope={scope}
-                searchText={this.state.searchText}
-              />
-
-              <CurrentDirectoryView
-                resources={this.state.resources}
-                scope={scope}
-                searchText={this.state.searchText}
-                onDownloadClick={(ids) => this.handleFileDownload(ids)}
-                onItemClick={(id) => this.handleFileClick(id)}
-                includeInSearchResult={this.includeInSearchResult}
-              />
-
-              <QuickAccessView
-                resources={this.state.resources}
-                scope={scope}
-                searchText={this.state.searchText}
-                onDownloadClick={(ids) => this.handleFileDownload(ids)}
-                onItemClick={(id) => this.handleFileClick(id)}
-              />
-            </>
-          );
-        case "list":
-          return (
-            <>
-              <ListView
-                folders={folders}
-                resources={this.state.resources}
-                searchText={this.state.searchText}
-                onDownloadClick={(ids) => this.handleFileDownload(ids)}
-                onSectionDownloadClick={(category) =>
-                  this.handleSectionDownload(category)
-                }
-                onItemClick={(id) => this.handleFileClick(id)}
-                includeInSearchResult={this.includeInSearchResult}
-              />
-            </>
-          );
+      switch(this.state.view) {
+        case "folder": return (
+          <>
+            <FoldersView
+              folders={this.folders()}
+              scope={scope}
+              searchText={this.state.searchText}
+              handleFolderDownload={(ids) => this.handleFolderDownload(ids)}
+            />
+
+            <CurrentDirectoryView
+              resources={this.state.resources}
+              scope={scope}
+              searchText={this.state.searchText}
+              onDownloadClick={(ids) => this.handleFileDownload(ids)}
+              onItemClick={(id) => this.handleFileClick(id)}
+              includeInSearchResult={this.includeInSearchResult}
+            />
+
+            <QuickAccessView
+              resources={this.state.resources}
+              scope={scope}
+              searchText={this.state.searchText}
+              onDownloadClick={(ids) => this.handleFileDownload(ids)}
+              onItemClick={(id) => this.handleFileClick(id)}
+            />
+          </>
+        );
+        case "list": return (
+          <>
+            <ListView
+              folders={this.folders()}
+              resources={this.state.resources}
+              searchText={this.state.searchText}
+              onDownloadClick={(ids) => this.handleFileDownload(ids)}
+              onSectionDownloadClick={(category) => this.handleSectionDownload(category)}
+              onItemClick={(id) => this.handleFileClick(id)}
+              includeInSearchResult={this.includeInSearchResult}
+            />
+          </>
+        );
       }
     };
     return (
-- 
GitLab