Files
LinkDesk/frontend/src/views/project/ProjectAssetsView.vue
T
indigo e628c99498 Sticky table headers, layout parity, and reuse My Tasks on the shared table/toolbar
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>
2026-07-18 10:15:04 +08:00

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>