From 84808a433f4e76c19aade44e7d7c7eb31f5e5ab3 Mon Sep 17 00:00:00 2001 From: Brian Wang Date: Sat, 11 Mar 2023 00:19:59 +1100 Subject: [PATCH 1/3] initial testing commit --- .../dashboard/components/Directory.tsx | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/frontend/src/packages/dashboard/components/Directory.tsx b/frontend/src/packages/dashboard/components/Directory.tsx index c468d8fc..5e9b0d45 100644 --- a/frontend/src/packages/dashboard/components/Directory.tsx +++ b/frontend/src/packages/dashboard/components/Directory.tsx @@ -7,8 +7,12 @@ import { useDispatch } from "react-redux"; import IconButton from "@mui/material/IconButton"; import ArrowBackIcon from "@mui/icons-material/ArrowBack"; -import { traverseBackFolder } from "../state/folders/actions"; +import { + traverseBackFolder, + traverseIntoFolder, +} from "../state/folders/actions"; import { getFolderState } from "../api/helpers"; +import { setDirectory } from "../state/folders/reducers"; const DirectoryFlex = styled.div` display: flex; @@ -22,7 +26,7 @@ const DirectoryFlex = styled.div` const BreadcrumbItem = customStyle(Chip)(({ theme }) => { const backgroundColor = - theme.palette.mode === 'light' + theme.palette.mode === "light" ? theme.palette.grey[200] : theme.palette.grey[800]; return { @@ -48,6 +52,15 @@ export default function Directory() { dispatch(traverseBackFolder(parentFolder)); }; + const folderState = getFolderState(); + + const handleClickBreadcrumbItem = ( + event: React.MouseEvent + ) => { + dispatch(traverseIntoFolder("3f4b7ac5-2b08-43fe-87cd-4dd1d1be8455")); + console.log("getFolderState", folderState); + }; + return ( handleClick()}> @@ -57,7 +70,13 @@ export default function Directory() { {getFolderState() .path.split("/") .map((folder, i) => { - return ; + return ( + + ); })} From e81ccdce12b23fe76cb21c622234eebfe963ccbc Mon Sep 17 00:00:00 2001 From: Brian Wang Date: Sat, 25 Mar 2023 18:04:37 +1100 Subject: [PATCH 2/3] implemented clicking on breadcrumb pill redirects you to desired page using ids on pathList, corrected display of files when navigating back to root directory after exiting file view --- frontend/src/packages/dashboard/Dashboard.tsx | 13 ++- .../dashboard/components/Directory.tsx | 50 +++++----- .../dashboard/state/folders/initial-state.ts | 2 +- .../dashboard/state/folders/reducers.ts | 95 +++++++++++-------- .../packages/dashboard/state/folders/types.ts | 7 +- 5 files changed, 96 insertions(+), 71 deletions(-) diff --git a/frontend/src/packages/dashboard/Dashboard.tsx b/frontend/src/packages/dashboard/Dashboard.tsx index b2d44355..6a95faf4 100644 --- a/frontend/src/packages/dashboard/Dashboard.tsx +++ b/frontend/src/packages/dashboard/Dashboard.tsx @@ -6,9 +6,14 @@ import { Breadcrumbs, Link } from "@mui/material"; // local imports import SideBar from "src/packages/dashboard/components/SideBar/SideBar"; import Renderer from "./components/FileRenderer/Renderer"; -import { initAction, traverseBackFolder } from "./state/folders/actions"; +import { + initAction, + traverseBackFolder, + traverseIntoFolder, +} from "./state/folders/actions"; import ConfirmationWindow from "./components/ConfirmationModal/ConfirmationWindow"; import Directory from "./components/Directory"; +import { getFolderState } from "./api/helpers"; const Container = styled.div` display: flex; @@ -33,12 +38,12 @@ export default function Dashboard() { ); const [selectedFile, setSelectedFile] = useState(null); - // const parentFolder = getFolderState().parentFolder; + const parentFolder = getFolderState().parentFolder; const dispatch = useDispatch(); - useEffect(() => { // fetches all folders and files from backend and displays it - dispatch(initAction()); + // dispatch(initAction()); + dispatch(traverseIntoFolder(parentFolder)); }, []); return ( diff --git a/frontend/src/packages/dashboard/components/Directory.tsx b/frontend/src/packages/dashboard/components/Directory.tsx index 5e9b0d45..adb57c5b 100644 --- a/frontend/src/packages/dashboard/components/Directory.tsx +++ b/frontend/src/packages/dashboard/components/Directory.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useEffect } from "react"; import { Breadcrumbs } from "@mui/material"; import Chip from "@mui/material/Chip"; import { emphasize, styled as customStyle } from "@mui/material/styles"; @@ -12,7 +12,7 @@ import { traverseIntoFolder, } from "../state/folders/actions"; import { getFolderState } from "../api/helpers"; -import { setDirectory } from "../state/folders/reducers"; +import { PathObject } from "../state/folders/types"; const DirectoryFlex = styled.div` display: flex; @@ -29,6 +29,7 @@ const BreadcrumbItem = customStyle(Chip)(({ theme }) => { theme.palette.mode === "light" ? theme.palette.grey[200] : theme.palette.grey[800]; + return { backgroundColor, height: theme.spacing(3), @@ -44,6 +45,27 @@ const BreadcrumbItem = customStyle(Chip)(({ theme }) => { }; }); +type BreadcrumbItemWrapperProps = { + folderObject: PathObject; +}; + +const BreadcrumbItemWrapper = ({ + folderObject, +}: BreadcrumbItemWrapperProps) => { + const dispatch = useDispatch(); + const handleClickBreadcrumbItem = () => { + dispatch(traverseIntoFolder(folderObject.folderId)); + }; + return ( +
+ +
+ ); +}; + export default function Directory() { const dispatch = useDispatch(); const parentFolder = getFolderState().parentFolder; @@ -51,33 +73,15 @@ export default function Directory() { const handleClick = () => { dispatch(traverseBackFolder(parentFolder)); }; - - const folderState = getFolderState(); - - const handleClickBreadcrumbItem = ( - event: React.MouseEvent - ) => { - dispatch(traverseIntoFolder("3f4b7ac5-2b08-43fe-87cd-4dd1d1be8455")); - console.log("getFolderState", folderState); - }; - return ( handleClick()}> - {getFolderState() - .path.split("/") - .map((folder, i) => { - return ( - - ); - })} + {getFolderState().path.map((folderObject, i) => { + return ; + })} ); diff --git a/frontend/src/packages/dashboard/state/folders/initial-state.ts b/frontend/src/packages/dashboard/state/folders/initial-state.ts index 529363e6..502713a2 100644 --- a/frontend/src/packages/dashboard/state/folders/initial-state.ts +++ b/frontend/src/packages/dashboard/state/folders/initial-state.ts @@ -4,6 +4,6 @@ const ROOT_UUID = "00000000-0000-0000-0000-000000000000"; export const initialState: sliceState = { parentFolder: ROOT_UUID, - path: "root", + path: [{ folderName: "root", folderId: ROOT_UUID }], items: [], }; diff --git a/frontend/src/packages/dashboard/state/folders/reducers.ts b/frontend/src/packages/dashboard/state/folders/reducers.ts index c8743b27..020b6f1b 100644 --- a/frontend/src/packages/dashboard/state/folders/reducers.ts +++ b/frontend/src/packages/dashboard/state/folders/reducers.ts @@ -1,79 +1,90 @@ -import { PayloadAction } from '@reduxjs/toolkit'; -import { RenamePayloadType, SetDirPayloadType } from './actions'; -import { - sliceState, - FileEntity, - Folder, - File -} from './types'; +import { PayloadAction } from "@reduxjs/toolkit"; +import { RenamePayloadType, SetDirPayloadType } from "./actions"; +import { sliceState, FileEntity, Folder, File, PathObject } from "./types"; /** * payload takes in: * array of type Folder || File */ -export function setItems(state: sliceState, action: PayloadAction) { - const newEntityList: FileEntity[] = action.payload; +export function setItems( + state: sliceState, + action: PayloadAction +) { + const newEntityList: FileEntity[] = [...action.payload]; return { ...state, - items: newEntityList - } + items: newEntityList, + }; } - -export function addFolderItems(state: sliceState, action: PayloadAction) { +export function addFolderItems( + state: sliceState, + action: PayloadAction +) { const newFolder: Folder = action.payload; return { ...state, - items: [ - ...state.items, - newFolder, - ] - } + items: [...state.items, newFolder], + }; } export function addFileItems(state: sliceState, action: PayloadAction) { const newFile: File = action.payload; return { - ...state, - items: [ - ...state.items, - newFile, - ] - } + ...state, + items: [...state.items, newFile], + }; } -export function renameFileEntity(state: sliceState, action: PayloadAction) { +export function renameFileEntity( + state: sliceState, + action: PayloadAction +) { const { id, newName } = action.payload; return { ...state, items: state.items.map((item) => { - if(item.id == id) { - return ({ + if (item.id == id) { + return { ...item, name: newName, - }) + }; } // else return item; - }) - } + }), + }; } -export function setDirectory(state: sliceState, action: PayloadAction) { - let pathDir = state.path; +export function setDirectory( + state: sliceState, + action: PayloadAction +) { + // Helper function for setDirectory + // checks if current folder already in breadcrumb path + function folderInPathList(pathList: PathObject[], folderId: string): boolean { + for (const pathObj of pathList) { + if (pathObj.folderId === folderId) { + return true; + } + } + return false; + } - // traverse back to the previous folder - if (action.payload.folderName == '') { - pathDir = (pathDir.split("/")).slice(0, -1).join("/"); - } else { // traverse into a folder - pathDir = pathDir + '/' + action.payload.folderName; + const pathList: PathObject[] = [...state.path]; + const destFolderName: string = action.payload.folderName; + const destFolderId: string = action.payload.parentFolder; + if (folderInPathList(pathList, destFolderId)) { + while (pathList[pathList.length - 1].folderId !== destFolderId) { + pathList.pop(); + } + } else { + pathList.push({ folderName: destFolderName, folderId: destFolderId }); } return { ...state, parentFolder: action.payload.parentFolder, - path: pathDir - } + path: pathList, + }; } - - diff --git a/frontend/src/packages/dashboard/state/folders/types.ts b/frontend/src/packages/dashboard/state/folders/types.ts index 0582e45c..b007d041 100644 --- a/frontend/src/packages/dashboard/state/folders/types.ts +++ b/frontend/src/packages/dashboard/state/folders/types.ts @@ -14,8 +14,13 @@ export type File = { // folders and files export type FileEntity = Folder | File; +export type PathObject = { + folderName: string; + folderId: string; +}; + export type sliceState = { parentFolder: string; - path: string; + path: PathObject[]; items: FileEntity[]; }; From 221f6dc55b639f8d04531d84aa8e80d8ab066259 Mon Sep 17 00:00:00 2001 From: Brian Wang Date: Sat, 25 Mar 2023 18:16:50 +1100 Subject: [PATCH 3/3] commented in types.ts and Directory.tsx the reasoning behind the following additions --- frontend/src/packages/dashboard/components/Directory.tsx | 1 + frontend/src/packages/dashboard/state/folders/types.ts | 2 ++ 2 files changed, 3 insertions(+) diff --git a/frontend/src/packages/dashboard/components/Directory.tsx b/frontend/src/packages/dashboard/components/Directory.tsx index adb57c5b..9bbdb380 100644 --- a/frontend/src/packages/dashboard/components/Directory.tsx +++ b/frontend/src/packages/dashboard/components/Directory.tsx @@ -45,6 +45,7 @@ const BreadcrumbItem = customStyle(Chip)(({ theme }) => { }; }); +// Wrapper used for breadcrumb to individualise onClick for each pill type BreadcrumbItemWrapperProps = { folderObject: PathObject; }; diff --git a/frontend/src/packages/dashboard/state/folders/types.ts b/frontend/src/packages/dashboard/state/folders/types.ts index b007d041..8d6f12b1 100644 --- a/frontend/src/packages/dashboard/state/folders/types.ts +++ b/frontend/src/packages/dashboard/state/folders/types.ts @@ -14,6 +14,8 @@ export type File = { // folders and files export type FileEntity = Folder | File; +// PathObject is the type which specifies the name AND id of the +// folder we are currently in export type PathObject = { folderName: string; folderId: string;