rename directory entries
This commit is contained in:
@@ -4,13 +4,14 @@ import {
|
||||
ContextMenuTrigger,
|
||||
ContextMenuContent,
|
||||
ContextMenuItem,
|
||||
ContextMenuSeparator,
|
||||
} from '@/components/ui/context-menu';
|
||||
import { deleteWarrenDirectory, deleteWarrenFile } from '~/lib/api/warrens';
|
||||
import type { DirectoryEntry } from '~/types';
|
||||
import { buttonVariants } from '@/components/ui/button';
|
||||
|
||||
const route = useRoute();
|
||||
const warrenRoute = useWarrenRoute();
|
||||
const renameDialog = useRenameDirectoryDialog();
|
||||
|
||||
const { entry, disabled } = defineProps<{
|
||||
entry: DirectoryEntry;
|
||||
@@ -30,6 +31,10 @@ async function submitDelete(force: boolean = false) {
|
||||
|
||||
deleting.value = false;
|
||||
}
|
||||
|
||||
async function openRenameDialog() {
|
||||
renameDialog.openDialog(entry);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -62,6 +67,13 @@ async function submitDelete(force: boolean = false) {
|
||||
</NuxtLink>
|
||||
</ContextMenuTrigger>
|
||||
<ContextMenuContent>
|
||||
<ContextMenuItem @select="openRenameDialog">
|
||||
<Icon name="lucide:pencil" />
|
||||
Rename
|
||||
</ContextMenuItem>
|
||||
|
||||
<ContextMenuSeparator />
|
||||
|
||||
<ContextMenuItem @select="() => submitDelete(false)">
|
||||
<Icon name="lucide:trash-2" />
|
||||
Delete
|
||||
|
||||
@@ -14,24 +14,17 @@ const warrenRoute = useWarrenRoute();
|
||||
const dialog = useCreateDirectoryDialog();
|
||||
|
||||
const creating = ref(false);
|
||||
const directoryName = ref('');
|
||||
const directoryNameValid = computed(
|
||||
() => directoryName.value.trim().length > 0
|
||||
);
|
||||
const directoryNameValid = computed(() => dialog.value.trim().length > 0);
|
||||
|
||||
async function submit() {
|
||||
creating.value = true;
|
||||
|
||||
const { success } = await createDirectory(
|
||||
warrenRoute.value,
|
||||
directoryName.value
|
||||
);
|
||||
const { success } = await createDirectory(warrenRoute.value, dialog.value);
|
||||
|
||||
creating.value = false;
|
||||
|
||||
if (success) {
|
||||
directoryName.value = '';
|
||||
dialog.open = false;
|
||||
dialog.reset();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -50,7 +43,7 @@ async function submit() {
|
||||
</DialogHeader>
|
||||
|
||||
<Input
|
||||
v-model="directoryName"
|
||||
v-model="dialog.value"
|
||||
type="text"
|
||||
name="directory-name"
|
||||
placeholder="my-awesome-directory"
|
||||
|
||||
68
frontend/components/actions/RenameEntryDialog.vue
Normal file
68
frontend/components/actions/RenameEntryDialog.vue
Normal file
@@ -0,0 +1,68 @@
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
} from '@/components/ui/dialog';
|
||||
import { renameWarrenEntry } from '~/lib/api/warrens';
|
||||
|
||||
const warrenRoute = useWarrenRoute();
|
||||
const dialog = useRenameDirectoryDialog();
|
||||
|
||||
const renaming = ref(false);
|
||||
const directoryNameValid = computed(() => dialog.value.trim().length > 0);
|
||||
|
||||
async function submit() {
|
||||
if (dialog.entry == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
renaming.value = true;
|
||||
|
||||
const { success } = await renameWarrenEntry(
|
||||
warrenRoute.value,
|
||||
dialog.entry.name,
|
||||
dialog.value
|
||||
);
|
||||
|
||||
renaming.value = false;
|
||||
|
||||
if (success) {
|
||||
dialog.reset();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Dialog v-model:open="dialog.open">
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>Rename your directory</DialogTitle>
|
||||
<DialogDescription
|
||||
>Give your directory a new memorable name</DialogDescription
|
||||
>
|
||||
</DialogHeader>
|
||||
|
||||
<Input
|
||||
v-model="dialog.value"
|
||||
type="text"
|
||||
name="directory-name"
|
||||
placeholder="my-awesome-directory"
|
||||
aria-required="true"
|
||||
autocomplete="off"
|
||||
required
|
||||
/>
|
||||
|
||||
<DialogFooter>
|
||||
<Button
|
||||
:disabled="!directoryNameValid || renaming"
|
||||
@click="submit"
|
||||
>Rename</Button
|
||||
>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</template>
|
||||
@@ -256,3 +256,49 @@ export async function uploadToWarren(
|
||||
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
export async function renameWarrenEntry(
|
||||
path: string,
|
||||
currentName: string,
|
||||
newName: string
|
||||
): Promise<{ success: boolean }> {
|
||||
// eslint-disable-next-line prefer-const
|
||||
let [warrenId, rest] = splitOnce(path, '/');
|
||||
|
||||
if (rest == null) {
|
||||
rest = '/';
|
||||
} else {
|
||||
rest = '/' + rest + '/';
|
||||
}
|
||||
|
||||
rest += currentName;
|
||||
|
||||
const { status } = await useFetch(getApiUrl(`warrens/files/rename`), {
|
||||
method: 'PATCH',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
warrenId,
|
||||
path: rest,
|
||||
newName,
|
||||
}),
|
||||
});
|
||||
|
||||
if (status.value !== 'success') {
|
||||
toast.error('Rename', {
|
||||
id: 'RENAME_FILE_TOAST',
|
||||
description: `Failed to rename ${currentName}`,
|
||||
});
|
||||
return { success: false };
|
||||
}
|
||||
|
||||
await refreshNuxtData('current-directory');
|
||||
|
||||
toast.success('Rename', {
|
||||
id: 'RENAME_FILE_TOAST',
|
||||
description: `Successfully renamed ${currentName} to ${newName}`,
|
||||
});
|
||||
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import DirectoryListContextMenu from '~/components/DirectoryListContextMenu.vue';
|
||||
import RenameEntryDialog from '~/components/actions/RenameEntryDialog.vue';
|
||||
import { getWarrenDirectory } from '~/lib/api/warrens';
|
||||
|
||||
const entries = useAsyncData('current-directory', () =>
|
||||
@@ -8,7 +9,10 @@ const entries = useAsyncData('current-directory', () =>
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DirectoryListContextMenu class="w-full grow">
|
||||
<DirectoryList v-if="entries != null" :entries="entries" />
|
||||
</DirectoryListContextMenu>
|
||||
<div>
|
||||
<DirectoryListContextMenu class="w-full grow">
|
||||
<DirectoryList v-if="entries != null" :entries="entries" />
|
||||
</DirectoryListContextMenu>
|
||||
<RenameEntryDialog />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { defineStore } from 'pinia';
|
||||
import type { DirectoryEntry } from '~/types';
|
||||
import type { Warren } from '~/types/warrens';
|
||||
|
||||
export const useWarrenStore = defineStore<
|
||||
@@ -19,10 +20,35 @@ export const useWarrenRoute = () =>
|
||||
export const useCreateDirectoryDialog = defineStore('create_directory_dialog', {
|
||||
state: () => ({
|
||||
open: false,
|
||||
value: '',
|
||||
}),
|
||||
actions: {
|
||||
openDialog() {
|
||||
this.open = true;
|
||||
},
|
||||
reset() {
|
||||
this.open = false;
|
||||
this.value = '';
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const useRenameDirectoryDialog = defineStore('rename_directory_dialog', {
|
||||
state: () => ({
|
||||
open: false,
|
||||
entry: null as DirectoryEntry | null,
|
||||
value: '',
|
||||
}),
|
||||
actions: {
|
||||
openDialog(entry: DirectoryEntry) {
|
||||
this.entry = entry;
|
||||
this.value = entry.name;
|
||||
this.open = true;
|
||||
},
|
||||
reset() {
|
||||
this.open = false;
|
||||
this.entry = null;
|
||||
this.value = '';
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user