diff --git a/src/App.tsx b/src/App.tsx index 478efd6..1048209 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1226,56 +1226,529 @@ export default function App() { />
-
- {loadingTexts ? ( -
Loading texts…
- ) : texts.length === 0 ? ( +
{ + event.preventDefault(); + }} + onDrop={handleRootDrop} + > + {loadingTexts || loadingFolders ? ( +
Loading…
+ ) : texts.length === 0 && folders.length === 0 ? (
No texts yet.
) : ( - texts.map((text) => ( -
setSelectedTextId(text.id)} - role="button" - tabIndex={0} - onKeyDown={(event) => { - if (event.key === "Enter" || event.key === " ") { - event.preventDefault(); - setSelectedTextId(text.id); - } - }} - > -
-
{text.title}
-
- Updated {formatDate(text.updated_at)} -
-
- +
{folder.name}
+
+ {expanded ? ( +
+ {childFolders + .filter((child) => !hasSearch || visibleFolderIds?.has(child.id)) + .map((child) => { + const childExpanded = isFolderExpanded(child.id); + const nestedFolders = foldersByParent.get(child.id) ?? []; + const nestedTexts = textsByFolder.get(child.id) ?? []; + return ( +
+
handleDragStartFolder(event, child)} + onDragEnd={handleDragEnd} + onDragOver={(event) => event.preventDefault()} + onDrop={(event) => handleFolderDrop(event, child)} + onClick={() => toggleFolderExpanded(child.id)} + > + +
{child.name}
+
+ {childExpanded ? ( +
+ {nestedFolders + .filter( + (nested) => + !hasSearch || visibleFolderIds?.has(nested.id) + ) + .map((nested) => ( +
+
+ handleDragStartFolder(event, nested) + } + onDragEnd={handleDragEnd} + onDragOver={(event) => event.preventDefault()} + onDrop={(event) => handleFolderDrop(event, nested)} + onClick={() => toggleFolderExpanded(nested.id)} + > + +
+ {nested.name} +
+
+ {isFolderExpanded(nested.id) ? ( +
+ {(foldersByParent.get(nested.id) ?? []) + .filter( + (nestedChild) => + !hasSearch || + visibleFolderIds?.has(nestedChild.id) + ) + .map((nestedChild) => ( +
+
+ handleDragStartFolder(event, nestedChild) + } + onDragEnd={handleDragEnd} + onDragOver={(event) => event.preventDefault()} + onDrop={(event) => + handleFolderDrop(event, nestedChild) + } + onClick={() => toggleFolderExpanded(nestedChild.id)} + > + +
+ {nestedChild.name} +
+
+ {isFolderExpanded(nestedChild.id) ? ( +
+ {(foldersByParent.get(nestedChild.id) ?? []) + .filter( + (deepChild) => + !hasSearch || + visibleFolderIds?.has(deepChild.id) + ) + .map((deepChild) => ( +
+
+ handleDragStartFolder(event, deepChild) + } + onDragEnd={handleDragEnd} + onDragOver={(event) => event.preventDefault()} + onDrop={(event) => + handleFolderDrop(event, deepChild) + } + onClick={() => + toggleFolderExpanded(deepChild.id) + } + > + +
+ {deepChild.name} +
+
+ {isFolderExpanded(deepChild.id) ? ( +
+ {(textsByFolder.get(deepChild.id) ?? []).map( + (text) => ( +
+ handleDragStartText(event, text) + } + onDragEnd={handleDragEnd} + onDragOver={(event) => + event.preventDefault() + } + onDrop={(event) => + handleTextDrop( + event, + text.id, + text.folder_id ?? null + ) + } + onClick={() => + setSelectedTextId(text.id) + } + onContextMenu={(event) => + handleTextContextMenu(event, text.id) + } + > +
+
+ {text.title} +
+
+ Updated {formatDate(text.updated_at)} +
+
+ +
+ ) + )} +
+ ) : null} +
+ ))} + {(textsByFolder.get(nestedChild.id) ?? []).map( + (text) => ( +
+ handleDragStartText(event, text) + } + onDragEnd={handleDragEnd} + onDragOver={(event) => event.preventDefault()} + onDrop={(event) => + handleTextDrop( + event, + text.id, + text.folder_id ?? null + ) + } + onClick={() => setSelectedTextId(text.id)} + onContextMenu={(event) => + handleTextContextMenu(event, text.id) + } + > +
+
+ {text.title} +
+
+ Updated {formatDate(text.updated_at)} +
+
+ +
+ ) + )} +
+ ) : null} +
+ ))} + {(textsByFolder.get(nested.id) ?? []).map((text) => ( +
handleDragStartText(event, text)} + onDragEnd={handleDragEnd} + onDragOver={(event) => event.preventDefault()} + onDrop={(event) => + handleTextDrop( + event, + text.id, + text.folder_id ?? null + ) + } + onClick={() => setSelectedTextId(text.id)} + onContextMenu={(event) => + handleTextContextMenu(event, text.id) + } + > +
+
{text.title}
+
+ Updated {formatDate(text.updated_at)} +
+
+ +
+ ))} +
+ ) : null} +
+ ))} + {nestedTexts.map((text) => ( +
handleDragStartText(event, text)} + onDragEnd={handleDragEnd} + onDragOver={(event) => event.preventDefault()} + onDrop={(event) => + handleTextDrop( + event, + text.id, + text.folder_id ?? null + ) + } + onClick={() => setSelectedTextId(text.id)} + onContextMenu={(event) => + handleTextContextMenu(event, text.id) + } + > +
+
{text.title}
+
+ Updated {formatDate(text.updated_at)} +
+
+ +
+ ))} +
+ ) : null} +
+ ); + })} + {childTexts.map((text) => ( +
handleDragStartText(event, text)} + onDragEnd={handleDragEnd} + onDragOver={(event) => event.preventDefault()} + onDrop={(event) => + handleTextDrop(event, text.id, text.folder_id ?? null) + } + onClick={() => setSelectedTextId(text.id)} + onContextMenu={(event) => handleTextContextMenu(event, text.id)} + > +
+
{text.title}
+
+ Updated {formatDate(text.updated_at)} +
+
+ +
+ ))} +
+ ) : null} +
+ ); + })} + {(textsByFolder.get(null) ?? []).map((text) => ( +
handleDragStartText(event, text)} + onDragEnd={handleDragEnd} + onDragOver={(event) => event.preventDefault()} + onDrop={(event) => handleTextDrop(event, text.id, text.folder_id ?? null)} + onClick={() => setSelectedTextId(text.id)} + onContextMenu={(event) => handleTextContextMenu(event, text.id)} > - × - -
- )) +
+
{text.title}
+
Updated {formatDate(text.updated_at)}
+
+ +
+ ))} + )}
+