e628c99498
Shot/Asset/Task data tables now keep their header row pinned while scrolling (both the locked two-pane and single-table modes), matching a common data- table expectation that was missing everywhere. Brings Asset and Task browsers to full structural parity with Shot's bounded- height layout (fixed toolbar, internally-scrolling table) instead of their previous page-scroll model with a sticky-positioned toolbar. AssetsDataTable gained the synced frozen/movable-pane scrolling it was missing entirely; TasksDataTable and both browsers/parent views got the same container model. The global My Tasks page (/tasks) now reuses TaskTableToolbar and TasksDataTable instead of its own ad hoc filter selects and TaskList, including the detail panel, bulk status/assignment context menu, and sticky header for free. Since it spans multiple projects, TaskTableToolbar gained an optional Project filter (only rendered when a project list is passed in, so the project-scoped Tasks page is unaffected); episode/assignee filters populate once a specific project is chosen. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
46 lines
1.5 KiB
Vue
46 lines
1.5 KiB
Vue
<template>
|
|
<div class="h-full flex flex-col">
|
|
<!-- Header -->
|
|
<div class="p-4 sm:p-6 border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
|
|
<div class="flex items-center justify-between">
|
|
<div>
|
|
<h2 class="text-xl font-semibold">Assets</h2>
|
|
<p class="text-sm text-muted-foreground mt-1">
|
|
Manage project assets including characters, props, sets, and vehicles
|
|
</p>
|
|
</div>
|
|
<div class="flex items-center gap-2">
|
|
<Badge variant="outline" class="text-xs">
|
|
{{ totalAssets }} {{ totalAssets === 1 ? 'asset' : 'assets' }}
|
|
</Badge>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Content -->
|
|
<div class="flex-1 overflow-hidden flex flex-col min-h-0">
|
|
<div class="flex-1 min-h-0 flex flex-col">
|
|
<AssetBrowser :project-id="projectId" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { computed } from 'vue'
|
|
import { useRoute } from 'vue-router'
|
|
import { Badge } from '@/components/ui/badge'
|
|
import AssetBrowser from '@/components/asset/AssetBrowser.vue'
|
|
import { useAssetsStore } from '@/stores/assets'
|
|
|
|
const route = useRoute()
|
|
const assetsStore = useAssetsStore()
|
|
|
|
// Computed properties
|
|
const projectId = computed(() => {
|
|
const id = route.params.projectId
|
|
return typeof id === 'string' ? parseInt(id) : Array.isArray(id) ? parseInt(id[0]) : 0
|
|
})
|
|
|
|
const totalAssets = computed(() => assetsStore.assets.length)
|
|
</script> |