Commit Graph

39 Commits

Author SHA1 Message Date
indigo 9bbd3df53c Add assignee popover to Gantt chart status cells
The Gantt used a status-only EditableTaskStatus, unlike the shot/asset
data tables which pair status with an avatar-popover assignee picker.
Bring the Gantt's task-level EditableTaskStatus to parity (opt-in via a
showAssignee prop so the flat Tasks table's separate assignee column is
unaffected), and widen the frozen status column to fit both controls.
2026-07-22 04:03:42 +08:00
indigo c09710f4e5 Add per-project Department management
Departments are now a customizable per-project list (standard + custom),
matching the existing custom task type/status pattern, instead of a fixed
7-value enum. They're usable directly on tasks (new field, independent of
assignee) and continue to drive team member department roles.
2026-07-22 04:03:33 +08:00
indigo 11e1369f2f Add group-by toggle (Task Type / Shot) to the Schedule Gantt chart
Generalizes the previous task-type-only grouping into rowGroups, keyed
by either task_type or the shot/asset name depending on a new toolbar
toggle. Each row's label shows whichever dimension isn't already the
group header, so switching modes stays readable instead of showing
redundant text. Collapse state resets on mode/project change to avoid
stale group keys.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-21 03:34:19 +08:00
indigo 7f260067a2 Add editable status column and submission markers to the Gantt chart
Adds a second frozen "Task Status" column (EditableTaskStatus) next to
the task name, and small white dot markers on each bar showing
submission dates - backed by a new lightweight GET /tasks/submission-dates
endpoint (task_id + submitted_at only, to avoid an N+1 fetch across
potentially hundreds of scheduled tasks).

Restructures the chart's scroll handling from a single scrolling
container with sticky-positioned columns to two independently-scrolled
panes (frozen name/status columns, and the timeline), synced on
vertical scroll. This fixes several issues that came with the sticky
approach - transparency bleed-through on hover and on group-header
rows, row heights not matching between columns, and the horizontal
scrollbar spanning the frozen columns instead of just the timeline.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-21 03:20:28 +08:00
indigo 04c85be0f7 Add tab/project quick-switch dropdowns to the project breadcrumb
The project header breadcrumb now always shows the active tab
(previously Overview was hidden), and both the project-name and
tab-level crumbs become dropdowns: project name lists all projects
(with a checkmark on the active one, plus "All Projects"), and the
tab crumb lists Overview/Shots/Assets/Tasks/Schedule/Settings with a
checkmark on the current tab. The trailing ">" separator is skipped
after any crumb that renders as a dropdown.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-20 23:22:35 +08:00
indigo 74be250912 Generalize aggregated notes to a shared component, reuse in Asset panel
Moves shot/ShotNotes.vue to shared/EntityNotes.vue (it had no
shot-specific logic) and wires it into AssetDetailPanel.vue too,
replacing the old read-only AssetNotes.vue. Asset panel gains the same
multi-select task filter, sort, client-only/submission-notes toggles,
and bottom composer that Shot's panel already had, plus the same
min-h-0 layout fix needed for the pinned composer.

NoteItem's absolute-format timestamp now shows date-only (y/m/d) with
an info icon whose tooltip reveals the full y/m/d H:M:S - applied to
both note and submission-note entries.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-20 12:11:07 +08:00
indigo 172e05af3e Redesign shot detail panel notes: aggregated composer, filters, submission notes
Extracts a new ShotNotes.vue component (mirroring TaskNotes.vue) with a
pinned bottom composer, multi-select task filter, newest/oldest sort,
and toggleable client-only / submission-notes filters. Notes now merge
production notes with each task's submission notes into one
chronological, absolute-timestamped (y/m/d H:M:S) list.

Required restructuring ShotDetailPanel's outer layout to the same
bounded flex-column pattern TaskDetailPanel already uses, since a
properly pinned composer needs a min-h-0 flex chain that the old
single-scroll wrapper didn't provide.

