Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions frontend/src/packages/dashboard/Dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -33,12 +38,12 @@ export default function Dashboard() {
);

const [selectedFile, setSelectedFile] = useState<string | null>(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 (
Expand Down
42 changes: 33 additions & 9 deletions frontend/src/packages/dashboard/components/Directory.tsx
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -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 { PathObject } from "../state/folders/types";

const DirectoryFlex = styled.div`
display: flex;
Expand All @@ -22,9 +26,10 @@ 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 {
backgroundColor,
height: theme.spacing(3),
Expand All @@ -40,25 +45,44 @@ const BreadcrumbItem = customStyle(Chip)(({ theme }) => {
};
});

// Wrapper used for breadcrumb to individualise onClick for each pill
type BreadcrumbItemWrapperProps = {
folderObject: PathObject;
};

const BreadcrumbItemWrapper = ({
folderObject,
}: BreadcrumbItemWrapperProps) => {
const dispatch = useDispatch();
const handleClickBreadcrumbItem = () => {
dispatch(traverseIntoFolder(folderObject.folderId));
};
return (
<div>
<BreadcrumbItem
label={folderObject.folderName}
onClick={handleClickBreadcrumbItem}
/>
</div>
);
};

export default function Directory() {
const dispatch = useDispatch();
const parentFolder = getFolderState().parentFolder;

const handleClick = () => {
dispatch(traverseBackFolder(parentFolder));
};

return (
<DirectoryFlex>
<IconButton aria-label="back" onClick={() => handleClick()}>
<ArrowBackIcon fontSize="inherit" />
</IconButton>
<Breadcrumbs aria-label="breadcrumb">
{getFolderState()
.path.split("/")
.map((folder, i) => {
return <BreadcrumbItem key={i} label={folder} />;
})}
{getFolderState().path.map((folderObject, i) => {
return <BreadcrumbItemWrapper folderObject={folderObject} key={i} />;
})}
</Breadcrumbs>
</DirectoryFlex>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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: [],
};
95 changes: 53 additions & 42 deletions frontend/src/packages/dashboard/state/folders/reducers.ts
Original file line number Diff line number Diff line change
@@ -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<FileEntity[]>) {
const newEntityList: FileEntity[] = action.payload;
export function setItems(
state: sliceState,
action: PayloadAction<FileEntity[]>
) {
const newEntityList: FileEntity[] = [...action.payload];
return {
...state,
items: newEntityList
}
items: newEntityList,
};
}


export function addFolderItems(state: sliceState, action: PayloadAction<Folder>) {
export function addFolderItems(
state: sliceState,
action: PayloadAction<Folder>
) {
const newFolder: Folder = action.payload;
return {
...state,
items: [
...state.items,
newFolder,
]
}
items: [...state.items, newFolder],
};
}

export function addFileItems(state: sliceState, action: PayloadAction<File>) {
const newFile: File = action.payload;
return {
...state,
items: [
...state.items,
newFile,
]
}
...state,
items: [...state.items, newFile],
};
}

export function renameFileEntity(state: sliceState, action: PayloadAction<RenamePayloadType>) {
export function renameFileEntity(
state: sliceState,
action: PayloadAction<RenamePayloadType>
) {
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<SetDirPayloadType>) {
let pathDir = state.path;
export function setDirectory(
state: sliceState,
action: PayloadAction<SetDirPayloadType>
) {
// 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,
};
}


9 changes: 8 additions & 1 deletion frontend/src/packages/dashboard/state/folders/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,15 @@ 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;
};

export type sliceState = {
parentFolder: string;
path: string;
path: PathObject[];
items: FileEntity[];
};