Add folder move functionality and update context menu
This commit is contained in:
58
src/App.tsx
58
src/App.tsx
@@ -25,6 +25,7 @@ import {
|
|||||||
listFolders,
|
listFolders,
|
||||||
listTexts,
|
listTexts,
|
||||||
listVersions,
|
listVersions,
|
||||||
|
moveFolder,
|
||||||
moveTextToFolder,
|
moveTextToFolder,
|
||||||
saveManualVersion,
|
saveManualVersion,
|
||||||
searchTexts,
|
searchTexts,
|
||||||
@@ -707,6 +708,18 @@ export default function App() {
|
|||||||
.sort((a, b) => a.label.localeCompare(b.label));
|
.sort((a, b) => a.label.localeCompare(b.label));
|
||||||
}, [buildFolderPath, folders]);
|
}, [buildFolderPath, folders]);
|
||||||
|
|
||||||
|
const isDescendantFolder = useCallback(
|
||||||
|
(folderId: string, potentialAncestorId: string) => {
|
||||||
|
let current: string | null = folderById.get(folderId)?.parent_id ?? null;
|
||||||
|
while (current) {
|
||||||
|
if (current === potentialAncestorId) return true;
|
||||||
|
current = folderById.get(current)?.parent_id ?? null;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
[folderById]
|
||||||
|
);
|
||||||
|
|
||||||
const handleMoveTextToFolder = useCallback(
|
const handleMoveTextToFolder = useCallback(
|
||||||
async (textId: string, folderId: string | null) => {
|
async (textId: string, folderId: string | null) => {
|
||||||
await moveTextToFolder(textId, folderId, null);
|
await moveTextToFolder(textId, folderId, null);
|
||||||
@@ -715,6 +728,21 @@ export default function App() {
|
|||||||
[refreshTexts]
|
[refreshTexts]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const handleMoveFolderToFolder = useCallback(
|
||||||
|
async (folderId: string, parentId: string | null) => {
|
||||||
|
await moveFolder(folderId, parentId, null);
|
||||||
|
await refreshFolders();
|
||||||
|
if (parentId) {
|
||||||
|
setExpandedFolders((prev) => {
|
||||||
|
const next = new Set(prev);
|
||||||
|
next.add(parentId);
|
||||||
|
return next;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[refreshFolders]
|
||||||
|
);
|
||||||
|
|
||||||
const handleDeleteText = useCallback(
|
const handleDeleteText = useCallback(
|
||||||
async (promptId: string) => {
|
async (promptId: string) => {
|
||||||
await deleteText(promptId);
|
await deleteText(promptId);
|
||||||
@@ -797,6 +825,30 @@ export default function App() {
|
|||||||
const handleFolderContextMenu = useCallback(
|
const handleFolderContextMenu = useCallback(
|
||||||
async (event: React.MouseEvent, folder: Folder) => {
|
async (event: React.MouseEvent, folder: Folder) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
const moveTargets = [
|
||||||
|
{
|
||||||
|
text: "Top level",
|
||||||
|
action: () => {
|
||||||
|
handleMoveFolderToFolder(folder.id, null).catch((error) => {
|
||||||
|
console.error("Failed to move folder", error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
...folderPathList
|
||||||
|
.filter(
|
||||||
|
(candidate) =>
|
||||||
|
candidate.id !== folder.id &&
|
||||||
|
!isDescendantFolder(candidate.id, folder.id)
|
||||||
|
)
|
||||||
|
.map((candidate) => ({
|
||||||
|
text: candidate.label,
|
||||||
|
action: () => {
|
||||||
|
handleMoveFolderToFolder(folder.id, candidate.id).catch((error) => {
|
||||||
|
console.error("Failed to move folder", error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
];
|
||||||
const menu = await Menu.new({
|
const menu = await Menu.new({
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@@ -814,12 +866,16 @@ export default function App() {
|
|||||||
onConfirm: () => handleDeleteFolder(folder.id)
|
onConfirm: () => handleDeleteFolder(folder.id)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Move to folder",
|
||||||
|
items: moveTargets
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
await menu.popup(undefined, getCurrentWindow());
|
await menu.popup(undefined, getCurrentWindow());
|
||||||
},
|
},
|
||||||
[handleDeleteFolder, startEditingFolder]
|
[folderPathList, handleDeleteFolder, handleMoveFolderToFolder, isDescendantFolder, startEditingFolder]
|
||||||
);
|
);
|
||||||
|
|
||||||
const createTextFromFile = useCallback(
|
const createTextFromFile = useCallback(
|
||||||
|
|||||||
Reference in New Issue
Block a user