feat(10-06): update StorageBrowser — skeleton rows, EmptyState, BreadcrumbBar swap

- Replace FolderBreadcrumb import with BreadcrumbBar + EmptyState imports
- Replace <FolderBreadcrumb> with <BreadcrumbBar :root-label="mode === 'cloud' ? 'Cloud' : 'Home'">
- Replace Loading… div with 5 animated skeleton rows (animate-pulse, grid-cols-[2rem_1fr_6rem_8rem_6rem])
- Replace inline empty-state divs with three <EmptyState> blocks (search/in-folder/root)
- UX-02 skeleton tests green (4/4)
This commit is contained in:
curo1305
2026-06-15 20:23:34 +02:00
parent 413d3f0ff7
commit d040e77548
@@ -4,8 +4,9 @@
<!-- Sticky toolbar --> <!-- Sticky toolbar -->
<div class="sticky top-0 z-10 bg-white border-b border-gray-100"> <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"> <div class="px-6 py-3 flex items-center gap-3 flex-wrap">
<FolderBreadcrumb <BreadcrumbBar
:segments="breadcrumb" :segments="breadcrumb"
:root-label="mode === 'cloud' ? 'Cloud' : 'Home'"
@navigate="$emit('breadcrumb-navigate', $event)" @navigate="$emit('breadcrumb-navigate', $event)"
/> />
<div class="ml-auto flex items-center gap-2 shrink-0"> <div class="ml-auto flex items-center gap-2 shrink-0">
@@ -223,25 +224,46 @@
</div> </div>
</div> </div>
<!-- Empty state --> <template v-if="loading">
<div <div
v-if="!loading && folders.length === 0 && files.length === 0 && !showNewFolderInput" v-for="n in 5"
class="px-4 py-10 text-center text-gray-300" :key="`sk-${n}`"
> class="px-4 py-2.5 grid grid-cols-[2rem_1fr_6rem_8rem_6rem] gap-3 items-center border-b border-gray-100"
<p class="text-gray-400 text-sm">{{ emptyMessage }}</p> >
<p class="text-xs mt-1">{{ emptyHint }}</p> <div class="w-7 h-7 bg-gray-100 rounded-lg animate-pulse"></div>
</div> <div class="h-4 bg-gray-100 rounded animate-pulse w-2/3"></div>
<div class="h-3 bg-gray-100 rounded animate-pulse hidden md:block"></div>
<div class="h-3 bg-gray-100 rounded animate-pulse hidden sm:block"></div>
<div class="w-14 h-3 bg-gray-100 rounded animate-pulse"></div>
</div>
</template>
<!-- Search no-results --> <EmptyState
<div v-else-if="searchQuery && folders.length === 0 && files.length === 0"
v-else-if="searchQuery && files.length === 0 && folders.length === 0" icon="search"
class="px-4 py-10 text-center text-sm text-gray-400" :headline="`No results for &quot;${searchQuery}&quot;`"
subtext="Try a different search term or clear the filter."
> >
No items match "{{ searchQuery }}". <template #cta>
</div> <button @click="$emit('search-change', '')" class="mt-3 text-sm text-indigo-600 hover:underline">
Clear search
</button>
</template>
</EmptyState>
<!-- Loading --> <EmptyState
<div v-if="loading" class="py-6 text-center text-sm text-gray-400">Loading</div> v-else-if="breadcrumb.length > 0 && folders.length === 0 && files.length === 0 && !showNewFolderInput"
icon="document"
:headline="emptyMessage"
:subtext="emptyHint"
/>
<EmptyState
v-else-if="folders.length === 0 && files.length === 0 && !showNewFolderInput"
icon="folder"
:headline="emptyMessage"
:subtext="emptyHint"
/>
</div> </div>
</div> </div>
</div> </div>
@@ -249,7 +271,8 @@
<script setup> <script setup>
import { ref, computed, nextTick, onMounted, onUnmounted } from 'vue' import { ref, computed, nextTick, onMounted, onUnmounted } from 'vue'
import FolderBreadcrumb from '../folders/FolderBreadcrumb.vue' import BreadcrumbBar from '../ui/BreadcrumbBar.vue'
import EmptyState from '../ui/EmptyState.vue'
import SearchBar from '../documents/SearchBar.vue' import SearchBar from '../documents/SearchBar.vue'
import SortControls from '../documents/SortControls.vue' import SortControls from '../documents/SortControls.vue'
import DropZone from '../upload/DropZone.vue' import DropZone from '../upload/DropZone.vue'