From 0807001b0b115449ba7d7a059acc9878e53e8a70 Mon Sep 17 00:00:00 2001 From: qvalentin Date: Sat, 22 May 2021 15:25:35 +0200 Subject: [PATCH 1/6] FF-430 add create new Folder api function --- src/background/api/filesystem.ts | 91 ++++++++++++++----- .../filesytem/upload/NewFolder.tsx} | 0 .../upload/NewFolderModalContent.tsx | 0 3 files changed, 66 insertions(+), 25 deletions(-) rename src/components/{basicElements/Login.css => pages/filesytem/upload/NewFolder.tsx} (100%) create mode 100644 src/components/pages/filesytem/upload/NewFolderModalContent.tsx diff --git a/src/background/api/filesystem.ts b/src/background/api/filesystem.ts index 48fadea0..89cd24ea 100644 --- a/src/background/api/filesystem.ts +++ b/src/background/api/filesystem.ts @@ -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>((resolve, reject) => { let config = { headers: { @@ -24,9 +34,8 @@ export const getFolderContents = (path: string) => { Axios.get(hostname + filesystemPath + "contents", config) .then((response: AxiosResponse) => resolve(response)) .catch((error) => reject(error)); - }) -} - + }); +}; export const uploadPreflight = ( files: File[] | EditableFileWithPreflightInfo[], @@ -43,7 +52,8 @@ export const uploadPreflight = ( })); return new Promise((resolve, reject) => { Axios.post( - hostname + filesystemPath + parentFolderID + "/upload/preflight", postData + hostname + filesystemPath + parentFolderID + "/upload/preflight", + postData ) .then((response: AxiosResponse) => { resolve(response.data); @@ -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(); @@ -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)); @@ -93,7 +111,6 @@ 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) => { @@ -101,7 +118,9 @@ export const deleteFsEntities = (files: FsEntity[]) => { fhHostname + "/delete/" + fsEntity.fileSystemId ) .then((response: AxiosResponse) => { - response.data.forEach((e) => store.dispatch(removeFromContents(e))); + response.data.forEach((e) => + store.dispatch(removeFromContents(e)) + ); resolve(response); }) .catch((error) => reject(error)); @@ -110,6 +129,21 @@ export const deleteFsEntities = (files: FsEntity[]) => { handleMultipleApiActions(files, apiCall, ApiActionType.DELETE); }; +export const createNewFolder = ( + folderName: string, + parentFolderID: string +): Promise> => { + const body = { name: folderName }; + + return new Promise((resolve, reject) => { + Axios.post( + hostname + filesystemPath + parentFolderID + "/folder/create", + body + ) + .then((response: AxiosResponse) => resolve(response)) + .catch((error: AxiosError) => reject(error)); + }); +}; function handleMultipleApiActions( items: Type[], @@ -134,7 +168,9 @@ function handleMultipleApiActions( // 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 || @@ -150,7 +186,10 @@ function handleMultipleApiActions( if (currentIndex === apiAction.totalAmount) { store.dispatch( - changeStatus({key: apiAction.key, status: ApiActionStatus.FINISHED}) + changeStatus({ + key: apiAction.key, + status: ApiActionStatus.FINISHED + }) ); return; } else { @@ -166,7 +205,9 @@ function handleMultipleApiActions( 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) => { diff --git a/src/components/basicElements/Login.css b/src/components/pages/filesytem/upload/NewFolder.tsx similarity index 100% rename from src/components/basicElements/Login.css rename to src/components/pages/filesytem/upload/NewFolder.tsx diff --git a/src/components/pages/filesytem/upload/NewFolderModalContent.tsx b/src/components/pages/filesytem/upload/NewFolderModalContent.tsx new file mode 100644 index 00000000..e69de29b From 238766170f3b82a1a1c41a148e6893b7f62bb9e5 Mon Sep 17 00:00:00 2001 From: qvalentin Date: Sat, 22 May 2021 15:26:15 +0200 Subject: [PATCH 2/6] FF-433 add Modal for create new folder --- src/components/pages/filesytem/FileList.tsx | 86 +-- .../pages/filesytem/ToolbarActions.tsx | 3 +- .../pages/filesytem/upload/NewFolder.tsx | 37 ++ .../upload/NewFolderModalContent.tsx | 66 +++ .../pages/filesytem/upload/UploadZone.tsx | 507 ++++++++++-------- 5 files changed, 438 insertions(+), 261 deletions(-) diff --git a/src/components/pages/filesytem/FileList.tsx b/src/components/pages/filesytem/FileList.tsx index 5df7acf9..70f89e7d 100644 --- a/src/components/pages/filesytem/FileList.tsx +++ b/src/components/pages/filesytem/FileList.tsx @@ -1,12 +1,12 @@ -import React, {ReactElement, useEffect, useState} from "react"; -import {getFolderContents} from "../../../background/api/filesystem"; -import {FsEntity} from "../../../background/api/filesystemTypes"; -import {Col, Container, Form, Row} from "react-bootstrap"; -import {useLocation} from "react-router-dom"; -import {FilesBreadcrumb} from "./FilesBreadcrumb"; -import {filesBaseUrl} from "./Filesystem"; +import React, { ReactElement, useEffect, useState } from "react"; +import { getFolderContents } from "../../../background/api/filesystem"; +import { FsEntity } from "../../../background/api/filesystemTypes"; +import { Col, Container, Form, Row } from "react-bootstrap"; +import { useLocation } from "react-router-dom"; +import { FilesBreadcrumb } from "./FilesBreadcrumb"; +import { filesBaseUrl } from "./Filesystem"; import FileListItem from "./FileListItem"; -import {SystemState} from "../../../background/redux/actions/sytemState"; +import { SystemState } from "../../../background/redux/actions/sytemState"; import { addToSelected, clearSelected, @@ -16,9 +16,9 @@ import { setCurrentFsItemId, setCurrentPath } from "../../../background/redux/actions/filesystem"; -import {connect, ConnectedProps} from "react-redux"; -import {FFLoading} from "../../basicElements/Loading"; -import {AxiosResponse} from "axios"; +import { connect, ConnectedProps } from "react-redux"; +import { FFLoading } from "../../basicElements/Loading"; +import { AxiosResponse } from "axios"; const mapState = (state: SystemState) => ({ filesystem: { @@ -58,7 +58,8 @@ function FileList(props: Props): ReactElement { const [sortedBy, setSortedBy] = useState(null); const [sortIncreasing, setSortIncreasing] = useState(false); const allAreSelected = - filesAndFolders?.length === props.filesystem.selectedFsEntities.length && + filesAndFolders?.length === + props.filesystem.selectedFsEntities.length && !!filesAndFolders?.length; const clearSelected = props.clearSelected; @@ -76,7 +77,9 @@ function FileList(props: Props): ReactElement { ...response.data.filter( (fsEntity: FsEntity) => fsEntity.type === "FOLDER" ), - ...response.data.filter((fsEntity: FsEntity) => fsEntity.type !== "FOLDER") + ...response.data.filter( + (fsEntity: FsEntity) => fsEntity.type !== "FOLDER" + ) ]); setError(""); setCurrentFsItemId(response.headers["x-ff-current"]); @@ -88,7 +91,7 @@ function FileList(props: Props): ReactElement { } setPath(location.pathname.slice(filesBaseUrl.length) || "/"); - setCurrentPath(path) + setCurrentPath(path); clearSelected(); updateStates(); }, [ @@ -125,23 +128,31 @@ function FileList(props: Props): ReactElement { return (a: any, b: any) => a[property] - b[property] === 0 ? a.fileSystemId - b.fileSystemId - : a[property] - b[property] + : a[property] - b[property]; case "name": case "type": - return (a:any, b:any) => - a[property].toLowerCase().localeCompare(b[property].toLowerCase()) === 0 + return (a: any, b: any) => + a[property] + .toLowerCase() + .localeCompare(b[property].toLowerCase()) === 0 ? a.fileSystemId - b.fileSystemId - : a[property].toLowerCase().localeCompare(b[property].toLowerCase()) + : a[property] + .toLowerCase() + .localeCompare(b[property].toLowerCase()); case "lastUpdated": default: - return (a:any, b:any) => + return (a: any, b: any) => a.lastUpdatedBy.username .toLowerCase() - .localeCompare(b.lastUpdatedBy.username.toLowerCase()) === 0 + .localeCompare( + b.lastUpdatedBy.username.toLowerCase() + ) === 0 ? a.fileSystemId - b.fileSystemId : a.lastUpdatedBy.username - .toLowerCase() - .localeCompare(b.lastUpdatedBy.username.toLowerCase()) + .toLowerCase() + .localeCompare( + b.lastUpdatedBy.username.toLowerCase() + ); } } @@ -150,17 +161,17 @@ function FileList(props: Props): ReactElement { return; } - setSortingOrder(property) + setSortingOrder(property); let toSort = [...(filesAndFolders ?? [])]; - toSort.sort(getSortingFunction(property)) + toSort.sort(getSortingFunction(property)); setFilesAndFolders(sortIncreasing ? toSort.reverse() : toSort); } console.log("[FileList path]" + path, filesAndFolders); return ( - + {/*//Head*/} @@ -186,32 +197,43 @@ function FileList(props: Props): ReactElement { handleSortClick("name")}> {"Name"} - handleSortClick("lastUpdatedBy")}> + handleSortClick("lastUpdatedBy")} + > Last updated by - handleSortClick("lastUpdated")}> + handleSortClick("lastUpdated")} + > {"Last changes"} handleSortClick("size")}> {"Size"} -
+
{/*//Body*/} - {error ? ( + {error && !filesAndFolders.length ? ( {error} ) : filesAndFolders?.length === 0 ? ( Nothing to see here. ) : ( - !filesAndFolders && + !filesAndFolders && )} {filesAndFolders?.map((folder: FsEntity) => { return ( - - + + ); })} diff --git a/src/components/pages/filesytem/ToolbarActions.tsx b/src/components/pages/filesytem/ToolbarActions.tsx index 0d9f337b..f958107c 100644 --- a/src/components/pages/filesytem/ToolbarActions.tsx +++ b/src/components/pages/filesytem/ToolbarActions.tsx @@ -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 @@ -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 - + ); } diff --git a/src/components/pages/filesytem/upload/NewFolder.tsx b/src/components/pages/filesytem/upload/NewFolder.tsx index e69de29b..5cbf2970 100644 --- a/src/components/pages/filesytem/upload/NewFolder.tsx +++ b/src/components/pages/filesytem/upload/NewFolder.tsx @@ -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") { + return <>; + } + + return ( + <> + + + + + + ); +} + +export { NewFolder }; diff --git a/src/components/pages/filesytem/upload/NewFolderModalContent.tsx b/src/components/pages/filesytem/upload/NewFolderModalContent.tsx index e69de29b..28b22c61 100644 --- a/src/components/pages/filesytem/upload/NewFolderModalContent.tsx +++ b/src/components/pages/filesytem/upload/NewFolderModalContent.tsx @@ -0,0 +1,66 @@ +import { Button, Form, Modal, Row } from "react-bootstrap"; +import React, { 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() { + 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)); + } + + return ( +
+ + Create new Directory + + + + Folder name + setFolderName(event.target.value)} + /> + + {error &&

{error}

} +
+ + + + + + + +
+ ); +} + +export { NewFolderModalContent }; diff --git a/src/components/pages/filesytem/upload/UploadZone.tsx b/src/components/pages/filesytem/upload/UploadZone.tsx index b4d24fd1..1fd41479 100644 --- a/src/components/pages/filesytem/upload/UploadZone.tsx +++ b/src/components/pages/filesytem/upload/UploadZone.tsx @@ -1,253 +1,304 @@ -import React, { ReactElement, Reducer, useCallback, useReducer, useState } from "react"; +import React, { + ReactElement, + Reducer, + useCallback, + useReducer, + useState +} from "react"; import { useDropzone } from "react-dropzone"; import { useSelector } from "react-redux"; import { RootState } from "../../../../background/redux/store"; import { Modal } from "react-bootstrap"; -import { uploadFiles, uploadPreflight } from "../../../../background/api/filesystem"; +import { + uploadFiles, + uploadPreflight +} from "../../../../background/api/filesystem"; import { FsEntity } from "../../../../background/api/filesystemTypes"; import { UploadDecisionsModalContent } from "./UploadDecisionsModalContent"; import { divideArrayByCondition } from "../../../../background/methods/arrays"; -import { getPathWithoutName, isFileNameValid } from "../../../../background/methods/filesystem"; import { - EditableEntityError, - EditableFileWithPreflightInfo, - EditablePreflightEntityOrFile, - PeflightEntiesActionTypes, - PREFLIGHT_ADD_ENTITIES, - PREFLIGHT_CHANGE_NAME, - PREFLIGHT_TOGGLE_ALL, - PREFLIGHT_TOGGLE_OVERWRITE, - PREFLIGHT_UPDATE_NAME, - PreflightEntity + getPathWithoutName, + isFileNameValid +} from "../../../../background/methods/filesystem"; +import { + EditableEntityError, + EditableFileWithPreflightInfo, + EditablePreflightEntityOrFile, + PeflightEntiesActionTypes, + PREFLIGHT_ADD_ENTITIES, + PREFLIGHT_CHANGE_NAME, + PREFLIGHT_TOGGLE_ALL, + PREFLIGHT_TOGGLE_OVERWRITE, + PREFLIGHT_UPDATE_NAME, + PreflightEntity } from "./preflightTypes"; import { preflightResultCombine } from "./preflightResponseParser"; export const UploadZone = (): ReactElement => { - const [showUploadDialog, setShowUploadDialog] = useState(false); - const handleClose = () => { - setPreflightResultDispatch({ type: PREFLIGHT_ADD_ENTITIES, payload: [] }); - setShowUploadDialog(false); - }; - const handleShow = () => setShowUploadDialog(true); - - const currentFsItemId = useSelector( - (state: RootState) => state.filesystem.currentFsItemId - ); - const [fsItemIdToUpload, setFsItemIdToUpload] = useState(currentFsItemId); - const currentFsContent = useSelector( - (state: RootState) => state.filesystem.folderContents - ); - - const onDrop = useCallback( - (acceptedFiles: EditableFileWithPreflightInfo[]) => { - - - if (!acceptedFiles.length){ - return // TODO: dispatch a action to show that a empty folder could not be uploaded - } - - //check if preflight is needed - let preflightNeeded = acceptedFiles.some( - (file: EditablePreflightEntityOrFile) => { - return ( - file.path.includes("/") || !isFileNameValid(file.name) || - currentFsContent.some( - (fsEntiy: FsEntity) => fsEntiy.name === file.name - ) - ); - } - ); - console.log("[Upload Zone, add files]",acceptedFiles, preflightNeeded); - - if (preflightNeeded) { - setFsItemIdToUpload(currentFsItemId); - uploadPreflight( - acceptedFiles, - currentFsItemId - ).then((response) => { - const actionsNeeded = response.some( - (e: PreflightEntity) => - !e.permissionIsSufficient || e.nameAlreadyInUse || !e.nameIsValid - ); - if (actionsNeeded) { - const combined = preflightResultCombine(acceptedFiles, response); - console.log("combined",combined) - - setPreflightResultDispatch({ - type: PREFLIGHT_ADD_ENTITIES, - payload: [ - ...combined, - ...(response.filter( - (f) => !f.isFile - )) - ] - }); - handleShow(); - } else { - uploadFiles((acceptedFiles as unknown) as File[], currentFsItemId); - } + const [showUploadDialog, setShowUploadDialog] = useState(false); + const handleClose = () => { + setPreflightResultDispatch({ + type: PREFLIGHT_ADD_ENTITIES, + payload: [] }); - } else { - uploadFiles((acceptedFiles as unknown) as File[], currentFsItemId); - } - }, - [currentFsItemId, currentFsContent] - ); - - const [preflightResult, setPreflightResultDispatch] = useReducer>(preflightResultReducer, []); - - // @ts-ignore - const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop }); - - if (currentFsItemId === "-1" ){ - return <> - } - return ( - <> -
- - {isDragActive ? ( -

Drop files here ...

- ) : ( -

Drag 'n' drop files or folders here, or click to select files

- )} -
- - - - - - ); -}; + setShowUploadDialog(false); + }; + const handleShow = () => setShowUploadDialog(true); + + const currentFsItemId = useSelector( + (state: RootState) => state.filesystem.currentFsItemId + ); + const [fsItemIdToUpload, setFsItemIdToUpload] = useState(currentFsItemId); + const currentFsContent = useSelector( + (state: RootState) => state.filesystem.folderContents + ); + + const onDrop = useCallback( + (acceptedFiles: EditableFileWithPreflightInfo[]) => { + if (!acceptedFiles.length) { + return; // TODO: dispatch a action to show that a empty folder could not be uploaded + } + + //check if preflight is needed + let preflightNeeded = acceptedFiles.some( + (file: EditablePreflightEntityOrFile) => { + return ( + file.path.includes("/") || + !isFileNameValid(file.name) || + currentFsContent.some( + (fsEntiy: FsEntity) => fsEntiy.name === file.name + ) + ); + } + ); + console.log( + "[Upload Zone, add files]", + acceptedFiles, + preflightNeeded + ); -export const preflightResultReducer: Reducer = (currentState, action) => { - switch (action.type) { - case PREFLIGHT_ADD_ENTITIES: { - return action.payload.sort(sortPreflightResult); + if (preflightNeeded) { + setFsItemIdToUpload(currentFsItemId); + uploadPreflight(acceptedFiles, currentFsItemId).then( + (response) => { + const actionsNeeded = response.some( + (e: PreflightEntity) => + !e.permissionIsSufficient || + e.nameAlreadyInUse || + !e.nameIsValid + ); + if (actionsNeeded) { + const combined = preflightResultCombine( + acceptedFiles, + response + ); + console.log("combined", combined); + + setPreflightResultDispatch({ + type: PREFLIGHT_ADD_ENTITIES, + payload: [ + ...combined, + ...response.filter((f) => !f.isFile) + ] + }); + handleShow(); + } else { + uploadFiles( + (acceptedFiles as unknown) as File[], + currentFsItemId + ); + } + } + ); + } else { + uploadFiles( + (acceptedFiles as unknown) as File[], + currentFsItemId + ); + } + }, + [currentFsItemId, currentFsContent] + ); + + const [preflightResult, setPreflightResultDispatch] = useReducer< + Reducer + >(preflightResultReducer, []); + + const { getRootProps, getInputProps, isDragActive } = useDropzone({ + // @ts-ignore + onDrop + }); + + if (currentFsItemId === "-1") { + return <>; } - case PREFLIGHT_TOGGLE_ALL: { - let [files, folders] = divideArrayByCondition( - currentState, - (e) => e.isFile - ); - let toChange = action.payload.isFolders ? folders : files; - let notToChange = !action.payload.isFolders ? folders : files; - - toChange = toChange.map((e: EditablePreflightEntityOrFile) => { - if (e.nameIsValid && e.permissionIsSufficient) { - e.overwrite = action.payload?.newValue ?? false; + return ( + <> +
+ + {isDragActive ? ( +

Drop files here ...

+ ) : ( +

+ Drag 'n' drop files or folders here, or click to select + files +

+ )} +
+ + + + + + ); +}; + +export const preflightResultReducer: Reducer< + EditablePreflightEntityOrFile[], + PeflightEntiesActionTypes +> = (currentState, action) => { + switch (action.type) { + case PREFLIGHT_ADD_ENTITIES: { + return action.payload.sort(sortPreflightResult); } - return e; - }); - return [...toChange, ...notToChange].sort(sortPreflightResult); - } - case PREFLIGHT_TOGGLE_OVERWRITE: { - let [[elementToReplace], restOfElements] = divideArrayByCondition( - currentState, - (e) => e.path === action.payload.path - ); - elementToReplace.overwrite = action.payload.overwrite; - - return [...restOfElements, elementToReplace].sort(sortPreflightResult); - } - case PREFLIGHT_CHANGE_NAME: { - let [[elementToReplace], restOfElements] = divideArrayByCondition( - currentState, - (e) => e.path === action.payload.path - ); - let oldPath = elementToReplace.newPath ?? elementToReplace.path; - - elementToReplace.newPath = - oldPath.substring( - 0, - oldPath.lastIndexOf(elementToReplace.newName ?? elementToReplace.name) - ) + action.payload.newName; - elementToReplace.newName = action.payload.newName; - elementToReplace.error = undefined; - return [...restOfElements, elementToReplace].sort(sortPreflightResult); - } - case PREFLIGHT_UPDATE_NAME: { - let [[elementToReplace], restOfElements] = divideArrayByCondition( - currentState, - (e) => e.path === action.payload.path - ); - let oldPath = elementToReplace.newPath ?? elementToReplace.path; - let newPath = - oldPath.substring( - 0, - oldPath.lastIndexOf(elementToReplace.newName ?? elementToReplace.name) - ) + action.payload.newName; - - let newPathAlreadyExits = restOfElements.some( - (e: EditablePreflightEntityOrFile) => { - let localPath = e.newPath ?? e.path; - return localPath === newPath; + case PREFLIGHT_TOGGLE_ALL: { + let [files, folders] = divideArrayByCondition( + currentState, + (e) => e.isFile + ); + let toChange = action.payload.isFolders ? folders : files; + let notToChange = !action.payload.isFolders ? folders : files; + + toChange = toChange.map((e: EditablePreflightEntityOrFile) => { + if (e.nameIsValid && e.permissionIsSufficient) { + e.overwrite = action.payload?.newValue ?? false; + } + return e; + }); + return [...toChange, ...notToChange].sort(sortPreflightResult); + } + case PREFLIGHT_TOGGLE_OVERWRITE: { + let [[elementToReplace], restOfElements] = divideArrayByCondition( + currentState, + (e) => e.path === action.payload.path + ); + elementToReplace.overwrite = action.payload.overwrite; + + return [...restOfElements, elementToReplace].sort( + sortPreflightResult + ); + } + case PREFLIGHT_CHANGE_NAME: { + let [[elementToReplace], restOfElements] = divideArrayByCondition( + currentState, + (e) => e.path === action.payload.path + ); + let oldPath = elementToReplace.newPath ?? elementToReplace.path; + + elementToReplace.newPath = + oldPath.substring( + 0, + oldPath.lastIndexOf( + elementToReplace.newName ?? elementToReplace.name + ) + ) + action.payload.newName; + elementToReplace.newName = action.payload.newName; + elementToReplace.error = undefined; + return [...restOfElements, elementToReplace].sort( + sortPreflightResult + ); + } + case PREFLIGHT_UPDATE_NAME: { + let [[elementToReplace], restOfElements] = divideArrayByCondition( + currentState, + (e) => e.path === action.payload.path + ); + let oldPath = elementToReplace.newPath ?? elementToReplace.path; + let newPath = + oldPath.substring( + 0, + oldPath.lastIndexOf( + elementToReplace.newName ?? elementToReplace.name + ) + ) + action.payload.newName; + + let newPathAlreadyExits = restOfElements.some( + (e: EditablePreflightEntityOrFile) => { + let localPath = e.newPath ?? e.path; + return localPath === newPath; + } + ); + + let newNameIsNotValid = !isFileNameValid(action.payload.newName); + + if (newPathAlreadyExits || newNameIsNotValid) { + elementToReplace.error = newPathAlreadyExits + ? EditableEntityError.ALREADYEXITS + : EditableEntityError.INVALIDNAME; + elementToReplace.newPath = + elementToReplace.prefNewPath ?? elementToReplace.path; + elementToReplace.newName = + elementToReplace.prefNewName ?? elementToReplace.name; + } else { + console.log( + elementToReplace.newPath, + elementToReplace.prefNewPath, + elementToReplace.path + ); + let prevOldPath = + elementToReplace.prefNewPath ?? elementToReplace.path; + restOfElements = restOfElements.map((e) => { + let currentPath = e.newPath ?? e.path; + let currentName = e.newName ?? e.name; + let currentPathWithoutName = getPathWithoutName( + currentPath, + currentName + ); + + let index = currentPathWithoutName.indexOf(prevOldPath); + + console.log( + prevOldPath, + currentPathWithoutName, + currentName + ); + if (index === 0) { + e.newPath = + newPath + currentPath.substr(prevOldPath?.length); + e.prefNewPath = e.newPath; + } + return e; + }); + elementToReplace.prefNewPath = newPath; + elementToReplace.prefNewName = action.payload.newName; + elementToReplace.newPath = newPath; + elementToReplace.newName = action.payload.newName; + elementToReplace.error = undefined; + console.log("updated"); + } + return [...restOfElements, elementToReplace].sort( + sortPreflightResult + ); } - ); - - let newNameIsNotValid = !isFileNameValid(action.payload.newName) - - if (newPathAlreadyExits || newNameIsNotValid) { - elementToReplace.error = newPathAlreadyExits - ? EditableEntityError.ALREADYEXITS - : EditableEntityError.INVALIDNAME; - elementToReplace.newPath = - elementToReplace.prefNewPath ?? elementToReplace.path; - elementToReplace.newName = - elementToReplace.prefNewName ?? elementToReplace.name; - } else { - console.log( - elementToReplace.newPath, - elementToReplace.prefNewPath, - elementToReplace.path - ); - let prevOldPath = elementToReplace.prefNewPath ?? elementToReplace.path; - restOfElements = restOfElements.map((e) => { - let currentPath = e.newPath ?? e.path; - let currentName = e.newName ?? e.name; - let currentPathWithoutName = getPathWithoutName( - currentPath, - currentName - ); - - let index = currentPathWithoutName.indexOf(prevOldPath); - - console.log(prevOldPath, currentPathWithoutName, currentName); - if (index === 0) { - e.newPath = newPath + currentPath.substr(prevOldPath?.length); - e.prefNewPath = e.newPath; - } - return e; - }); - elementToReplace.prefNewPath = newPath; - elementToReplace.prefNewName = action.payload.newName; - elementToReplace.newPath = newPath; - elementToReplace.newName = action.payload.newName; - elementToReplace.error = undefined; - console.log("updated"); - } - return [...restOfElements, elementToReplace].sort(sortPreflightResult); } - } }; const sortPreflightResult = ( - a: EditablePreflightEntityOrFile, - b: EditablePreflightEntityOrFile + a: EditablePreflightEntityOrFile, + b: EditablePreflightEntityOrFile ) => { - return a.path.localeCompare(b.path); + return a.path.localeCompare(b.path); }; export default UploadZone; From 7640b8c98831ab057e288c5d3feed1786a4d4c65 Mon Sep 17 00:00:00 2001 From: qvalentin Date: Sat, 22 May 2021 15:26:50 +0200 Subject: [PATCH 3/6] update snapshots --- .../__snapshots__/storybook.test.ts.snap | 7 ----- src/background/constants.ts | 29 +++++++++---------- 2 files changed, 13 insertions(+), 23 deletions(-) diff --git a/src/__tests__/__snapshots__/storybook.test.ts.snap b/src/__tests__/__snapshots__/storybook.test.ts.snap index 19c27621..24effcc4 100644 --- a/src/__tests__/__snapshots__/storybook.test.ts.snap +++ b/src/__tests__/__snapshots__/storybook.test.ts.snap @@ -210,13 +210,6 @@ exports[`Storyshots Filesystem default 1`] = ` Download -
Date: Sat, 22 May 2021 15:36:15 +0200 Subject: [PATCH 4/6] change be url --- src/background/constants.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/background/constants.ts b/src/background/constants.ts index ba13f56f..d70d2f01 100644 --- a/src/background/constants.ts +++ b/src/background/constants.ts @@ -11,8 +11,8 @@ const prod: constantsdef = { const dev: constantsdef = { url: { - // API_URL: "https://demo.filefighter.de/api", - API_URL: "http://localhost:8080", + 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" From c6297c6d965ac1db73ca93bc18e65c5f610c0a1a Mon Sep 17 00:00:00 2001 From: qvalentin Date: Sun, 23 May 2021 12:55:09 +0200 Subject: [PATCH 5/6] add prevent default to event handler --- .../pages/filesytem/upload/NewFolderModalContent.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/pages/filesytem/upload/NewFolderModalContent.tsx b/src/components/pages/filesytem/upload/NewFolderModalContent.tsx index 28b22c61..ebd434fb 100644 --- a/src/components/pages/filesytem/upload/NewFolderModalContent.tsx +++ b/src/components/pages/filesytem/upload/NewFolderModalContent.tsx @@ -1,5 +1,5 @@ import { Button, Form, Modal, Row } from "react-bootstrap"; -import React, { useState } from "react"; +import React, { FormEvent, useState } from "react"; import { createNewFolder } from "../../../../background/api/filesystem"; import { isFileNameValid } from "../../../../background/methods/filesystem"; import { useDispatch } from "react-redux"; @@ -15,7 +15,8 @@ function NewFolderModalContent({ handleClose, currentFsItemId }: Props) { const [folderName, setFolderName] = useState(""); const [error, setError] = useState(""); - function handleApply() { + function handleApply(event: FormEvent) { + event.preventDefault(); console.log("[NEW FOLDER ]", folderName); if (!isFileNameValid(folderName)) { setError("The name is not a valid foldername."); From 41b3cc530194432227aab9ef617b769030e6f7a7 Mon Sep 17 00:00:00 2001 From: qvalentin Date: Sun, 23 May 2021 13:24:02 +0200 Subject: [PATCH 6/6] update snapshots --- src/__tests__/__snapshots__/storybook.test.ts.snap | 8 -------- .../pages/filesytem/upload/NewFolderModalContent.tsx | 10 +++++++--- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/__tests__/__snapshots__/storybook.test.ts.snap b/src/__tests__/__snapshots__/storybook.test.ts.snap index 59432595..d6559c82 100644 --- a/src/__tests__/__snapshots__/storybook.test.ts.snap +++ b/src/__tests__/__snapshots__/storybook.test.ts.snap @@ -226,13 +226,6 @@ exports[`Storyshots Filesystem default 1`] = ` Download -
- Nothing to see here.
diff --git a/src/components/pages/filesytem/upload/NewFolderModalContent.tsx b/src/components/pages/filesytem/upload/NewFolderModalContent.tsx index ebd434fb..d99c5a87 100644 --- a/src/components/pages/filesytem/upload/NewFolderModalContent.tsx +++ b/src/components/pages/filesytem/upload/NewFolderModalContent.tsx @@ -29,7 +29,11 @@ function NewFolderModalContent({ handleClose, currentFsItemId }: Props) { setError(""); handleClose(); }) - .catch((error) => setError(error.response?.data.message)); + .catch((error) => + setError( + error.response?.data.message ?? "Something went wrong :(" + ) + ); } return ( @@ -53,10 +57,10 @@ function NewFolderModalContent({ handleClose, currentFsItemId }: Props) {