Files
warren/frontend/components/DirectoryList.vue
2025-09-04 18:31:02 +02:00

71 lines
2.0 KiB
Vue

<script setup lang="ts">
import { ScrollArea } from '@/components/ui/scroll-area';
import type { DirectoryEntry } from '#shared/types';
const {
entries,
parent,
isOverDropZone,
disableEntries = false,
entriesDraggable = true,
} = defineProps<{
entries: DirectoryEntry[];
parent: DirectoryEntry | null;
isOverDropZone?: boolean;
disableEntries?: boolean;
entriesDraggable?: boolean;
}>();
const emit = defineEmits<{
'entry-click': [entry: DirectoryEntry, event: MouseEvent];
'entry-download': [entry: DirectoryEntry];
'entry-delete': [entry: DirectoryEntry, force: boolean];
back: [];
}>();
const { isLoading } = useLoadingIndicator();
function onEntryClicked(entry: DirectoryEntry, event: MouseEvent) {
emit('entry-click', entry, event);
}
function onEntryDownload(entry: DirectoryEntry) {
emit('entry-download', entry);
}
function onEntryDelete(entry: DirectoryEntry, force: boolean) {
emit('entry-delete', entry, force);
}
</script>
<template>
<ScrollArea class="flex h-full w-full flex-col overflow-hidden">
<div
v-if="isOverDropZone"
class="bg-background/50 pointer-events-none absolute flex h-full w-full items-center justify-center"
>
<Icon class="size-16 animate-pulse" name="lucide:upload" />
</div>
<div
class="flex w-full flex-col gap-2 overflow-hidden sm:flex-row sm:flex-wrap"
>
<DirectoryBackEntry
v-if="parent != null"
:entry="parent"
@back="() => emit('back')"
/>
<DirectoryEntry
v-for="(entry, i) in entries"
:key="entry.name"
:entry-index="i"
:entry="entry"
:disabled="isLoading || disableEntries"
:draggable="entriesDraggable"
@entry-click="onEntryClicked"
@entry-download="onEntryDownload"
@entry-delete="onEntryDelete"
/>
</div>
</ScrollArea>
</template>