Skip to content
This repository was archived by the owner on Apr 5, 2024. It is now read-only.
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
8 changes: 0 additions & 8 deletions src/__tests__/__snapshots__/storybook.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -226,13 +226,6 @@ exports[`Storyshots Filesystem default 1`] = `
Download
</a>
</span>
<button
className="btn btn-primary"
disabled={false}
type="button"
>
New Folder
</button>
</span>
</div>
<div
Expand Down Expand Up @@ -333,7 +326,6 @@ exports[`Storyshots Filesystem default 1`] = `
<div
className="text-center col"
>

Nothing to see here.
</div>
</div>
Expand Down
91 changes: 66 additions & 25 deletions src/background/api/filesystem.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,30 @@
import {FsEntity} from "./filesystemTypes";
import {filesystemPath, hostname} from "./api";
import Axios, {AxiosResponse} from "axios";
import {constants} from "../constants";
import { FsEntity } from "./filesystemTypes";
import { filesystemPath, hostname } from "./api";
import Axios, { AxiosError, AxiosResponse } from "axios";
import { constants } from "../constants";

import store from "../redux/store";
import {ApiAction, ApiActionStatus, ApiActionType} from "../redux/actions/apiActionsTypes";
import {addApiAction, changeStatus, nextFsEntity} from "../redux/actions/apiActions";
import {addToContents, removeFromContents} from "../redux/actions/filesystem";
import {EditableFileWithPreflightInfo, PreflightEntity} from "../../components/pages/filesytem/upload/preflightTypes";
import {isFsEntityInFolder} from "../methods/filesystem";

import {
ApiAction,
ApiActionStatus,
ApiActionType
} from "../redux/actions/apiActionsTypes";
import {
addApiAction,
changeStatus,
nextFsEntity
} from "../redux/actions/apiActions";
import { addToContents, removeFromContents } from "../redux/actions/filesystem";
import {
EditableFileWithPreflightInfo,
PreflightEntity
} from "../../components/pages/filesytem/upload/preflightTypes";
import { isFsEntityInFolder } from "../methods/filesystem";

const fhHostname = constants.url.FH_URL;

export const getFolderContents = (path: string) => {
console.log("[Get folder content", path)
console.log("[Get folder content", path);
return new Promise<AxiosResponse<FsEntity[]>>((resolve, reject) => {
let config = {
headers: {
Expand All @@ -24,9 +34,8 @@ export const getFolderContents = (path: string) => {
Axios.get<FsEntity[]>(hostname + filesystemPath + "contents", config)
.then((response: AxiosResponse<FsEntity[]>) => resolve(response))
.catch((error) => reject(error));
})
}

});
};

