diff --git a/src/components/pages/ModuleResources/components/FoldersView.tsx b/src/components/pages/ModuleResources/components/FoldersView.tsx index 44dfdb87971315a42bf9802471dc24675559ac9e..48455eb46769339c5a6f0c334dc2f8c1b21cfd4e 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 dc8d5045657187c20bee8de81443d0175db45652..34e2db1b5cae1ea9bbe6b31f68b437141dfce537 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 2312c4980b7c9ee0ee31ad7845193c5a8fb87ec0..28cde2d4efe2ed2e080d5d3fb36ab1a21e1846d6 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 (