Fix #119
All checks were successful
Build and Push Docker Images / build-backend (push) Successful in 2m36s
Build and Push Docker Images / build-frontend (push) Successful in 1m5s

Fix #153
This commit is contained in:
2026-03-25 17:20:47 +01:00
parent 669bcd93ab
commit 7ad44544cf

View File

@@ -37,6 +37,14 @@ const renameData = ref({id: null, name: '', type: ''})
const selectedFileIndex = ref(0) const selectedFileIndex = ref(0)
const draggedItem = ref(null) const draggedItem = ref(null)
const getEntryActions = (entry) => [[
{
label: 'Umbenennen',
icon: 'i-heroicons-pencil-square',
onSelect: () => openRenameModal(entry)
}
]]
// --- Search & Debounce --- // --- Search & Debounce ---
const searchString = ref(tempStore.searchStrings["files"] || '') const searchString = ref(tempStore.searchStrings["files"] || '')
const debouncedSearch = ref(searchString.value) const debouncedSearch = ref(searchString.value)
@@ -289,11 +297,15 @@ const showFile = (fileId) => {
}) })
} }
const isDialogOpen = computed(() => createFolderModalOpen.value || renameModalOpen.value)
defineShortcuts({ defineShortcuts({
'/': () => document.getElementById("searchinput")?.focus(), '/': () => document.getElementById("searchinput")?.focus(),
'Enter': { 'Enter': {
usingInput: true, usingInput: false,
handler: () => { handler: () => {
if (isDialogOpen.value) return
const entry = renderedFileList.value[selectedFileIndex.value] const entry = renderedFileList.value[selectedFileIndex.value]
if (!entry) return if (!entry) return
if (entry.type === "file") showFile(entry.id) if (entry.type === "file") showFile(entry.id)
@@ -413,10 +425,13 @@ const syncdokubox = async () => {
{{ entry.type !== 'up' ? dayjs(entry.createdAt).format("DD.MM.YY") : '-' }} {{ entry.type !== 'up' ? dayjs(entry.createdAt).format("DD.MM.YY") : '-' }}
</td> </td>
<td class="px-3 text-right" @click.stop> <td class="px-3 text-right" @click.stop>
<UDropdown v-if="entry.type !== 'up'" <UDropdownMenu
:items="[[{ label: 'Umbenennen', icon: 'i-heroicons-pencil-square', click: () => openRenameModal(entry) }]]"> v-if="entry.type !== 'up'"
<UButton color="gray" variant="ghost" icon="i-heroicons-ellipsis-horizontal"/> :items="getEntryActions(entry)"
</UDropdown> :content="{ align: 'end' }"
>
<UButton color="neutral" variant="ghost" icon="i-heroicons-ellipsis-horizontal"/>
</UDropdownMenu>
</td> </td>
</tr> </tr>
<tr v-if="renderedFileList.length === 0"> <tr v-if="renderedFileList.length === 0">
@@ -438,11 +453,15 @@ const syncdokubox = async () => {
class="group relative bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-xl p-4 flex flex-col items-center hover:border-primary-500 transition-all cursor-pointer" class="group relative bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-xl p-4 flex flex-col items-center hover:border-primary-500 transition-all cursor-pointer"
@click="entry.type === 'folder' ? changeFolder(entry) : (entry.type === 'up' ? navigateUp() : showFile(entry.id))" @click="entry.type === 'folder' ? changeFolder(entry) : (entry.type === 'up' ? navigateUp() : showFile(entry.id))"
> >
<UDropdown v-if="entry.type !== 'up'" <UDropdownMenu
:items="[[{ label: 'Umbenennen', icon: 'i-heroicons-pencil-square', click: () => openRenameModal(entry) }]]" v-if="entry.type !== 'up'"
class="absolute top-1 right-1 opacity-0 group-hover:opacity-100" @click.stop> :items="getEntryActions(entry)"
<UButton color="gray" variant="ghost" icon="i-heroicons-ellipsis-vertical" size="xs"/> :content="{ align: 'end' }"
</UDropdown> class="absolute top-1 right-1 opacity-0 group-hover:opacity-100"
@click.stop
>
<UButton color="neutral" variant="ghost" icon="i-heroicons-ellipsis-vertical" size="xs"/>
</UDropdownMenu>
<UIcon <UIcon
:name="entry.type === 'up' ? 'i-heroicons-arrow-uturn-left' : (entry.type === 'folder' ? 'i-heroicons-folder-solid' : 'i-heroicons-document-text')" :name="entry.type === 'up' ? 'i-heroicons-arrow-uturn-left' : (entry.type === 'folder' ? 'i-heroicons-folder-solid' : 'i-heroicons-document-text')"
class="w-12 h-12 mb-2" class="w-12 h-12 mb-2"
@@ -462,40 +481,51 @@ const syncdokubox = async () => {
<UModal v-model:open="createFolderModalOpen"> <UModal v-model:open="createFolderModalOpen">
<template #content> <template #content>
<UCard> <UCard class="shadow-xl ring-1 ring-black/5">
<template #header><h3 class="font-bold">Ordner erstellen</h3></template> <template #header>
<div class="flex items-start gap-4">
<div class="flex h-12 w-12 items-center justify-center rounded-2xl bg-primary/10 text-primary ring-1 ring-primary/15">
<UIcon name="i-heroicons-folder-plus" class="h-6 w-6" />
</div>
<div>
<h3 class="text-lg font-semibold text-highlighted">Ordner erstellen</h3>
<p class="mt-1 text-sm text-muted">Lege einen neuen Ordner im aktuellen Bereich an.</p>
</div>
</div>
</template>
<div class="space-y-4"> <form class="space-y-5" @submit.prevent="createFolder">
<UFormField label="Name" required> <UFormField label="Name" required>
<UInput v-model="createFolderData.name" autofocus @keyup.enter="createFolder"/> <UInput v-model="createFolderData.name" autofocus class="w-full" />
</UFormField> </UFormField>
<UFormField <UFormField
label="Standard Dateityp (Tag)" label="Standard Dateityp (Tag)"
:help="isParentTypeMandatory ? 'Vom übergeordneten Ordner vorgegeben' : ''" :help="isParentTypeMandatory ? 'Vom übergeordneten Ordner vorgegeben' : ''"
> >
<USelectMenu <USelectMenu
v-model="createFolderData.standardFiletype" v-model="createFolderData.standardFiletype"
:items="filetags" :items="filetags"
value-key="id" value-key="id"
label-key="name" label-key="name"
placeholder="Kein Standardtyp" placeholder="Kein Standardtyp"
searchable class="w-full"
clear-search-on-close :search-input="{ placeholder: 'Dateityp suchen...' }"
:filter-fields="['name']"
:disabled="isParentTypeMandatory"
/>
</UFormField>
<UCheckbox
v-model="createFolderData.standardFiletypeIsOptional"
label="Dateityp ist optional"
:disabled="isParentTypeMandatory" :disabled="isParentTypeMandatory"
/> />
</UFormField> </form>
<UCheckbox
v-model="createFolderData.standardFiletypeIsOptional"
label="Dateityp ist optional"
:disabled="isParentTypeMandatory"
/>
</div>
<template #footer> <template #footer>
<div class="flex justify-end gap-2"> <div class="flex justify-end gap-2">
<UButton color="gray" @click="createFolderModalOpen = false">Abbrechen</UButton> <UButton color="neutral" variant="ghost" @click="createFolderModalOpen = false">Abbrechen</UButton>
<UButton color="primary" @click="createFolder">Erstellen</UButton> <UButton color="primary" @click="createFolder">Erstellen</UButton>
</div> </div>
</template> </template>
@@ -505,14 +535,16 @@ const syncdokubox = async () => {
<UModal v-model:open="renameModalOpen"> <UModal v-model:open="renameModalOpen">
<template #content> <template #content>
<UCard> <UCard class="shadow-xl ring-1 ring-black/5">
<template #header><h3 class="font-bold">Umbenennen</h3></template> <template #header><h3 class="text-lg font-semibold text-highlighted">Umbenennen</h3></template>
<UFormField label="Neuer Name"> <form @submit.prevent="updateName">
<UInput v-model="renameData.name" autofocus @keyup.enter="updateName"/> <UFormField label="Neuer Name">
</UFormField> <UInput v-model="renameData.name" autofocus class="w-full" />
</UFormField>
</form>
<template #footer> <template #footer>
<div class="flex justify-end gap-2"> <div class="flex justify-end gap-2">
<UButton color="gray" @click="renameModalOpen = false">Abbrechen</UButton> <UButton color="neutral" variant="ghost" @click="renameModalOpen = false">Abbrechen</UButton>
<UButton color="primary" @click="updateName">Speichern</UButton> <UButton color="primary" @click="updateName">Speichern</UButton>
</div> </div>
</template> </template>