NoteItem.vue gains optional dateFormat and hideClientBadge props
(both default to prior behavior, so TaskDetailPanel is unaffected),
compacts Edit/Delete to icon-only, and the Client badge is now
orange/white instead of a plain outline.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-20 11:11:32 +08:00
indigo 9c5abf6342 Add example-data script for testing submissions and reviews
Idempotent script mirroring the existing note/schedule seed-data
scripts: seeds Submission + Review rows (with real placeholder files
on disk) for the same sample of Dragon Quest shots, so the
submissions/reviews UI has realistic data to test against.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-20 10:00:47 +08:00
indigo f547d05478 Add project Schedule page with interactive Gantt chart
Adds a Schedule tab (Kitsu-style production schedule) under each
project: tasks grouped by type with drag-to-reschedule bars, Day/Week/
Month zoom, manual date-range control, weekend shading, a frozen task
column, and a two-tier month/date axis header. Requires a new
start_date field on Task (start_date was previously missing; only
deadline existed) and shadcn DatePicker inputs replace native date
inputs on the Schedule toolbar and TaskDetailPanel's Start Date/
Deadline fields.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-20 04:10:43 +08:00
indigo 981808b901 Extend submission config: .mxf/codec/frame-rate checks, regex naming, shot/asset tabs
- Movie spec checks now also cover codec (h264/h265/mjpeg/dnxhd/dnxhr/
  prores/uncompressed/avid/cineform) and frame rate (23.976/24/30/48/60),
  detected in-browser via mediainfo.js container parsing - works even
  for formats the native <video> element can't decode (MXF, ProRes,
  DNxHD). Added .mxf to the supported/allowed format lists.
- Naming pattern supports a raw regex mode (validated by compiling
  server-side at save time) as an alternative to the token pattern,
  and gained three more tokens: {task_name}, {project_name},
  {project_code} (fetched lazily only when referenced).
- Submission Configuration settings page now splits Shot Tasks /
  Asset Tasks into separate tabs instead of one merged list; the
  per-task-type card was extracted into SubmissionTypeConfigCard.vue
  to avoid duplicating it across both tabs.
2026-07-19 19:15:05 +08:00
indigo 23740af816 Add per-task-type submission configuration with client-side movie spec checks
Coordinators can configure, per task type, accepted file extensions, a
naming convention, and (for video files) required resolution/format/
codec/frame rate. All checking happens entirely client-side in the
browser before upload - the backend only stores and validates the
configuration itself, never inspects submitted files.

- backend: submission_config_by_task_type JSON column on Project,
  schemas/submission_config.py for validation, GET/PUT
  /projects/{id}/submission-config endpoints. Added .mxf/.ma/.usd(a/c)
  to the supported file formats.
- frontend: new Submissions tab in Project Settings
  (SubmissionConfigManager.vue) to configure rules per task type.
  TaskSubmissions.vue enforces them before upload: extension/naming
  checks via regex, and real video resolution/codec/frame rate
  detection via mediainfo.js (parses container metadata directly,
  so it works for formats browsers can't play natively like MXF,
  ProRes, or DNxHD).
2026-07-19 10:38:29 +08:00
indigo 762bd34f74 Redesign note display as message cards; fix reply and Textarea v-model bugs
- NoteItem.vue: render each note as a rounded card (own notes tinted)
  instead of a flat list row.
- TaskNotes.vue: show a "Replying to X" banner with cancel and
  auto-focus the composer when Reply is clicked, so replying is
  actually visible instead of silently setting hidden state.
- ShotDetailPanel/ShotBrowser/TaskDetailPanel: carry the target note
  id through select-task so replying from the shot-level aggregated
  notes view pre-fills the reply in the destination task's panel
  instead of just switching tabs.
- Textarea.vue: fix v-model, which was never wired up (modelValue/
  update:modelValue fell through as dead attrs on the native
  textarea), so typed content never reached the bound ref anywhere
  it's used - notes, submissions, and shot/asset/episode/project
  description fields.
- AssetDetailPanel/ShotDetailPanel/TaskDetailPanel: drop the header
  status badge and switch tab labels to icons (with an unread-style
  badge on Notes), fixing the TabsTrigger clipping/vertical alignment
  it introduced.
