fix: renaming folders!
This commit is contained in:
@ -162,7 +162,7 @@ function RenameForm({
|
||||
function handleKeyDown(e: React.KeyboardEvent<HTMLInputElement>) {
|
||||
if (e.key === 'Escape') {
|
||||
e.stopPropagation()
|
||||
onSubmit(e)
|
||||
onSubmit()
|
||||
} else if (e.key === 'Enter') {
|
||||
// This is needed to prevent events to bubble up and the form to be submitted.
|
||||
// (Alternatively the form could be changed into a div.)
|
||||
@ -274,7 +274,7 @@ export const FileExplorerRowElement = ({
|
||||
onSubmit={(event) => {
|
||||
row.rowRenameEnd(event)
|
||||
}}
|
||||
></RenameForm>
|
||||
></RenameForm>
|
||||
)}
|
||||
<div className="ml-auto">{row.status}</div>
|
||||
<div style={{ width: '0.25rem' }}></div>
|
||||
|
||||
@ -18,6 +18,10 @@ import { useState, useRef, useEffect } from 'react'
|
||||
import { systemIOActor } from '@src/lib/singletons'
|
||||
import { SystemIOMachineEvents } from '@src/machines/systemIO/utils'
|
||||
import { sortFilesAndDirectories } from '@src/lib/desktopFS'
|
||||
import { joinOSPaths } from '@src/lib/paths'
|
||||
import {
|
||||
useProjectDirectoryPath,
|
||||
} from '@src/machines/systemIO/hooks'
|
||||
|
||||
const isFileExplorerEntryOpened = (
|
||||
rows: { [key: string]: boolean },
|
||||
@ -41,6 +45,8 @@ export const ProjectExplorer = ({
|
||||
}: {
|
||||
project: Project
|
||||
}) => {
|
||||
const projectDirectoryPath = useProjectDirectoryPath()
|
||||
|
||||
// cache the state of opened rows to allow nested rows to be opened if a parent one is closed
|
||||
// when the parent opens the children will already be opened
|
||||
const [openedRows, setOpenedRows] = useState<{ [key: string]: boolean }>({})
|
||||
@ -164,12 +170,31 @@ export const ProjectExplorer = ({
|
||||
},
|
||||
rowRenameEnd: (event) => {
|
||||
setIsRenaming(false)
|
||||
const requestedRename = String(event.target.value)
|
||||
const name = row.name
|
||||
|
||||
// if (requestedProjectName !== projectName) {
|
||||
// }
|
||||
}
|
||||
const requestedFolderName = String(event?.target?.value || '')
|
||||
if (!requestedFolderName) {
|
||||
// user pressed esc
|
||||
return
|
||||
}
|
||||
const folderName = row.name
|
||||
if (requestedFolderName !== folderName) {
|
||||
systemIOActor.send({type:SystemIOMachineEvents.renameFolder, data: {
|
||||
requestedFolderName,
|
||||
folderName,
|
||||
absolutePathToParentDirectory: joinOSPaths(projectDirectoryPath, child.parentPath)
|
||||
}})
|
||||
// TODO: Gotcha... Set new string open even if it fails?
|
||||
if (openedRowsRef.current[child.key]) {
|
||||
// If the file tree had the folder opened make the new one open.
|
||||
const newOpenedRows = { ...openedRowsRef.current }
|
||||
const key = constructPath({
|
||||
parentPath: child.parentPath,
|
||||
name: requestedFolderName
|
||||
})
|
||||
newOpenedRows[key] = true
|
||||
setOpenedRows(newOpenedRows)
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
return row
|
||||
|
||||
@ -140,7 +140,15 @@ export const systemIOMachine = setup({
|
||||
requestedProjectName: string
|
||||
requestedFileName: string
|
||||
}
|
||||
},
|
||||
}
|
||||
| {
|
||||
type: SystemIOMachineEvents.renameFolder
|
||||
data: {
|
||||
requestedFolderName: string
|
||||
folderName: string
|
||||
absolutePathToParentDirectory: string
|
||||
}
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
[SystemIOMachineActions.setFolders]: assign({
|
||||
@ -370,6 +378,21 @@ export const systemIOMachine = setup({
|
||||
return { message: '', fileName: '', projectName: '', subRoute: '' }
|
||||
}
|
||||
),
|
||||
[SystemIOMachineActors.renameFolder]: fromPromise(
|
||||
async ({
|
||||
input,
|
||||
}: {
|
||||
input: {
|
||||
context: SystemIOContext
|
||||
rootContext: AppMachineContext
|
||||
requestedFolderName: string
|
||||
folderName: string
|
||||
absolutePathToParentDirectory: string
|
||||
}
|
||||
}) => {
|
||||
return { message: '', folderName: '', requestedFolderName: '' }
|
||||
}
|
||||
),
|
||||
},
|
||||
}).createMachine({
|
||||
initial: SystemIOMachineStates.idle,
|
||||
@ -448,6 +471,9 @@ export const systemIOMachine = setup({
|
||||
[SystemIOMachineEvents.bulkCreateKCLFilesAndNavigateToFile]: {
|
||||
target: SystemIOMachineStates.bulkCreatingKCLFilesAndNavigateToFile,
|
||||
},
|
||||
[SystemIOMachineEvents.renameFolder]: {
|
||||
target: SystemIOMachineStates.renamingFolder,
|
||||
}
|
||||
},
|
||||
},
|
||||
[SystemIOMachineStates.readingFolders]: {
|
||||
@ -765,5 +791,28 @@ export const systemIOMachine = setup({
|
||||
},
|
||||
},
|
||||
},
|
||||
[SystemIOMachineStates.renamingFolder]: {
|
||||
invoke: {
|
||||
id: SystemIOMachineActors.renameFolder,
|
||||
src: SystemIOMachineActors.renameFolder,
|
||||
input: ({ context, event, self }) => {
|
||||
assertEvent(event, SystemIOMachineEvents.renameFolder)
|
||||
return {
|
||||
context,
|
||||
requestedFolderName: event.data.requestedFolderName,
|
||||
folderName: event.data.folderName,
|
||||
absolutePathToParentDirectory: event.data.absolutePathToParentDirectory,
|
||||
rootContext: self.system.get('root').getSnapshot().context,
|
||||
}
|
||||
},
|
||||
onDone: {
|
||||
target: SystemIOMachineStates.readingFolders,
|
||||
},
|
||||
onError: {
|
||||
target: SystemIOMachineStates.idle,
|
||||
actions: [SystemIOMachineActions.toastError],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
@ -398,5 +398,57 @@ export const systemIOMachineDesktop = systemIOMachine.provide({
|
||||
}
|
||||
}
|
||||
),
|
||||
[SystemIOMachineActors.renameFolder]: fromPromise(
|
||||
async ({
|
||||
input,
|
||||
}: {
|
||||
input: {
|
||||
context: SystemIOContext
|
||||
rootContext: AppMachineContext
|
||||
requestedFolderName: string
|
||||
folderName: string
|
||||
absolutePathToParentDirectory: string
|
||||
}
|
||||
}) => {
|
||||
|
||||
const { folderName, requestedFolderName, absolutePathToParentDirectory} = input
|
||||
const oldPath = window.electron.path.join(
|
||||
absolutePathToParentDirectory,
|
||||
folderName
|
||||
)
|
||||
const newPath = window.electron.path.join(
|
||||
absolutePathToParentDirectory,
|
||||
requestedFolderName
|
||||
)
|
||||
|
||||
// no-op
|
||||
if (oldPath === newPath) {
|
||||
return {
|
||||
message: `Old is the same as new.`,
|
||||
folderName,
|
||||
requestedFolderName,
|
||||
}
|
||||
}
|
||||
|
||||
// if there are any siblings with the same name, report error.
|
||||
const entries = await window.electron.readdir(
|
||||
window.electron.path.dirname(newPath)
|
||||
)
|
||||
|
||||
for (let entry of entries) {
|
||||
if (entry === requestedFolderName) {
|
||||
return Promise.reject(new Error('Filename already exists.'))
|
||||
}
|
||||
}
|
||||
|
||||
window.electron.rename(oldPath, newPath)
|
||||
|
||||
return {
|
||||
message:`Successfully renamed "${folderName}" to "${requestedFolderName}"`,
|
||||
folderName,
|
||||
requestedFolderName
|
||||
}
|
||||
}
|
||||
),
|
||||
},
|
||||
})
|
||||
|
||||
@ -16,6 +16,7 @@ export enum SystemIOMachineActors {
|
||||
bulkCreateKCLFiles = 'bulk create kcl files',
|
||||
bulkCreateKCLFilesAndNavigateToProject = 'bulk create kcl files and navigate to project',
|
||||
bulkCreateKCLFilesAndNavigateToFile = 'bulk create kcl files and navigate to file',
|
||||
renameFolder = 'renameFolder',
|
||||
}
|
||||
|
||||
export enum SystemIOMachineStates {
|
||||
@ -33,6 +34,7 @@ export enum SystemIOMachineStates {
|
||||
bulkCreatingKCLFiles = 'bulkCreatingKCLFiles',
|
||||
bulkCreatingKCLFilesAndNavigateToProject = 'bulkCreatingKCLFilesAndNavigateToProject',
|
||||
bulkCreatingKCLFilesAndNavigateToFile = 'bulkCreatingKCLFilesAndNavigateToFile',
|
||||
renamingFolder = 'renamingFolder',
|
||||
}
|
||||
|
||||
const donePrefix = 'xstate.done.actor.'
|
||||
@ -61,6 +63,7 @@ export enum SystemIOMachineEvents {
|
||||
bulkCreateKCLFilesAndNavigateToFile = 'bulk create kcl files and navigate to file',
|
||||
done_bulkCreateKCLFilesAndNavigateToFile = donePrefix +
|
||||
'bulk create kcl files and navigate to file',
|
||||
renameFolder = 'rename folder',
|
||||
}
|
||||
|
||||
export enum SystemIOMachineActions {
|
||||
|
||||
Reference in New Issue
Block a user