export const uploadPreflight = (
files: File[] | EditableFileWithPreflightInfo[],
Expand All @@ -43,7 +52,8 @@ export const uploadPreflight = (
}));
return new Promise<PreflightEntity[]>((resolve, reject) => {
Axios.post<PreflightEntity[]>(
hostname + filesystemPath + parentFolderID + "/upload/preflight", postData
hostname + filesystemPath + parentFolderID + "/upload/preflight",
postData
)
.then((response: AxiosResponse<PreflightEntity[]>) => {
resolve(response.data);
Expand All @@ -52,8 +62,15 @@ export const uploadPreflight = (
});
};

export const uploadFiles = (files: File[] | EditableFileWithPreflightInfo[], parentFolderID: string) => {
console.log("[API filesystem] uploading files to folderID", parentFolderID , files);
export const uploadFiles = (
files: File[] | EditableFileWithPreflightInfo[],
parentFolderID: string
) => {
console.log(
"[API filesystem] uploading files to folderID",
parentFolderID,
files
);
const apiCall = (file: File | EditableFileWithPreflightInfo) => {
return new Promise((resolve, reject) => {
let formData = new FormData();
Expand All @@ -78,9 +95,10 @@ export const uploadFiles = (files: File[] | EditableFileWithPreflightInfo[], par
.then((response: AxiosResponse<[FsEntity]>) => {
const currentPath = store.getState().filesystem.currentPath;

const fsEntityToShow = response.data.find((fsEntity: FsEntity) =>
isFsEntityInFolder(fsEntity, currentPath)
)
const fsEntityToShow = response.data.find(
(fsEntity: FsEntity) =>
isFsEntityInFolder(fsEntity, currentPath)
);

if (fsEntityToShow) {
store.dispatch(addToContents(fsEntityToShow));
Expand All @@ -93,15 +111,16 @@ export const uploadFiles = (files: File[] | EditableFileWithPreflightInfo[], par
handleMultipleApiActions(files, apiCall, ApiActionType.UPLOAD);
};


export const deleteFsEntities = (files: FsEntity[]) => {
const apiCall = (fsEntity: FsEntity) => {
return new Promise((resolve, reject) => {
Axios.delete<FsEntity[]>(
fhHostname + "/delete/" + fsEntity.fileSystemId
)
.then((response: AxiosResponse<FsEntity[]>) => {
response.data.forEach((e) => store.dispatch(removeFromContents(e)));
response.data.forEach((e) =>
store.dispatch(removeFromContents(e))
);
resolve(response);
})
.catch((error) => reject(error));
Expand All @@ -110,6 +129,21 @@ export const deleteFsEntities = (files: FsEntity[]) => {
handleMultipleApiActions(files, apiCall, ApiActionType.DELETE);
};

export const createNewFolder = (
folderName: string,
parentFolderID: string
): Promise<AxiosResponse<FsEntity>> => {
const body = { name: folderName };

return new Promise((resolve, reject) => {
Axios.post<FsEntity>(
hostname + filesystemPath + parentFolderID + "/folder/create",
body
)
.then((response: AxiosResponse<FsEntity>) => resolve(response))
.catch((error: AxiosError) => reject(error));
});
};

function handleMultipleApiActions<Type extends File | FsEntity>(
items: Type[],
Expand All @@ -134,7 +168,9 @@ function handleMultipleApiActions<Type extends File | FsEntity>(
// get the info from the store
apiAction = store
.getState()
.apiActions.actions.find((a: ApiAction) => a.key === apiAction?.key);
.apiActions.actions.find(
(a: ApiAction) => a.key === apiAction?.key
);

if (
!apiAction ||
Expand All @@ -150,7 +186,10 @@ function handleMultipleApiActions<Type extends File | FsEntity>(

if (currentIndex === apiAction.totalAmount) {
store.dispatch(
changeStatus({key: apiAction.key, status: ApiActionStatus.FINISHED})
changeStatus({
key: apiAction.key,
status: ApiActionStatus.FINISHED
})
);
return;
} else {
Expand All @@ -166,7 +205,9 @@ function handleMultipleApiActions<Type extends File | FsEntity>(

action(items[currentIndex])
.then((response) => {
console.log("[API filesystem] handleMultipleApiActions next iteration");
console.log(
"[API filesystem] handleMultipleApiActions next iteration"
);
handleMultipleApiActions(items, action, type, apiAction);
})
.catch((error) => {
Expand Down
29 changes: 13 additions & 16 deletions src/background/constants.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,26 @@
interface constantsdef {
url: { API_URL: string
FH_URL: string};
url: { API_URL: string; FH_URL: string };
}

const prod: constantsdef = {
url: {
API_URL: window.location.origin + "/api",
FH_URL: window.location.origin + "/data"
}
url: {
API_URL: window.location.origin + "/api",
FH_URL: window.location.origin + "/data"
}
};

const dev: constantsdef = {
url: {
API_URL: "https://demo.filefighter.de/api",
// API_URL: "http://localhost:8080",
//API_URL: "http://localhost/api",
//FH_URL: "http://localhost:5000/data"
//FH_URL: "http://localhost/data"
FH_URL: "https://demo.filefighter.de/data"

}
url: {
API_URL: "https://demo.filefighter.de/api",
// API_URL: "http://localhost:8080",
//API_URL: "http://localhost/api",
//FH_URL: "http://localhost:5000/data"
//FH_URL: "http://localhost/data"
FH_URL: "https://demo.filefighter.de/data"
}
};
export const constants = process.env.NODE_ENV === "development" ? dev : prod;


export const MIN_PASSWORD_LENGTH = 8;
export const MAX_PASSWORD_LENGTH = 20;
export const DEFAULT_ALERT_DURATION = 3500;
3 changes: 1 addition & 2 deletions src/components/pages/filesytem/FileList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -223,11 +223,10 @@ function FileList(props: Props): ReactElement {
<div className="overflow-auto flex-grow-1">
{/*Table Body*/}
<Row className="m-0">
{error ? (
{error && !filesAndFolders.length ? (
<Col className={"text-center"}> {error}</Col>
) : filesAndFolders?.length === 0 ? (
<Col className={"text-center"}>
{" "}
Nothing to see here.
</Col>
) : (
Expand Down
3 changes: 2 additions & 1 deletion src/components/pages/filesytem/ToolbarActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { connect, ConnectedProps } from "react-redux";
import { deleteFsEntities } from "../../../background/api/filesystem";
import { constants } from "../../../background/constants";
import { FsEntity } from "../../../background/api/filesystemTypes";
import { NewFolder } from "./upload/NewFolder";

const mapState = (state: SystemState) => ({
selectedFsEntities: state.filesystem.selectedFsEntities
Expand Down Expand Up @@ -34,7 +35,7 @@ function ToolbarActions(props: Props): ReactElement | null {
href={constants.url.FH_URL + "/download?ids=" + props.selectedFsEntities.map((e: FsEntity) => e.fileSystemId.toString())}>Download</Button>
</span>
</Fade>
<Button>New Folder</Button>
<NewFolder/>
</span>
);
}
Expand Down
37 changes: 37 additions & 0 deletions src/components/pages/filesytem/upload/NewFolder.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { useSelector } from "react-redux";
import React, { ReactElement, useState } from "react";
import { RootState } from "../../../../background/redux/store";
import { Button } from "react-bootstrap";
import { Modal } from "react-bootstrap";
import { NewFolderModalContent } from "./NewFolderModalContent";

function NewFolder(): ReactElement {
const currentFsItemId = useSelector(
(state: RootState) => state.filesystem.currentFsItemId
);
const [showModal, setShowModal] = useState(false);
const handleClose = () => setShowModal(false);
const handleShow = () => setShowModal(true);

if (currentFsItemId === "-1") {
Copy link
Member

@Gimleux Gimleux May 22, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<3

return <></>;
}

return (
<>
<Button onClick={handleShow}>New Folder</Button>
<Modal
show={showModal}
onHide={handleClose}
contentClassName={"bg-body"}
>
<NewFolderModalContent
handleClose={handleClose}
currentFsItemId={currentFsItemId}
/>
</Modal>
</>
);
}

export { NewFolder };
71 changes: 71 additions & 0 deletions src/components/pages/filesytem/upload/NewFolderModalContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { Button, Form, Modal, Row } from "react-bootstrap";
import React, { FormEvent, useState } from "react";
import { createNewFolder } from "../../../../background/api/filesystem";
import { isFileNameValid } from "../../../../background/methods/filesystem";
import { useDispatch } from "react-redux";
import { addToContents } from "../../../../background/redux/actions/filesystem";

interface Props {
handleClose: () => void;
currentFsItemId: string;
}

function NewFolderModalContent({ handleClose, currentFsItemId }: Props) {
const dispatch = useDispatch();
const [folderName, setFolderName] = useState("");
const [error, setError] = useState("");

function handleApply(event: FormEvent) {
event.preventDefault();
console.log("[NEW FOLDER ]", folderName);
if (!isFileNameValid(folderName)) {
setError("The name is not a valid foldername.");
return;
}

createNewFolder(folderName, currentFsItemId)
.then((response) => {
dispatch(addToContents(response.data));
setError("");
handleClose();
})
.catch((error) =>
setError(
error.response?.data.message ?? "Something went wrong :("
)
);
}

return (
<Form onSubmit={handleApply}>
<Modal.Header closeButton>
<Modal.Title>Create new Directory</Modal.Title>
</Modal.Header>
<Modal.Body>
<Form.Group controlId="formFolderName">
<Form.Label>Folder name</Form.Label>
<Form.Control
type="text"
placeholder="e.g. My Cat Pictures"
value={folderName}
onChange={(event) => setFolderName(event.target.value)}
/>
</Form.Group>
{error && <p className="text-danger">{error}</p>}
</Modal.Body>

<Modal.Footer>
<Row className="w-100 justify-content-between">
<Button variant="secondary" onClick={handleClose}>
Abort
</Button>
<Button variant="primary" onClick={handleApply}>
Creat Folder
</Button>
</Row>
</Modal.Footer>
</Form>
);
}

export { NewFolderModalContent };
Loading