2026-07-19 00:00:11 +08:00
indigo 4bffec642e Align detail panel top edge with the header's actual bottom edge
DetailPanelOverlay.vue (shared by the shot/asset/task detail panels and
the My Tasks page) used a hardcoded top-[113px] that left a 49px gap
above the panel. The header is h-16 (64px), confirmed via its live
getBoundingClientRect() - switched to top-16 so the panel's top edge
sits flush against it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18 22:26:00 +08:00
indigo 548d1081ba Remove top project tabs in favor of the sidebar's Projects sub-menu
The sidebar already provides Overview/Shots/Assets/Tasks/Settings
navigation for the current project, making the top ProjectTabs bar
redundant. Removed it from ProjectDetailView.vue and deleted the
now-fully-unused ProjectTabs.vue component.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18 21:58:30 +08:00
indigo 960753b3d6 Make note/submission edit-own and edit-others' permissions explicit
Split note:edit/note:delete and submission:edit/submission:delete into
four independent permissions each - edit_self/delete_self (acting on
your own note or submission) and edit_other/delete_other (acting on
someone else's). Previously "own" access was an unconditional, unrevokable
ownership check with no permission behind it, and a prior round had
accidentally granted coordinator submission:edit/delete by default
(inconsistent with notes, which were correctly own-only) - both are fixed
here: self-service now goes through a real, default-granted-to-everyone
permission, and acting on someone else's note/submission is an explicit
elevated grant that nobody gets by default.

The Role Management permission editor now shows "Edit Own / Delete Own /
Edit Others' / Delete Others'" as four clear, independently toggleable
options instead of one ambiguous "Edit"/"Delete" checkbox.

migrate_role_permissions.py renames the existing permission rows in place
(rather than leaving orphaned duplicates) and includes a one-time,
idempotent correction that revokes the earlier over-grant from coordinator.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18 21:17:47 +08:00
indigo db2c414c1a Add multi-role permission system with a Role Management admin page
Users can now hold multiple roles, each with its own editable set of
create/edit/delete-style permissions across assets, shots, tasks, task
assignment, review approve/retake, submissions, uploads, and notes
(including internal vs. client note visibility). The 4 existing roles
(coordinator/director/artist/developer) are migrated into the new system
as system roles, seeded to reproduce today's actual behavior exactly;
admins can create custom roles (e.g. "Reviewer", "Outsourcing") via the
new Role Management page and assign multiple roles to a user via a new
"Manage Roles" action on the Team page.

Backend:
- New Role/Permission models and role_permissions/user_roles tables,
  plus a one-off, idempotent seed/backfill migration script.
- New require_permission()/user_has_permission() dependency, wired into
  the actual mutation endpoints across shots/assets/tasks/reviews,
  always preserving existing ownership- and self-service-based access
  (e.g. artists editing their own task status, own notes, own uploads,
  own submissions) as an unconditional fallback alongside the new
  permission checks - nothing that worked before now requires a role.
- New endpoints: PUT/DELETE on task submissions (wires up soft-deletion
  columns that existed on the model but were never exposed), plus full
  role CRUD and per-user role assignment.
- Along the way: fixed newly-created users not being linked to their
  matching system role (silently leaving them with zero permissions),
  and unified an inconsistency between the single vs. bulk task status
  endpoints that allowed different roles to bulk-update status.

Frontend:
- Role Management page with a grouped, human-readable permission editor
  (icons, plain-language action labels, per-resource select-all, live
  selected count) replacing an earlier dense matrix prototype.
- hasPermission() added to the existing usePermission() composable
  without touching its current isAdmin/isCoordinatorOrAdmin consumers.
- Note composer gets an Internal/Client toggle; submissions gain inline
  edit/delete actions gated the same ownership-or-permission way as notes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18 20:41:17 +08:00
indigo 976ec40b52 Add per-project sub-navigation to the sidebar's Projects nav item
Inside a specific project, the "Projects" item in the sidebar now shows
Overview/Shots/Assets/Tasks/Settings as sub-links (mirroring the existing
top-of-page ProjectTabs), with the active tab highlighted to match the
current route.

When the sidebar is collapsed to icons, the Projects icon still links
straight to /projects like any other nav item; hovering it reveals the
same 5 sub-links as a flyout menu (a controlled Popover, not a
DropdownMenu, so its own click-to-open behavior doesn't hijack the
icon's normal navigation click).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18 17:35:15 +08:00
indigo eb5587eb40 Consistent status colors, prevent native context menu leaks, fix settings 404
- Task status badges (bulk change-status popover, right-click menu) now
  use the real per-project TaskStatusesStore colors/labels instead of the
  hardcoded TaskStatus enum, matching EditableTaskStatus everywhere.
- Suppress the native browser context menu from leaking through gaps in
  the task table (header/empty space), open popovers/dropdowns and their
  submenus, the status Select, and a second right-click at the same
  coordinates (the popover's positioning anchor now has
  pointer-events: none so it doesn't intercept the repeat click).
- Fix 404s on /api/settings/* caused by a double-declared route prefix.
- Fix 422 on bulk-applying a custom task status by relaxing
  BulkStatusUpdate.status from the TaskStatus enum to str, matching the
  existing single-task update schema.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18 16:07:39 +08:00
indigo f013e1cf25 Fix wrong selected-task count in the task bulk-actions context menu
handleContextMenu (and the shift-click range-selection path) resolved the
target row via props.tasks[index], but index is the row's position in the
sorted/rendered row model (table.getRowModel().rows), not the raw prop
array — the two orders rarely match once the default created_at sort is
applied. This caused right-click (and shift-click) to select the wrong row,
corrupting the count shown in TaskBulkActionsMenu. Both call sites now
resolve the task from the actual row data instead of an index lookup into
the unsorted array, matching the pattern ShotsDataTable.vue already used
correctly.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18 13:19:42 +08:00
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
indigo 442abc3586 Fix unresolved Activity component warning in ActivityFeed.vue
The lucide icon was imported as "Activity as ActivityIcon" but the empty-
state template still referenced <Activity>, which was never registered
under that name — triggering a Vue "failed to resolve component" warning
whenever a project's activity feed was empty.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18 04:18:17 +08:00
indigo 9527f06b3f Fix activities endpoints to match established project-access convention
get_project_activities, get_task_activities, and get_recent_activities were
gating on "project member OR admin", incorrectly blocking coordinators,
directors, and developers from projects they weren't explicitly added to as
members. Every other project-scoped router (shots.py, assets.py) only
restricts the artist role this way — everyone else has access regardless of
membership. Brought activities.py in line with that convention.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18 04:18:07 +08:00
indigo 4f9deeb57a Phase 4: Architecture & tooling investment
Fixes a real N+1 API-call bug (per-cell project-member fetches in shot/asset
task-status cells, now a shared cached store), replaces a polling-based
in-flight request de-dup with promise memoization, adds markRaw() around
icon components in reactive state, and fixes a deep watcher that re-scanned
the whole projects array just to trigger thumbnail loading.

Introduces useAsyncAction and usePermission composables to cut duplicated
store boilerplate and duplicated role/admin checks, applied only where the
existing code was a clean match rather than forced onto everything. Extracts
assets.ts's shared per-asset optimistic-update/rollback helper without
merging the single and bulk API paths, which hit genuinely different
endpoints. Adds toast-on-error for previously-silent secondary loads and
fixes a dead try/catch in the router's auth-init guard along the way.

Also fixes a thumbnail-loading regression introduced earlier in this same
pass: the new ID-keyed watcher never fired on a repeat visit to the Projects
page when the store already held the same project list, so thumbnails
(local component state, reset per mount) silently stopped loading after the
first visit. Replaced the watcher with a direct call after each fetch.

Table virtualization, splitting the two largest view files, broad store
caching, and moving domain types into types/ were scoped out as separate,
higher-risk follow-ups (documented in frontend_tasks.md).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-18 04:03:58 +08:00
indigo 841e786fdd Fix task assignee resolution and align task status styling in ShotDetailPanel
The Tasks list embedded assigned_user_name: undefined with a "will be
resolved if needed" comment that was never followed up on, so every task
showed "Unassigned" regardless of actual assignment. Resolve it from the
project members list, matching how the shot table's own assignment control
does it, and show an avatar next to the name. Also swap the hardcoded
status Badge/variant switch for the same TaskStatusBadge + task-statuses
store the shot table uses, so status colors and labels (including custom
per-project statuses) always match between the table and the panel.
2026-07-18 02:17:06 +08:00
indigo 26807984ee Phase 3: Unify controls across shot/asset/task toolbars and detail panels
Extracts duplication that built up as shot/asset/task features reached
parity: CheckableCommandItem/ColumnToggleList replace 14+ hand-rolled
checkbox-list blocks, shared toolbar pieces (debounced search, detail-panel
toggle, clear-filters, segmented view/context toggle) replace copy-pasted
markup in the three table toolbars, icon-only buttons standardize on the
icon-sm size, TaskBulkActionsMenu's Assign To submenu matches Set Status,
and a shared DetailPanelOverlay/Header/Loading/Error shell backs all three
detail panels (adding a previously-missing error state to the task panel).
2026-07-18 02:15:55 +08:00
indigo cd3628a255 Phase 2: asset/shot feature parity, task actions, member management
Phase 2 of frontend_tasks.md - close feature gaps between domains:

- Asset user-assignment popover, ported from shot's EditableTaskStatus,
  wired through columns.ts and AssetBrowser.vue.
- Asset column-locking toggle: two-pane frozen-column layout ported
  into AssetsDataTable.vue (adapted for asset's page-scroll layout,
  which has no bounded-height container like shot's).
- Task table row-actions menu (View Details + Reassign only - no
  Delete/Edit, since no backend support exists for either).
- Real select-task/create-task behavior on asset and shot detail
  panels: clicking a task swaps in the actual TaskDetailPanel in
  place; "Add Task" opens a task-type picker that creates real tasks
  via the existing createAssetTask/createShotTask services.
- create-note/upload-reference/publish-version implemented via a
  task-picker that deep-links into TaskDetailPanel's Notes/
  Attachments/Submissions tabs (new initialTab prop), reusing the
  already-working task-level components instead of building three new
  bespoke forms. Also fixed shot's pre-existing dead "Add Note"/
  "Upload Reference" buttons the same way.
- Consolidated ProjectMembersManager.vue and ProjectMemberManagement.vue
  into one component, combining remove-confirmation and approved-user
  filtering with toast feedback and the shared Select/Dialog UI kit.
- Wired ProjectDetailView's "Manage Members" to navigate to the
  project's Settings > Team tab.

Also fixed a bug in this session's own new code: TaskBrowser.vue's
row-click handler is a no-op by design, so the new row-actions menu
needed to emit row-double-click (which actually opens the panel)
instead.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-17 08:45:06 +08:00
indigo e8b26487db Add task_details to the single-asset endpoint response
GET /assets/{id} never returned task_details (the schema didn't even
declare the field), unlike GET /shots/{id} which already populated it
correctly. This silently broke the asset detail panel's task list -
surfaced while wiring real task data into it on the frontend.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-17 08:44:36 +08:00
indigo cd2efe3587 Truth-in-UI cleanup: wire real dashboard data, fix delete/dialog gaps
Phase 1 of frontend_tasks.md - stop showing fabricated/broken UI:

- Dashboard now fetches real stats (projects, tasks, users, pending
  approvals, API keys, developer stats, pending reviews, admin
  activity) instead of hardcoded numbers. Added services/developer.ts
  and services/review.ts wrappers for previously-unused backend
  endpoints.
- Wired ActivityFeed into every project's Overview page in place of
  the "coming soon" placeholder.
- Registered the missing /projects/:id/technical-specs route (view
  and service already existed, just unreachable).
- Fixed AssetDeleteConfirmDialog's raw styled divs to use the shared
  Alert component and wired it into AssetBrowser, matching
  ShotBrowser's impact-summary + type-to-confirm safety pattern
  (asset deletion was previously less safe than shot deletion).
- Fixed a shared bug in both delete dialogs where the impact-summary
  section never rendered (watch on the open prop needed
  { immediate: true }).
- Replaced native confirm()/alert() with styled AlertDialog/Dialog in
  NoteItem, TaskAttachments, and UserMenu's keyboard-shortcuts item.
- Removed dead-end UI: Google OAuth stub buttons, UserMenu items
  pointing at non-existent routes, the /developer/docs dead link, and
  the no-op action button on the API Keys placeholder page.
- Removed leftover debug console logging across 8 files.

Added frontend_report.md (full audit) and frontend_tasks.md (phased
checklist) as the reference for this and future phases.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-17 04:47:26 +08:00
indigo c63a71883b Fix broken joinedload and import path in reviews/activities endpoints
joinedload("reviewer") used a string instead of a class-bound
attribute (rejected by SQLAlchemy 2.x), and models.submission was the
wrong import path for Submission. Both endpoints 500'd whenever
actually called; surfaced while wiring real dashboard/activity data
into the frontend.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-17 04:46:43 +08:00
indigo 61ee1a7364 Remove leftover debug/test scratch files from frontend root
These were one-off HTML/JS files and status reports accumulated from
past debugging sessions, not part of the app or a maintained test
suite.
2026-07-17 01:26:24 +08:00
indigo 14320693c7 Collapse sidebar column controls into icon dropdowns
When the sidebar is collapsed to icon-rail mode, the Columns/Task
Columns checkbox lists had no icon-only representation. Show icon
buttons that open a dropdown menu with checkbox items instead.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-17 01:23:18 +08:00
indigo d44398033a Add shot table column lock with two-pane horizontal scroll
Add a lock toggle to the shot table toolbar that freezes the
checkbox, thumbnail, and shot name columns. When locked, the table
splits into a fixed left pane and a horizontally scrollable right
pane so the scrollbar spans only the movable columns. Constrain the
table to fill the viewport height so the scrollbar stays at the
screen bottom, and add min-w-0 to the layout to keep horizontal
overflow inside the table instead of the page.

Also fix the asset Task Status filter to render task type groups by
using the object-aware TaskStatusBadge.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 10:04:55 +08:00
indigo b3ee14cc6e Match asset page layout and toolbar to shot page
- Remove wrapper padding from ProjectAssetsView so toolbar sits flush
  under the header, matching the shot page
- Add px-4 to AssetsDataTable root div to match ShotsDataTable margin
- Move thumbnail toggle from left filter group to right action area as
  an icon-only button, matching the shot toolbar's right-side pattern

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 01:29:27 +08:00
indigo 0acf9ddff2 Optimize shot table loading performance
- Pass episode_id filter to backend API instead of client-side filtering,
  reducing payload size when an episode is selected
- Skip getShot refetch in ShotDetailPanel when initialShot prop is provided
- Fix redundant DB query in list_shots: read project.custom_task_statuses
  directly from the already-fetched project object
- Add missing indexes on Task.shot_id, Task.assigned_user_id,
  Task.deleted_at and Episode.project_id; add add_perf_indexes.py
  migration script to apply them to existing databases
- Center login page layout
- Update CLAUDE.md and AGENTS.md with correct venv path

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 00:30:18 +08:00
indigo 0dd37d1706 Add CLAUDE.md and AGENTS.md with codebase architecture and dev commands
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 04:03:47 +08:00
indigo 19bc4e8a23 Add function for sidebar shot column switch 2026-03-07 09:33:44 +08:00
indigo 1f229bff6c Modify Shot Data Table Functions 2026-03-05 22:12:02 +08:00
indigo c8c4c99a6e modify my task 2026-03-01 11:30:40 +08:00
indigo de59b57ee7 Init Repo 2026-02-28 03:22:04 +08:00