Merge cleanup branch
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
<template>
|
||||
<div class="flex flex-col h-full">
|
||||
|
||||
<!-- ── Sticky toolbar ──────────────────────────────────────────────── -->
|
||||
<div class="sticky top-0 z-10 bg-white border-b border-gray-100">
|
||||
<div class="px-6 py-3 flex items-center gap-3 flex-wrap">
|
||||
<BreadcrumbBar
|
||||
@@ -29,16 +28,13 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ── Content area ───────────────────────────────────────────────── -->
|
||||
<div class="flex-1 overflow-y-auto flex flex-col">
|
||||
|
||||
<!-- Upload zone -->
|
||||
<div class="px-6 pt-5 pb-3">
|
||||
<DropZone ref="dropZoneRef" @files-selected="$emit('upload', $event)" />
|
||||
<UploadProgress :items="uploadQueue" />
|
||||
</div>
|
||||
|
||||
<!-- Column headers — 5-column grid, consistent for local and cloud -->
|
||||
<div class="mx-6 px-4 py-2 grid grid-cols-[2rem_1fr_6rem_8rem_6rem] gap-3 items-center rounded-lg bg-gray-50 text-xs font-semibold text-gray-400 uppercase tracking-wider select-none">
|
||||
<span></span>
|
||||
<span>Name</span>
|
||||
@@ -47,7 +43,6 @@
|
||||
<span></span>
|
||||
</div>
|
||||
|
||||
<!-- Inline new-folder row (local only) -->
|
||||
<div v-if="showNewFolderInput" class="mx-6 mt-1 px-4 py-2.5 grid grid-cols-[2rem_1fr_6rem_8rem_6rem] gap-3 items-center rounded-lg border border-amber-200 bg-amber-50/40">
|
||||
<div class="w-7 h-7 bg-amber-50 rounded-lg flex items-center justify-center">
|
||||
<AppIcon name="folder" class="w-4 h-4 text-amber-400" />
|
||||
@@ -68,10 +63,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ── Item list ─────────────────────────────────────────────────── -->
|
||||
<div class="mx-6 mt-1 mb-6 flex flex-col divide-y divide-gray-100 border border-gray-100 rounded-xl overflow-hidden">
|
||||
|
||||
<!-- Folder rows -->
|
||||
<div
|
||||
v-for="folder in folders"
|
||||
:key="`f-${folder.id}`"
|
||||
@@ -89,7 +82,6 @@
|
||||
<AppIcon name="folder" class="w-4 h-4 text-amber-500" />
|
||||
</div>
|
||||
|
||||
<!-- Name / rename input -->
|
||||
<div>
|
||||
<input
|
||||
v-if="renamingId === folder.id"
|
||||
@@ -105,7 +97,6 @@
|
||||
<span class="text-right text-xs text-gray-400 hidden md:block">—</span>
|
||||
<span class="text-right text-xs text-gray-400 hidden sm:block">{{ formatDate(folder.created_at) }}</span>
|
||||
|
||||
<!-- Folder actions (local only) -->
|
||||
<div class="flex justify-end gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity" @click.stop>
|
||||
<template v-if="mode === 'local'">
|
||||
<button @click.stop="startRename(folder)" title="Rename"
|
||||
@@ -135,7 +126,6 @@
|
||||
<AppIcon name="document" class="w-4 h-4 text-indigo-400" />
|
||||
</div>
|
||||
|
||||
<!-- Name + topics + shared badge -->
|
||||
<div class="min-w-0">
|
||||
<div class="flex items-center gap-2">
|
||||
<p class="text-sm font-medium text-gray-900 truncate">{{ file.original_name ?? file.name }}</p>
|
||||
@@ -154,15 +144,12 @@
|
||||
<span class="text-right text-xs text-gray-400 hidden md:block">{{ formatSize(file.size_bytes ?? file.size) }}</span>
|
||||
<span class="text-right text-xs text-gray-400 hidden sm:block">{{ formatDate(file.created_at) }}</span>
|
||||
|
||||
<!-- File actions (local only) -->
|
||||
<div class="flex justify-end gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity" @click.stop>
|
||||
<template v-if="mode === 'local'">
|
||||
<!-- Share -->
|
||||
<button @click.stop="$emit('file-share', file)" title="Share"
|
||||
class="p-1.5 rounded hover:bg-gray-200 text-gray-400 hover:text-gray-700 transition-colors">
|
||||
<AppIcon name="share" class="w-3.5 h-3.5" />
|
||||
</button>
|
||||
<!-- Move -->
|
||||
<div class="relative">
|
||||
<button
|
||||
@click.stop="openFolderPicker(file.id, $event)"
|
||||
@@ -172,7 +159,6 @@
|
||||
<AppIcon name="folderMove" class="w-3.5 h-3.5" />
|
||||
</button>
|
||||
</div>
|
||||
<!-- Delete -->
|
||||
<button @click.stop="$emit('file-delete', file.id)" title="Delete"
|
||||
class="p-1.5 rounded hover:bg-red-50 text-gray-400 hover:text-red-500 transition-colors">
|
||||
<AppIcon name="trash" class="w-3.5 h-3.5" />
|
||||
@@ -225,7 +211,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Teleported folder picker — avoids overflow:hidden clipping -->
|
||||
<Teleport to="body">
|
||||
<div
|
||||
v-if="folderPickerFileId"
|
||||
@@ -305,13 +290,9 @@ function topicColor(name) {
|
||||
return props.topicColorFn(name)
|
||||
}
|
||||
|
||||
// ── Child component refs ──────────────────────────────────────────────────────
|
||||
|
||||
const dropZoneRef = ref(null)
|
||||
const searchBarRef = ref(null)
|
||||
|
||||
// ── New folder inline input ───────────────────────────────────────────────────
|
||||
|
||||
const showNewFolderInput = ref(false)
|
||||
const newFolderName = ref('')
|
||||
const newFolderError = ref('')
|
||||
@@ -331,8 +312,17 @@ function cancelNewFolder() {
|
||||
|
||||
async function submitNewFolder() {
|
||||
const name = newFolderName.value.trim()
|
||||
if (!name) { newFolderError.value = 'Folder name cannot be empty.'; return }
|
||||
emit('folder-create', { name, onError: (msg) => { newFolderError.value = msg }, onSuccess: cancelNewFolder })
|
||||
if (!name) {
|
||||
newFolderError.value = 'Folder name cannot be empty.'
|
||||
return
|
||||
}
|
||||
emit('folder-create', {
|
||||
name,
|
||||
onError: (msg) => {
|
||||
newFolderError.value = msg
|
||||
},
|
||||
onSuccess: cancelNewFolder,
|
||||
})
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
@@ -342,8 +332,6 @@ defineExpose({
|
||||
clearSearch: () => emit('search-change', ''),
|
||||
})
|
||||
|
||||
// ── Rename ────────────────────────────────────────────────────────────────────
|
||||
|
||||
const renamingId = ref(null)
|
||||
const renameValue = ref('')
|
||||
|
||||
@@ -352,8 +340,6 @@ function startRename(folder) {
|
||||
renameValue.value = folder.name
|
||||
}
|
||||
|
||||
// ── Drag and drop (local only) ────────────────────────────────────────────────
|
||||
|
||||
const draggingFile = ref(null)
|
||||
const dragOverFolderId = ref(null)
|
||||
|
||||
@@ -383,11 +369,8 @@ async function onDropDocOnFolder(folderId) {
|
||||
draggingFile.value = null
|
||||
}
|
||||
|
||||
// ── Move folder picker (Teleport + getBoundingClientRect) ─────────────────────
|
||||
|
||||
const folderPickerFileId = ref(null)
|
||||
const pickerStyle = ref({})
|
||||
// Map fileId → trigger button element, so scroll listener can reposition
|
||||
const pickerTriggerMap = new Map()
|
||||
|
||||
function updatePickerPosition(rect) {
|
||||
@@ -409,7 +392,6 @@ function updatePickerPosition(rect) {
|
||||
}
|
||||
|
||||
function openFolderPicker(fileId, ev) {
|
||||
// Toggle off if same file
|
||||
if (folderPickerFileId.value === fileId) {
|
||||
folderPickerFileId.value = null
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user