mirror of
https://github.com/sasjs/server.git
synced 2025-12-12 03:54:34 +00:00
feat: implemented the functionality for renaming file/folder from context menu
This commit is contained in:
@@ -8,15 +8,19 @@ import { BootstrapDialog } from './modal'
|
|||||||
type NameInputModalProps = {
|
type NameInputModalProps = {
|
||||||
open: boolean
|
open: boolean
|
||||||
setOpen: React.Dispatch<React.SetStateAction<boolean>>
|
setOpen: React.Dispatch<React.SetStateAction<boolean>>
|
||||||
|
title: string
|
||||||
isFolder: boolean
|
isFolder: boolean
|
||||||
add: (name: string) => void
|
actionLabel: string
|
||||||
|
action: (name: string) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const NameInputModal = ({
|
const NameInputModal = ({
|
||||||
open,
|
open,
|
||||||
setOpen,
|
setOpen,
|
||||||
|
title,
|
||||||
isFolder,
|
isFolder,
|
||||||
add
|
actionLabel,
|
||||||
|
action
|
||||||
}: NameInputModalProps) => {
|
}: NameInputModalProps) => {
|
||||||
const [name, setName] = useState('')
|
const [name, setName] = useState('')
|
||||||
const [hasError, setHasError] = useState(false)
|
const [hasError, setHasError] = useState(false)
|
||||||
@@ -48,7 +52,7 @@ const NameInputModal = ({
|
|||||||
return (
|
return (
|
||||||
<BootstrapDialog fullWidth onClose={() => setOpen(false)} open={open}>
|
<BootstrapDialog fullWidth onClose={() => setOpen(false)} open={open}>
|
||||||
<BootstrapDialogTitle id="abort-modal" handleOpen={setOpen}>
|
<BootstrapDialogTitle id="abort-modal" handleOpen={setOpen}>
|
||||||
{isFolder ? 'Add Folder' : 'Add File'}
|
{title}
|
||||||
</BootstrapDialogTitle>
|
</BootstrapDialogTitle>
|
||||||
<DialogContent dividers>
|
<DialogContent dividers>
|
||||||
<TextField
|
<TextField
|
||||||
@@ -68,11 +72,11 @@ const NameInputModal = ({
|
|||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
add(name)
|
action(name)
|
||||||
}}
|
}}
|
||||||
disabled={hasError || !name}
|
disabled={hasError || !name}
|
||||||
>
|
>
|
||||||
Add
|
{actionLabel}
|
||||||
</Button>
|
</Button>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
</BootstrapDialog>
|
</BootstrapDialog>
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ type Props = {
|
|||||||
deleteNode: (path: string, isFolder: boolean) => void
|
deleteNode: (path: string, isFolder: boolean) => void
|
||||||
addFile: (path: string) => void
|
addFile: (path: string) => void
|
||||||
addFolder: (path: string) => void
|
addFolder: (path: string) => void
|
||||||
|
rename: (oldPath: string, newPath: string) => void
|
||||||
defaultExpanded?: string[]
|
defaultExpanded?: string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,6 +26,7 @@ const TreeView = ({
|
|||||||
deleteNode,
|
deleteNode,
|
||||||
addFile,
|
addFile,
|
||||||
addFolder,
|
addFolder,
|
||||||
|
rename,
|
||||||
defaultExpanded
|
defaultExpanded
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
return (
|
return (
|
||||||
@@ -42,6 +44,7 @@ const TreeView = ({
|
|||||||
deleteNode={deleteNode}
|
deleteNode={deleteNode}
|
||||||
addFile={addFile}
|
addFile={addFile}
|
||||||
addFolder={addFolder}
|
addFolder={addFolder}
|
||||||
|
rename={rename}
|
||||||
defaultExpanded={defaultExpanded}
|
defaultExpanded={defaultExpanded}
|
||||||
/>
|
/>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -57,6 +60,7 @@ const TreeViewNode = ({
|
|||||||
deleteNode,
|
deleteNode,
|
||||||
addFile,
|
addFile,
|
||||||
addFolder,
|
addFolder,
|
||||||
|
rename,
|
||||||
defaultExpanded
|
defaultExpanded
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
const [deleteConfirmationModalOpen, setDeleteConfirmationModalOpen] =
|
const [deleteConfirmationModalOpen, setDeleteConfirmationModalOpen] =
|
||||||
@@ -64,6 +68,8 @@ const TreeViewNode = ({
|
|||||||
const [deleteConfirmationModalMessage, setDeleteConfirmationModalMessage] =
|
const [deleteConfirmationModalMessage, setDeleteConfirmationModalMessage] =
|
||||||
useState('')
|
useState('')
|
||||||
const [nameInputModalOpen, setNameInputModalOpen] = useState(false)
|
const [nameInputModalOpen, setNameInputModalOpen] = useState(false)
|
||||||
|
const [nameInputModalTitle, setNameInputModalTitle] = useState('')
|
||||||
|
const [nameInputModalActionLabel, setNameInputModalActionLabel] = useState('')
|
||||||
const [nameInputModalForFolder, setNameInputModalForFolder] = useState(false)
|
const [nameInputModalForFolder, setNameInputModalForFolder] = useState(false)
|
||||||
const [childVisible, setChildVisibility] = useState(false)
|
const [childVisible, setChildVisibility] = useState(false)
|
||||||
const [contextMenu, setContextMenu] = useState<{
|
const [contextMenu, setContextMenu] = useState<{
|
||||||
@@ -122,12 +128,16 @@ const TreeViewNode = ({
|
|||||||
const handleNewFolderItemClick = () => {
|
const handleNewFolderItemClick = () => {
|
||||||
setContextMenu(null)
|
setContextMenu(null)
|
||||||
setNameInputModalOpen(true)
|
setNameInputModalOpen(true)
|
||||||
|
setNameInputModalTitle('Add Folder')
|
||||||
|
setNameInputModalActionLabel('Add')
|
||||||
setNameInputModalForFolder(true)
|
setNameInputModalForFolder(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleNewFileItemClick = () => {
|
const handleNewFileItemClick = () => {
|
||||||
setContextMenu(null)
|
setContextMenu(null)
|
||||||
setNameInputModalOpen(true)
|
setNameInputModalOpen(true)
|
||||||
|
setNameInputModalTitle('Add File')
|
||||||
|
setNameInputModalActionLabel('Add')
|
||||||
setNameInputModalForFolder(false)
|
setNameInputModalForFolder(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,6 +148,23 @@ const TreeViewNode = ({
|
|||||||
else addFile(path)
|
else addFile(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleRenameItemClick = () => {
|
||||||
|
setContextMenu(null)
|
||||||
|
setNameInputModalOpen(true)
|
||||||
|
setNameInputModalTitle('Rename')
|
||||||
|
setNameInputModalActionLabel('Rename')
|
||||||
|
setNameInputModalForFolder(node.isFolder)
|
||||||
|
}
|
||||||
|
|
||||||
|
const renameFileFolder = (name: string) => {
|
||||||
|
setNameInputModalOpen(false)
|
||||||
|
const oldPath = node.relativePath
|
||||||
|
const splittedPath = node.relativePath.split('/')
|
||||||
|
splittedPath.splice(-1, 1, name)
|
||||||
|
const newPath = splittedPath.join('/')
|
||||||
|
rename(oldPath, newPath)
|
||||||
|
}
|
||||||
|
|
||||||
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' }}>
|
||||||
@@ -163,6 +190,7 @@ const TreeViewNode = ({
|
|||||||
deleteNode={deleteNode}
|
deleteNode={deleteNode}
|
||||||
addFile={addFile}
|
addFile={addFile}
|
||||||
addFolder={addFolder}
|
addFolder={addFolder}
|
||||||
|
rename={rename}
|
||||||
defaultExpanded={defaultExpanded}
|
defaultExpanded={defaultExpanded}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
@@ -176,8 +204,12 @@ const TreeViewNode = ({
|
|||||||
<NameInputModal
|
<NameInputModal
|
||||||
open={nameInputModalOpen}
|
open={nameInputModalOpen}
|
||||||
setOpen={setNameInputModalOpen}
|
setOpen={setNameInputModalOpen}
|
||||||
|
title={nameInputModalTitle}
|
||||||
isFolder={nameInputModalForFolder}
|
isFolder={nameInputModalForFolder}
|
||||||
add={addFileFolder}
|
actionLabel={nameInputModalActionLabel}
|
||||||
|
action={
|
||||||
|
nameInputModalActionLabel === 'Add' ? addFileFolder : renameFileFolder
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
<Menu
|
<Menu
|
||||||
open={contextMenu !== null}
|
open={contextMenu !== null}
|
||||||
@@ -202,7 +234,9 @@ const TreeViewNode = ({
|
|||||||
{item}
|
{item}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
))}
|
))}
|
||||||
<MenuItem>Rename</MenuItem>
|
<MenuItem disabled={!node.relativePath} onClick={handleRenameItemClick}>
|
||||||
|
Rename
|
||||||
|
</MenuItem>
|
||||||
<MenuItem disabled={!node.relativePath} onClick={handleDeleteItemClick}>
|
<MenuItem disabled={!node.relativePath} onClick={handleDeleteItemClick}>
|
||||||
Delete
|
Delete
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
|||||||
@@ -122,6 +122,31 @@ const SideBar = ({
|
|||||||
.finally(() => setIsLoading(false))
|
.finally(() => setIsLoading(false))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const rename = (oldPath: string, newPath: string) => {
|
||||||
|
setIsLoading(true)
|
||||||
|
axios
|
||||||
|
.post('/SASjsApi/drive/rename', { oldPath, newPath })
|
||||||
|
.then(() => {
|
||||||
|
setSnackbarMessage('Successfully Renamed')
|
||||||
|
setSnackbarSeverity(AlertSeverityType.Success)
|
||||||
|
setOpenSnackbar(true)
|
||||||
|
if (oldPath === selectedFilePath) handleSelect(newPath)
|
||||||
|
else if (selectedFilePath.startsWith(oldPath))
|
||||||
|
handleSelect(selectedFilePath.replace(oldPath, newPath))
|
||||||
|
refreshSideBar()
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
setModalTitle('Abort')
|
||||||
|
setModalPayload(
|
||||||
|
typeof err.response.data === 'object'
|
||||||
|
? JSON.stringify(err.response.data)
|
||||||
|
: err.response.data
|
||||||
|
)
|
||||||
|
setOpenModal(true)
|
||||||
|
})
|
||||||
|
.finally(() => setIsLoading(false))
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Drawer
|
<Drawer
|
||||||
variant="permanent"
|
variant="permanent"
|
||||||
@@ -147,6 +172,7 @@ const SideBar = ({
|
|||||||
deleteNode={deleteNode}
|
deleteNode={deleteNode}
|
||||||
addFile={addFile}
|
addFile={addFile}
|
||||||
addFolder={addFolder}
|
addFolder={addFolder}
|
||||||
|
rename={rename}
|
||||||
defaultExpanded={defaultExpanded}
|
defaultExpanded={defaultExpanded}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user