mirror of
https://github.com/sasjs/server.git
synced 2025-12-11 19:44:35 +00:00
feat: implemented delete file/folder functionality
This commit is contained in:
@@ -3,12 +3,15 @@ import { Menu, MenuItem } from '@mui/material'
|
|||||||
import ExpandMoreIcon from '@mui/icons-material/ExpandMore'
|
import ExpandMoreIcon from '@mui/icons-material/ExpandMore'
|
||||||
import ChevronRightIcon from '@mui/icons-material/ChevronRight'
|
import ChevronRightIcon from '@mui/icons-material/ChevronRight'
|
||||||
|
|
||||||
|
import DeleteConfirmationModal from './deleteConfirmationModal'
|
||||||
|
|
||||||
import { TreeNode } from '../utils/types'
|
import { TreeNode } from '../utils/types'
|
||||||
|
|
||||||
type TreeViewProps = {
|
type Props = {
|
||||||
node: TreeNode
|
node: TreeNode
|
||||||
selectedFilePath: string
|
selectedFilePath: string
|
||||||
handleSelect: (filePath: string) => void
|
handleSelect: (filePath: string) => void
|
||||||
|
deleteNode: (path: string, isFolder: boolean) => void
|
||||||
defaultExpanded?: string[]
|
defaultExpanded?: string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -16,8 +19,9 @@ const TreeView = ({
|
|||||||
node,
|
node,
|
||||||
selectedFilePath,
|
selectedFilePath,
|
||||||
handleSelect,
|
handleSelect,
|
||||||
|
deleteNode,
|
||||||
defaultExpanded
|
defaultExpanded
|
||||||
}: TreeViewProps) => {
|
}: Props) => {
|
||||||
return (
|
return (
|
||||||
<ul
|
<ul
|
||||||
style={{
|
style={{
|
||||||
@@ -30,6 +34,7 @@ const TreeView = ({
|
|||||||
node={node}
|
node={node}
|
||||||
selectedFilePath={selectedFilePath}
|
selectedFilePath={selectedFilePath}
|
||||||
handleSelect={handleSelect}
|
handleSelect={handleSelect}
|
||||||
|
deleteNode={deleteNode}
|
||||||
defaultExpanded={defaultExpanded}
|
defaultExpanded={defaultExpanded}
|
||||||
/>
|
/>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -38,19 +43,17 @@ const TreeView = ({
|
|||||||
|
|
||||||
export default TreeView
|
export default TreeView
|
||||||
|
|
||||||
type TreeViewNodeProps = {
|
|
||||||
node: TreeNode
|
|
||||||
selectedFilePath: string
|
|
||||||
handleSelect: (filePath: string) => void
|
|
||||||
defaultExpanded?: string[]
|
|
||||||
}
|
|
||||||
|
|
||||||
const TreeViewNode = ({
|
const TreeViewNode = ({
|
||||||
node,
|
node,
|
||||||
selectedFilePath,
|
selectedFilePath,
|
||||||
handleSelect,
|
handleSelect,
|
||||||
|
deleteNode,
|
||||||
defaultExpanded
|
defaultExpanded
|
||||||
}: TreeViewNodeProps) => {
|
}: Props) => {
|
||||||
|
const [deleteConfirmationModalOpen, setDeleteConfirmationModalOpen] =
|
||||||
|
useState(false)
|
||||||
|
const [deleteConfirmationModalMessage, setDeleteConfirmationModalMessage] =
|
||||||
|
useState('')
|
||||||
const [childVisible, setChildVisibility] = useState(false)
|
const [childVisible, setChildVisibility] = useState(false)
|
||||||
const [contextMenu, setContextMenu] = useState<{
|
const [contextMenu, setContextMenu] = useState<{
|
||||||
mouseX: number
|
mouseX: number
|
||||||
@@ -90,6 +93,21 @@ const TreeViewNode = ({
|
|||||||
}
|
}
|
||||||
}, [defaultExpanded, node.relativePath])
|
}, [defaultExpanded, node.relativePath])
|
||||||
|
|
||||||
|
const handleDeleteItemClick = () => {
|
||||||
|
setContextMenu(null)
|
||||||
|
setDeleteConfirmationModalOpen(true)
|
||||||
|
setDeleteConfirmationModalMessage(
|
||||||
|
`Are you sure you want to delete ${node.isFolder ? 'folder' : 'file'} "${
|
||||||
|
node.relativePath
|
||||||
|
}"?`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const deleteConfirm = () => {
|
||||||
|
setDeleteConfirmationModalOpen(false)
|
||||||
|
deleteNode(node.relativePath, node.isFolder)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div onContextMenu={handleContextMenu} style={{ cursor: 'context-menu' }}>
|
<div onContextMenu={handleContextMenu} style={{ cursor: 'context-menu' }}>
|
||||||
<li style={{ display: 'list-item' }}>
|
<li style={{ display: 'list-item' }}>
|
||||||
@@ -112,10 +130,17 @@ const TreeViewNode = ({
|
|||||||
node={child}
|
node={child}
|
||||||
selectedFilePath={selectedFilePath}
|
selectedFilePath={selectedFilePath}
|
||||||
handleSelect={handleSelect}
|
handleSelect={handleSelect}
|
||||||
|
deleteNode={deleteNode}
|
||||||
defaultExpanded={defaultExpanded}
|
defaultExpanded={defaultExpanded}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</li>
|
</li>
|
||||||
|
<DeleteConfirmationModal
|
||||||
|
open={deleteConfirmationModalOpen}
|
||||||
|
setOpen={setDeleteConfirmationModalOpen}
|
||||||
|
message={deleteConfirmationModalMessage}
|
||||||
|
_delete={deleteConfirm}
|
||||||
|
/>
|
||||||
<Menu
|
<Menu
|
||||||
open={contextMenu !== null}
|
open={contextMenu !== null}
|
||||||
onClose={() => setContextMenu(null)}
|
onClose={() => setContextMenu(null)}
|
||||||
@@ -131,7 +156,9 @@ const TreeViewNode = ({
|
|||||||
<MenuItem key={item}>{item}</MenuItem>
|
<MenuItem key={item}>{item}</MenuItem>
|
||||||
))}
|
))}
|
||||||
<MenuItem>Rename</MenuItem>
|
<MenuItem>Rename</MenuItem>
|
||||||
<MenuItem>Delete</MenuItem>
|
<MenuItem disabled={!node.relativePath} onClick={handleDeleteItemClick}>
|
||||||
|
Delete
|
||||||
|
</MenuItem>
|
||||||
</Menu>
|
</Menu>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -107,6 +107,8 @@ const SASjsEditor = ({
|
|||||||
setOpenModal(true)
|
setOpenModal(true)
|
||||||
})
|
})
|
||||||
.finally(() => setIsLoading(false))
|
.finally(() => setIsLoading(false))
|
||||||
|
} else {
|
||||||
|
setFileContent('')
|
||||||
}
|
}
|
||||||
}, [selectedFilePath])
|
}, [selectedFilePath])
|
||||||
|
|
||||||
|
|||||||
@@ -56,6 +56,12 @@ const Studio = () => {
|
|||||||
) => {
|
) => {
|
||||||
if (node.relativePath === path) {
|
if (node.relativePath === path) {
|
||||||
removeNodeFromParent(parentNode, path)
|
removeNodeFromParent(parentNode, path)
|
||||||
|
// reset selected file path and file path query param
|
||||||
|
if (
|
||||||
|
node.relativePath === selectedFilePath ||
|
||||||
|
selectedFilePath.startsWith(node.relativePath)
|
||||||
|
)
|
||||||
|
setSearchParams({})
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if (Array.isArray(node.children)) {
|
if (Array.isArray(node.children)) {
|
||||||
@@ -81,6 +87,7 @@ const Studio = () => {
|
|||||||
selectedFilePath={selectedFilePath}
|
selectedFilePath={selectedFilePath}
|
||||||
directoryData={directoryData}
|
directoryData={directoryData}
|
||||||
handleSelect={handleSelect}
|
handleSelect={handleSelect}
|
||||||
|
removeFileFromTree={removeFileFromTree}
|
||||||
/>
|
/>
|
||||||
<SASjsEditor
|
<SASjsEditor
|
||||||
selectedFilePath={selectedFilePath}
|
selectedFilePath={selectedFilePath}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React, { useMemo } from 'react'
|
import React, { useMemo } from 'react'
|
||||||
|
import axios from 'axios'
|
||||||
import { Box, Drawer, Toolbar } from '@mui/material'
|
import { Box, Drawer, Toolbar } from '@mui/material'
|
||||||
|
|
||||||
import TreeView from '../../components/tree'
|
import TreeView from '../../components/tree'
|
||||||
@@ -11,9 +11,15 @@ type Props = {
|
|||||||
selectedFilePath: string
|
selectedFilePath: string
|
||||||
directoryData: TreeNode | null
|
directoryData: TreeNode | null
|
||||||
handleSelect: (filePath: string) => void
|
handleSelect: (filePath: string) => void
|
||||||
|
removeFileFromTree: (filePath: string) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const SideBar = ({ selectedFilePath, directoryData, handleSelect }: Props) => {
|
const SideBar = ({
|
||||||
|
selectedFilePath,
|
||||||
|
directoryData,
|
||||||
|
handleSelect,
|
||||||
|
removeFileFromTree
|
||||||
|
}: Props) => {
|
||||||
const defaultExpanded = useMemo(() => {
|
const defaultExpanded = useMemo(() => {
|
||||||
const splittedPath = selectedFilePath.split('/')
|
const splittedPath = selectedFilePath.split('/')
|
||||||
const arr = ['']
|
const arr = ['']
|
||||||
@@ -27,6 +33,20 @@ const SideBar = ({ selectedFilePath, directoryData, handleSelect }: Props) => {
|
|||||||
return arr
|
return arr
|
||||||
}, [selectedFilePath])
|
}, [selectedFilePath])
|
||||||
|
|
||||||
|
const deleteNode = (path: string, isFolder: boolean) => {
|
||||||
|
const axiosPromise = axios.delete(
|
||||||
|
`/SASjsApi/drive/${
|
||||||
|
isFolder ? `folder?_folderPath=${path}` : `file?_filePath=${path}`
|
||||||
|
}`
|
||||||
|
)
|
||||||
|
|
||||||
|
axiosPromise
|
||||||
|
.then(() => removeFileFromTree(path))
|
||||||
|
.catch((err) => {
|
||||||
|
console.log(err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Drawer
|
<Drawer
|
||||||
variant="permanent"
|
variant="permanent"
|
||||||
@@ -43,6 +63,7 @@ const SideBar = ({ selectedFilePath, directoryData, handleSelect }: Props) => {
|
|||||||
node={directoryData}
|
node={directoryData}
|
||||||
selectedFilePath={selectedFilePath}
|
selectedFilePath={selectedFilePath}
|
||||||
handleSelect={handleSelect}
|
handleSelect={handleSelect}
|
||||||
|
deleteNode={deleteNode}
|
||||||
defaultExpanded={defaultExpanded}
|
defaultExpanded={defaultExpanded}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user