From fa627aabf9206962a1643f61b25da59265dae856 Mon Sep 17 00:00:00 2001 From: sabhas Date: Wed, 16 Mar 2022 18:48:18 +0000 Subject: [PATCH 1/3] chore(web-refactor): state uplifted for drive container in web component --- web/src/containers/Drive/index.tsx | 50 ++++++++++++++++++++++++- web/src/containers/Drive/sideBar.tsx | 55 ++++------------------------ 2 files changed, 56 insertions(+), 49 deletions(-) diff --git a/web/src/containers/Drive/index.tsx b/web/src/containers/Drive/index.tsx index bac5119..9ec1119 100644 --- a/web/src/containers/Drive/index.tsx +++ b/web/src/containers/Drive/index.tsx @@ -1,4 +1,6 @@ -import React, { useState } from 'react' +import React, { useState, useEffect, useCallback } from 'react' +import { useLocation } from 'react-router-dom' +import axios from 'axios' import CssBaseline from '@mui/material/CssBaseline' import Box from '@mui/material/Box' @@ -6,12 +8,56 @@ import Box from '@mui/material/Box' import SideBar from './sideBar' import Main from './main' +export interface TreeNode { + name: string + relativePath: string + absolutePath: string + children: Array +} + const Drive = () => { + const location = useLocation() + const baseUrl = window.location.origin + const [selectedFilePath, setSelectedFilePath] = useState('') + const [directoryData, setDirectoryData] = useState(null) + + const setFilePathOnMount = useCallback(() => { + const queryParams = new URLSearchParams(location.search) + setSelectedFilePath(queryParams.get('filePath') ?? '') + }, [location.search]) + + useEffect(() => { + axios + .get(`/SASjsApi/drive/fileTree`) + .then((res: any) => { + if (res.data && res.data?.status === 'success') { + setDirectoryData(res.data.tree) + } + }) + .catch((err) => { + console.log(err) + }) + setFilePathOnMount() + }, [setFilePathOnMount]) + + const handleSelect = (node: TreeNode) => { + if (node.children.length) return + + if (!node.name.includes('.')) return + + window.history.pushState( + '', + '', + `${baseUrl}/#/SASjsDrive?filePath=${node.relativePath}` + ) + setSelectedFilePath(node.relativePath) + } + return ( - +
) diff --git a/web/src/containers/Drive/sideBar.tsx b/web/src/containers/Drive/sideBar.tsx index 3d07302..db3d63d 100644 --- a/web/src/containers/Drive/sideBar.tsx +++ b/web/src/containers/Drive/sideBar.tsx @@ -1,6 +1,4 @@ -import React, { useState, useEffect, useCallback } from 'react' -import axios from 'axios' -import { useLocation } from 'react-router-dom' +import React from 'react' import { makeStyles } from '@mui/styles' @@ -16,12 +14,7 @@ import TreeItem from '@mui/lab/TreeItem' import ExpandMoreIcon from '@mui/icons-material/ExpandMore' import ChevronRightIcon from '@mui/icons-material/ChevronRight' -interface TreeNode { - name: string - relativePath: string - absolutePath: string - children: Array -} +import { TreeNode } from '.' const useStyles = makeStyles(() => ({ root: { @@ -36,46 +29,14 @@ const useStyles = makeStyles(() => ({ const drawerWidth = 240 -const SideBar = (props: any) => { - const location = useLocation() - const baseUrl = window.location.origin +type Props = { + directoryData: TreeNode | null + handleSelect: (node: TreeNode) => void +} + +const SideBar = ({ directoryData, handleSelect }: Props) => { const classes = useStyles() - const { setSelectedFilePath } = props - const [directoryData, setDirectoryData] = useState(null) - - const setFilePathOnMount = useCallback(() => { - const queryParams = new URLSearchParams(location.search) - setSelectedFilePath(queryParams.get('filePath')) - }, [location.search, setSelectedFilePath]) - - useEffect(() => { - axios - .get(`/SASjsApi/drive/fileTree`) - .then((res: any) => { - if (res.data && res.data?.status === 'success') { - setDirectoryData(res.data.tree) - } - }) - .catch((err) => { - console.log(err) - }) - setFilePathOnMount() - }, [setFilePathOnMount]) - - const handleSelect = (node: TreeNode) => { - if (node.children.length) return - - if (!node.name.includes('.')) return - - window.history.pushState( - '', - '', - `${baseUrl}/#/SASjsDrive?filePath=${node.relativePath}` - ) - setSelectedFilePath(node.relativePath) - } - const renderTree = (nodes: TreeNode) => ( Date: Wed, 16 Mar 2022 18:52:00 +0000 Subject: [PATCH 2/3] fix(web-drive): upon delete remove entry of deleted file from directory tree in sidebar --- web/src/containers/Drive/index.tsx | 38 +++++++++++++++++++++++++++++- web/src/containers/Drive/main.tsx | 8 ++++++- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/web/src/containers/Drive/index.tsx b/web/src/containers/Drive/index.tsx index 9ec1119..8382831 100644 --- a/web/src/containers/Drive/index.tsx +++ b/web/src/containers/Drive/index.tsx @@ -54,11 +54,47 @@ const Drive = () => { setSelectedFilePath(node.relativePath) } + const removeFileFromTree = (path: string) => { + if (directoryData) { + const newTree = JSON.parse(JSON.stringify(directoryData)) as TreeNode + findAndRemoveNode(newTree, newTree, path) + setDirectoryData(newTree) + } + } + + const findAndRemoveNode = ( + node: TreeNode, + parentNode: TreeNode, + path: string + ) => { + if (node.relativePath === path) { + removeNodeFromParent(parentNode, path) + return true + } + if (Array.isArray(node.children)) { + for (let i = 0; i < node.children.length; i++) { + if (findAndRemoveNode(node.children[i], node, path)) return + } + } + } + + const removeNodeFromParent = (parent: TreeNode, path: string) => { + const index = parent.children.findIndex( + (node) => node.relativePath === path + ) + if (index !== -1) { + parent.children.splice(index, 1) + } + } + return ( -
+
) } diff --git a/web/src/containers/Drive/main.tsx b/web/src/containers/Drive/main.tsx index fa083a4..0a92e2f 100644 --- a/web/src/containers/Drive/main.tsx +++ b/web/src/containers/Drive/main.tsx @@ -11,7 +11,12 @@ import Button from '@mui/material/Button' import Toolbar from '@mui/material/Toolbar' import CircularProgress from '@mui/material/CircularProgress' -const Main = (props: any) => { +type Props = { + selectedFilePath: string + removeFileFromTree: (path: string) => void +} + +const Main = (props: Props) => { const baseUrl = window.location.origin const [isLoading, setIsLoading] = useState(false) @@ -45,6 +50,7 @@ const Main = (props: any) => { .delete(`/SASjsApi/drive/file?_filePath=${filePath}`) .then((res) => { setFileContent('') + props.removeFileFromTree(filePath) window.history.pushState('', '', `${baseUrl}/#/SASjsDrive`) }) .catch((err) => { From 3d89b753f023beed4d51a64db4f74e1011437aab Mon Sep 17 00:00:00 2001 From: sabhas Date: Wed, 16 Mar 2022 19:13:50 +0000 Subject: [PATCH 3/3] feat(web): directory tree in sidebar of drive should be expanded by default at root level --- web/src/containers/Drive/sideBar.tsx | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/web/src/containers/Drive/sideBar.tsx b/web/src/containers/Drive/sideBar.tsx index db3d63d..6040bf2 100644 --- a/web/src/containers/Drive/sideBar.tsx +++ b/web/src/containers/Drive/sideBar.tsx @@ -68,12 +68,15 @@ const SideBar = ({ directoryData, handleSelect }: Props) => { > - } - defaultExpandIcon={} - > - {directoryData && renderTree(directoryData)} - + {directoryData && ( + } + defaultExpandIcon={} + defaultExpanded={[directoryData.relativePath]} + > + {renderTree(directoryData)} + + )} )