({
openPaths: state.openPaths,
togglePath: state.togglePath,
@@ -341,14 +352,16 @@ function FileNode({
hidden: !open && !node.isRoot,
})}
>
- {[...tmpNodes, ...node.children].map((node, idx) => (
-
-
-
- ))}
+ {allNodes.map((node, idx) => {
+ return (
+
+
+
+ )
+ })}
)}
diff --git a/packages/web-ui/src/sections/Document/Sidebar/Files/useNodeValidator/index.ts b/packages/web-ui/src/sections/Document/Sidebar/Files/useNodeValidator/index.ts
index 53223eb2a..590b21af4 100644
--- a/packages/web-ui/src/sections/Document/Sidebar/Files/useNodeValidator/index.ts
+++ b/packages/web-ui/src/sections/Document/Sidebar/Files/useNodeValidator/index.ts
@@ -78,6 +78,7 @@ export function useNodeValidator({
const onClickOutside = useCallback(async () => {
const val = inputRef.current?.value ?? ''
const value = val.trim()
+ setValue(value)
if (!value) {
leaveWithoutSave?.()
@@ -117,6 +118,6 @@ export function useNodeValidator({
onInputChange,
onInputKeyDown,
error: validationError,
- keepFocused: !value.trim(),
+ keepFocused: !value,
}
}
diff --git a/packages/web-ui/src/sections/Document/Sidebar/Files/useTempNodes/index.test.ts b/packages/web-ui/src/sections/Document/Sidebar/Files/useTempNodes/index.test.ts
index ea609dd54..f0a9c4b0f 100644
--- a/packages/web-ui/src/sections/Document/Sidebar/Files/useTempNodes/index.test.ts
+++ b/packages/web-ui/src/sections/Document/Sidebar/Files/useTempNodes/index.test.ts
@@ -11,7 +11,12 @@ describe('useTempNodes', () => {
it('should add a folder', async () => {
const { result } = renderHook(() => useTempNodes((state) => state))
- act(() => result.current.addFolder({ parentPath: 'some-folder' }))
+ act(() =>
+ result.current.addFolder({
+ parentPath: 'some-folder',
+ parentId: 'fake-id',
+ }),
+ )
expect(result.current.tmpFolders).toEqual({
'some-folder': [
@@ -27,7 +32,12 @@ describe('useTempNodes', () => {
it('should update a folder', async () => {
const { result } = renderHook(() => useTempNodes((state) => state))
- act(() => result.current.addFolder({ parentPath: 'some-folder' }))
+ act(() =>
+ result.current.addFolder({
+ parentPath: 'some-folder',
+ parentId: 'fake-id',
+ }),
+ )
const id = result?.current?.tmpFolders?.['some-folder']?.[0]?.id
act(() => result.current.updateFolder({ id: id!, path: 'new-name' }))
@@ -45,10 +55,62 @@ describe('useTempNodes', () => {
it('should delete a folder', async () => {
const { result } = renderHook(() => useTempNodes((state) => state))
- act(() => result.current.addFolder({ parentPath: 'some-folder' }))
+ act(() =>
+ result.current.addFolder({
+ parentPath: 'some-folder',
+ parentId: 'fake-id',
+ }),
+ )
const id = result?.current?.tmpFolders?.['some-folder']?.[0]?.id
act(() => result.current.deleteTmpFolder({ id: id! }))
expect(result.current.tmpFolders).toEqual({ 'some-folder': [] })
})
+
+ it.only('should update the parent folder children', async () => {
+ const { result } = renderHook(() => useTempNodes((state) => state))
+ act(() =>
+ result.current.addFolder({
+ parentPath: 'some-folder',
+ parentId: 'fake-id',
+ }),
+ )
+ const id = result?.current?.tmpFolders?.['some-folder']?.[0]?.id
+ act(() =>
+ result.current.updateFolder({ id: id!, path: 'parent-tmp-folder' }),
+ )
+
+ act(() =>
+ result.current.addFolder({
+ parentPath: 'some-folder/parent-tmp-folder',
+ parentId: id!,
+ }),
+ )
+
+ const childId =
+ result?.current?.tmpFolders?.['some-folder']?.[0]?.children?.[0]?.id
+
+ act(() =>
+ result.current.updateFolder({ id: childId!, path: 'child-tmp-folder' }),
+ )
+
+ expect(result.current.tmpFolders).toEqual({
+ 'some-folder': [
+ new Node({
+ id: expect.any(String),
+ path: 'some-folder/parent-tmp-folder',
+ name: 'parent-tmp-folder',
+ isPersisted: false,
+ children: [
+ new Node({
+ id: expect.any(String),
+ path: 'some-folder/parent-tmp-folder/child-tmp-folder',
+ name: 'child-tmp-folder',
+ isPersisted: false,
+ }),
+ ],
+ }),
+ ],
+ })
+ })
})
diff --git a/packages/web-ui/src/sections/Document/Sidebar/Files/useTempNodes/index.ts b/packages/web-ui/src/sections/Document/Sidebar/Files/useTempNodes/index.ts
index a9d0b70d7..2fe178bcc 100644
--- a/packages/web-ui/src/sections/Document/Sidebar/Files/useTempNodes/index.ts
+++ b/packages/web-ui/src/sections/Document/Sidebar/Files/useTempNodes/index.ts
@@ -4,14 +4,30 @@ import { defaultGenerateNodeUuid, Node } from '../useTree'
type OpenPathsState = {
tmpFolders: Record
- addFolder: (args: { parentPath: string }) => void
+ addFolder: (args: { parentPath: string; parentId: string }) => void
updateFolder: (args: { id: string; path: string }) => void
deleteTmpFolder: (args: { id: string }) => void
reset: () => void
}
+function nodeAndChildren(node: Node): Node[] {
+ return [node, ...node.children.flatMap(nodeAndChildren)]
+}
+
function allTmpNodes(tmpFolders: OpenPathsState['tmpFolders']) {
- return Object.values(tmpFolders).flatMap((nodes) => nodes)
+ return Object.values(tmpFolders)
+ .flatMap((nodes) => nodes.map(nodeAndChildren))
+ .flat()
+}
+
+function createEmptyNode({ parentPath }: { parentPath: string }) {
+ const emptyName = ' '
+ return new Node({
+ id: defaultGenerateNodeUuid(),
+ name: emptyName,
+ path: `${parentPath}/${emptyName}`,
+ isPersisted: false,
+ })
}
export const useTempNodes = create((set) => ({
@@ -21,16 +37,37 @@ export const useTempNodes = create((set) => ({
tmpFolders: {},
})
},
- addFolder: ({ parentPath }) => {
+ addFolder: ({ parentPath, parentId }) => {
set((state) => {
- const prevNodes = state.tmpFolders[parentPath]
- const emptyName = ' '
- const node = new Node({
- id: defaultGenerateNodeUuid(),
- name: emptyName,
- path: `${parentPath}/${emptyName}`,
- isPersisted: false,
+ const allNodes = allTmpNodes(state.tmpFolders)
+ const parentNode = allNodes.find((node) => node.id === parentId)
+
+ const node = createEmptyNode({
+ parentPath: parentNode ? parentNode.path : parentPath,
})
+
+ if (parentNode) {
+ parentNode.children = [node, ...parentNode.children]
+ const grandParentPath = parentNode.path
+ .split('/')
+ .slice(0, -1)
+ .join('/')
+ const grandParent = state.tmpFolders[grandParentPath]
+ if (!grandParent) return state
+ const idx = grandParent.findIndex((n) => n.id === parentId)
+ return {
+ tmpFolders: {
+ ...state.tmpFolders,
+ [grandParentPath]: [
+ ...grandParent.slice(0, idx),
+ parentNode,
+ ...grandParent.slice(idx + 1),
+ ],
+ },
+ }
+ }
+
+ const prevNodes = state.tmpFolders[parentPath]
return {
tmpFolders: {
...state.tmpFolders,
@@ -46,26 +83,11 @@ export const useTempNodes = create((set) => ({
if (!node) return state
const parentPath = node.path.split('/').slice(0, -1).join('/')
- const parent = state.tmpFolders[parentPath]
- if (!parent) return state
-
- const idx = parent.findIndex((n) => n.id === id)
- const existingNode = parent[idx]
- if (!existingNode) return state
+ node.name = path
+ node.path = `${parentPath}/${path}`
- existingNode.name = path
- existingNode.path = `${parentPath}/${path}`
- return {
- tmpFolders: {
- ...state.tmpFolders,
- [parentPath]: [
- ...parent.slice(0, idx),
- existingNode,
- ...parent.slice(idx + 1),
- ],
- },
- }
+ return state
})
},
deleteTmpFolder: ({ id }) => {