Skip to content

feat: canvas directory - rename, thumbnail preview with auto-save, search/sort, save indicator#57

Merged
calebyhan merged 11 commits intomainfrom
feature/dashboard
Mar 17, 2026
Merged

feat: canvas directory - rename, thumbnail preview with auto-save, search/sort, save indicator#57
calebyhan merged 11 commits intomainfrom
feature/dashboard

Conversation

@calebyhan
Copy link
Owner

Description

Account dashboard revamp.

Type of Change

  • 🐛 Bug fix (non-breaking change which fixes an issue)
  • ✨ New feature (non-breaking change which adds functionality)
  • 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • 📚 Documentation update
  • 🔨 Refactoring (no functional changes)
  • ✅ Test additions or updates
  • 🔧 Configuration/build changes

Related Issues

Closes #24

Changes Made

  • Added canvas preview
  • Added saving indicator on canvas
  • Added search/filter canvas on dashboard

Checklist

  • My code follows the project's style guidelines (PEP 8 for Python, ESLint for TypeScript)
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings or errors
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published

Additional Context

N/A


Copilot AI review requested due to automatic review settings March 16, 2026 21:05
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR revamps the canvas “directory” experience by adding persisted canvas thumbnails, rename support, search/sort on the dashboard, and an in-canvas save indicator—backed by a new thumbnail field on canvases in the backend API/schema.

Changes:

  • Add thumbnail (JSON) support end-to-end: DB schema, backend list/get/update APIs, and frontend API types.
  • Add dashboard UX features: thumbnail preview cards, rename modal for owned canvases, and search/sort controls for owned/shared lists.
  • Add debounced thumbnail auto-save from the canvas editor and display a save-state indicator in the top navigation.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
frontend/lib/api/backendClient.ts Adds CanvasThumbnail type and allows PATCH updates to include thumbnails.
frontend/hooks/useCanvas.ts Adds renameCanvas() and wires it into owned-canvas flows.
frontend/components/navigation/TopNavigation.tsx Replaces static “Auto-saved” badge with a save-state indicator UI.
frontend/components/dashboard/SharedCanvases.tsx Adds search + sort UI and filtered rendering for shared canvases.
frontend/components/dashboard/MyCanvases.tsx Adds search + sort UI and passes rename handler into owned canvas cards.
frontend/components/dashboard/CanvasCard.tsx Implements thumbnail preview rendering and an owned-canvas rename modal entrypoint.
frontend/components/AutoVizAgent.tsx Adds debounced thumbnail auto-save and propagates save state to TopNavigation.
backend/database/schema.sql Adds thumbnail JSONB column to canvases schema.
backend/app/api/routes/canvases.py Returns thumbnail in list/get/shared responses and accepts it in PATCH updates.
Comments suppressed due to low confidence (2)

backend/app/api/routes/canvases.py:312

  • updates = body.model_dump(exclude_unset=True) will include fields explicitly set to null (e.g. { "name": null }), which will attempt to write NULL into a NOT NULL column and likely bubble up as a 500 from Supabase/PostgREST. Consider validating updates before calling .update() (e.g., reject name is None / blank, and possibly sanitize thumbnail), and return a 4xx error instead of relying on the DB constraint failure path.
    updates = body.model_dump(exclude_unset=True)
    if not updates:
        raise HTTPException(status_code=400, detail="No fields to update")

    result = await asyncio.to_thread(
        lambda: supabase.table("canvases").update(updates).eq("id", canvas_id).execute()
    )
    return result.data[0]

backend/app/api/routes/canvases.py:312

  • New persisted behavior is being introduced (thumbnail JSON stored on canvases and returned from list/get/shared, plus new PATCH field), but backend tests don’t currently cover it. Please add tests that (1) PATCHing a valid thumbnail stores/returns it, (2) invalid thumbnail shapes are rejected, and (3) list/shared responses include the thumbnail field when present.
@router.patch("/{canvas_id}", response_model=Dict[str, Any])
async def update_canvas(canvas_id: str, body: UpdateCanvasRequest, user_id: str = Depends(require_user)):
    supabase = get_supabase_client()
    permission = await get_canvas_permission(canvas_id, user_id, supabase)
    if permission not in ("owner", "edit"):
        raise HTTPException(status_code=403, detail="Edit access required")

    updates = body.model_dump(exclude_unset=True)
    if not updates:
        raise HTTPException(status_code=400, detail="No fields to update")

    result = await asyncio.to_thread(
        lambda: supabase.table("canvases").update(updates).eq("id", canvas_id).execute()
    )
    return result.data[0]

… after rename, fix initial-load save guard, clear thumbnail when all elements deleted
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Implements the canvas directory/dashboard revamp by adding thumbnail previews, rename support, search/sort on the dashboard, and an auto-save indicator tied to thumbnail persistence.

Changes:

  • Add thumbnail support across backend schema + canvases API responses, and expose it in frontend API types.
  • Add thumbnail rendering to owned/shared canvas cards and auto-save thumbnail updates from the canvas editor.
  • Add dashboard search + sort, plus owned-canvas rename UX and hook support.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
frontend/lib/api/backendClient.ts Adds CanvasThumbnail + thumbnail fields; extends PATCH payload shape.
frontend/hooks/useCanvas.ts Adds renameCanvas helper and wires it into owned canvases state updates.
frontend/components/navigation/TopNavigation.tsx Replaces static “Auto-saved” badge with a dynamic save indicator.
frontend/components/dashboard/SharedCanvases.tsx Adds search + sort UI and filtering for shared canvases list.
frontend/components/dashboard/MyCanvases.tsx Adds search + sort and wires rename into owned canvas cards.
frontend/components/dashboard/CanvasCard.tsx Adds thumbnail preview rendering and rename modal/menu action in cards.
frontend/components/AutoVizAgent.tsx Implements debounced thumbnail auto-save and forwards save state to top nav.
backend/database/schema.sql Adds thumbnail JSONB column to canvases.
backend/app/api/routes/canvases.py Plumbs thumbnail through list/get/shared and PATCH request model.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the account dashboard “canvas directory” experience by adding canvas thumbnails (with auto-save), rename support, search/sort, and a more informative save indicator, with backend support for persisting thumbnail JSON.

Changes:

  • Added thumbnail to canvas models and endpoints; added DB column (thumbnail JSONB).
  • Implemented thumbnail preview cards + rename modal; added search and sort to owned/shared canvas lists.
  • Added debounced thumbnail auto-save in the canvas editor and surfaced save state in the top navigation.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
frontend/lib/api/backendClient.ts Adds CanvasThumbnail and extends canvas update/type definitions to include thumbnail.
frontend/hooks/useCanvas.ts Adds renameCanvas helper wiring to the canvas update endpoint.
frontend/components/navigation/TopNavigation.tsx Replaces “Auto-saved” badge with a SaveIndicator showing saving/saved states.
frontend/components/dashboard/SharedCanvases.tsx Adds search + sort UI and filtered rendering for shared canvases.
frontend/components/dashboard/MyCanvases.tsx Adds search + sort + rename wiring for owned canvases.
frontend/components/dashboard/CanvasCard.tsx Adds thumbnail preview rendering and a rename dialog/menu action on canvas cards.
frontend/components/AutoVizAgent.tsx Adds debounced thumbnail auto-save and passes save state to the top nav.
backend/database/schema.sql Adds thumbnail JSONB column to canvases table (plus commented migration hint).
backend/app/api/routes/canvases.py Adds thumbnail to list/get responses and allows thumbnail updates via PATCH.
Comments suppressed due to low confidence (1)

backend/app/api/routes/canvases.py:312

  • This PR adds new behavior (persisting thumbnail via PATCH and returning it from list/get), but the existing route tests don’t cover setting a thumbnail or clearing it back to null. Adding focused tests around PATCH thumbnail update/clear would help prevent regressions, especially given the changed update serialization behavior.
@router.patch("/{canvas_id}", response_model=Dict[str, Any])
async def update_canvas(canvas_id: str, body: UpdateCanvasRequest, user_id: str = Depends(require_user)):
    supabase = get_supabase_client()
    permission = await get_canvas_permission(canvas_id, user_id, supabase)
    if permission not in ("owner", "edit"):
        raise HTTPException(status_code=403, detail="Edit access required")

    updates = body.model_dump(exclude_unset=True)
    if not updates:
        raise HTTPException(status_code=400, detail="No fields to update")

    result = await asyncio.to_thread(
        lambda: supabase.table("canvases").update(updates).eq("id", canvas_id).execute()
    )
    return result.data[0]

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds “canvas directory” enhancements to the dashboard/canvas UX, including thumbnail previews persisted to the backend, rename support, search/sort controls, and an in-canvas save status indicator.

Changes:

  • Add thumbnail (JSONB) to canvases and expose it via canvas list/detail/shared APIs + update endpoint.
  • Generate and auto-save lightweight thumbnail metadata from canvas layout changes; display save state in top navigation.
  • Enhance dashboard canvas cards with SVG thumbnail preview, rename action, and search/sort UI for owned/shared canvases.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
frontend/lib/api/backendClient.ts Adds CanvasThumbnail type and includes thumbnail in canvas types + update payload.
frontend/hooks/useCanvas.ts Adds renameCanvas helper that PATCHes canvas name and updates local state.
frontend/components/navigation/TopNavigation.tsx Replaces static “Auto-saved” badge with dynamic save indicator UI.
frontend/components/dashboard/SharedCanvases.tsx Adds search and sort UI + filtered rendering for shared canvases.
frontend/components/dashboard/MyCanvases.tsx Adds search/sort and wires rename action into owned canvas cards.
frontend/components/dashboard/CanvasCard.tsx Adds thumbnail SVG preview rendering + rename modal + layout tweaks.
frontend/components/AutoVizAgent.tsx Debounced auto-save of thumbnail metadata on layout changes; passes save state to top nav.
backend/database/schema.sql Adds thumbnail JSONB column to canvases table (with commented “migration” line).
backend/app/api/routes/canvases.py Adds thumbnail to selects/responses and supports updating/clearing thumbnail via PATCH.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR revamps the canvas “directory” experience on the account dashboard by adding canvas thumbnails, rename, search/sort controls, and an auto-save status indicator, backed by a new thumbnail field persisted on canvases in the backend.

Changes:

  • Add a thumbnail JSON field to canvases (DB + API) and extend the frontend Canvas types to include it.
  • Add dashboard UX improvements: thumbnail previews, rename flow, search + sort for owned/shared canvases.
  • Add an auto-save indicator in the top navigation driven by debounced thumbnail updates from the canvas page.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
frontend/lib/api/backendClient.ts Adds CanvasThumbnail typing and allows updating thumbnail via PATCH.
frontend/hooks/useCanvas.ts Adds renameCanvas helper to update canvas name and refresh local state.
frontend/components/navigation/TopNavigation.tsx Replaces static “Auto-saved” badge with a stateful save indicator.
frontend/components/dashboard/SharedCanvases.tsx Adds search + sort UI and filtering for shared canvases.
frontend/components/dashboard/MyCanvases.tsx Adds search + sort UI, filtering, and rename wiring for owned canvases.
frontend/components/dashboard/CanvasCard.tsx Adds thumbnail preview rendering and a rename modal/action in the canvas card menu.
frontend/components/AutoVizAgent.tsx Implements debounced thumbnail auto-save and surfaces save state to TopNavigation.
backend/database/schema.sql Adds thumbnail JSONB column to the canvases table definition.
backend/app/api/routes/canvases.py Adds thumbnail to list/get/selects and supports updating/clearing it via PATCH.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the canvas “directory” experience (dashboard) by adding thumbnail previews with auto-save, canvas rename, search/sort controls, and an in-canvas save indicator, backed by a new thumbnail field on canvases in the backend.

Changes:

  • Add thumbnail JSON payload support to canvases (DB schema, API responses, PATCH updates, frontend types).
  • Implement debounced thumbnail auto-save from the canvas editor and display a save state indicator in the top nav.
  • Upgrade dashboard canvas lists/cards with thumbnail previews, search/sort, and rename UI for owned canvases.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
frontend/lib/api/backendClient.ts Adds CanvasThumbnail type + thumbnail field to canvas models and update payload.
frontend/hooks/useCanvas.ts Adds renameCanvas helper that PATCHes canvas name and updates local state.
frontend/components/navigation/TopNavigation.tsx Replaces static “Auto-saved” badge with a save-state indicator.
frontend/components/dashboard/SharedCanvases.tsx Adds query + sort UI and applies filtering/sorting to shared canvases list.
frontend/components/dashboard/MyCanvases.tsx Adds query + sort UI and wires rename action into owned canvas cards.
frontend/components/dashboard/CanvasCard.tsx Renders thumbnail previews, adds rename modal + action menu updates.
frontend/components/AutoVizAgent.tsx Debounced thumbnail auto-save based on layout changes; forwards save status to top nav.
backend/database/schema.sql Adds thumbnail JSONB column to canvases schema (with a commented migration hint).
backend/app/api/routes/canvases.py Adds thumbnail to list/get/shared selects and allows PATCH updates for thumbnail.
Comments suppressed due to low confidence (1)

backend/app/api/routes/canvases.py:317

  • The new thumbnail behavior (setting/clearing thumbnail via PATCH, and returning thumbnail from list/get/shared responses) isn’t covered by the existing canvas route tests. Adding tests for updating a thumbnail, clearing it with null, and verifying it appears in list/get responses would help prevent regressions.
@router.patch("/{canvas_id}", response_model=Dict[str, Any])
async def update_canvas(canvas_id: str, body: UpdateCanvasRequest, user_id: str = Depends(require_user)):
    supabase = get_supabase_client()
    permission = await get_canvas_permission(canvas_id, user_id, supabase)
    if permission not in ("owner", "edit"):
        raise HTTPException(status_code=403, detail="Edit access required")

    updates = body.model_dump(exclude_unset=True)
    # Drop None for name (NOT NULL) and description (nullable but not clearable via this endpoint);
    # allow thumbnail=None to pass through so clients can explicitly clear the thumbnail
    for field in ("name", "description"):
        if updates.get(field) is None:
            updates.pop(field, None)
    if not updates:
        raise HTTPException(status_code=400, detail="No fields to update")

    result = await asyncio.to_thread(
        lambda: supabase.table("canvases").update(updates).eq("id", canvas_id).execute()
    )
    return result.data[0]

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds “canvas directory” enhancements across backend + frontend to support dashboard browsing improvements and in-canvas auto-saving UX, including persisted thumbnail previews.

Changes:

  • Persist and return a thumbnail JSONB field for canvases (schema + API + frontend types).
  • Add debounced auto-save of canvas thumbnails and a “saving/saved” indicator in the top navigation.
  • Add dashboard search/sort plus owned-canvas rename UI and thumbnail previews in canvas cards.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
frontend/lib/api/backendClient.ts Adds CanvasThumbnail type and supports updating thumbnail via canvasAPI.update.
frontend/hooks/useCanvas.ts Adds renameCanvas helper and wires it into owned canvases state updates.
frontend/components/navigation/TopNavigation.tsx Replaces static “Auto-saved” badge with a save-state indicator component.
frontend/components/dashboard/SharedCanvases.tsx Adds client-side search + sort controls for shared canvases listing.
frontend/components/dashboard/MyCanvases.tsx Adds client-side search + sort and wires rename handler into owned canvas cards.
frontend/components/dashboard/CanvasCard.tsx Adds thumbnail preview rendering and an owned-canvas rename dialog/actions menu.
frontend/components/AutoVizAgent.tsx Implements debounced thumbnail auto-save and passes save-state into navigation.
backend/database/schema.sql Adds thumbnail column to canvases (plus idempotent ALTER for existing DBs).
backend/app/api/routes/canvases.py Exposes thumbnail in list/get/shared and allows PATCH updates for it.
Comments suppressed due to low confidence (1)

backend/app/api/routes/canvases.py:316

  • New thumbnail behavior (persisting thumbnail via PATCH and returning it from list/get/shared) isn’t covered by the existing canvases route tests. Since this changes API behavior and is used for the dashboard preview, add pytest coverage for: setting a thumbnail, clearing it with null, and verifying list/get/shared include the field.
@router.patch("/{canvas_id}", response_model=Dict[str, Any])
async def update_canvas(canvas_id: str, body: UpdateCanvasRequest, user_id: str = Depends(require_user)):
    supabase = get_supabase_client()
    permission = await get_canvas_permission(canvas_id, user_id, supabase)
    if permission not in ("owner", "edit"):
        raise HTTPException(status_code=403, detail="Edit access required")

    updates = body.model_dump(exclude_unset=True)
    # Drop None for name (NOT NULL) and description (nullable but not clearable via this endpoint);
    # allow thumbnail=None to pass through so clients can explicitly clear the thumbnail
    for field in ("name", "description"):
        if updates.get(field) is None:
            updates.pop(field, None)
    if not updates:
        raise HTTPException(status_code=400, detail="No fields to update")

    result = await asyncio.to_thread(
        lambda: supabase.table("canvases").update(updates).eq("id", canvas_id).execute()
    )

@calebyhan calebyhan requested a review from Copilot March 17, 2026 03:27
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds “canvas directory” enhancements across the frontend dashboard and backend canvases API to support thumbnails, renaming, search/sort, and an autosave indicator.

Changes:

  • Add thumbnail payload support to canvases API + DB schema, and render thumbnail previews in dashboard cards.
  • Add canvas rename flow for owned canvases and add search/sort UI for owned/shared canvases.
  • Debounced auto-save of thumbnail snapshots from the canvas editor, with a save-state indicator in the top navigation.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
frontend/lib/api/backendClient.ts Adds CanvasThumbnail type and wires thumbnail into canvas types + PATCH update payload.
frontend/hooks/useCanvas.ts Adds renameCanvas() hook method and updates local canvas list state.
frontend/components/navigation/TopNavigation.tsx Replaces static “Auto-saved” badge with a live save indicator (saving/saved + relative time).
frontend/components/dashboard/SharedCanvases.tsx Adds search + sort controls and applies filtering/sorting to shared canvases list.
frontend/components/dashboard/MyCanvases.tsx Adds search + sort controls and passes rename handler into owned canvas cards.
frontend/components/dashboard/CanvasCard.tsx Adds thumbnail preview rendering and a rename dialog + actions menu entry.
frontend/components/AutoVizAgent.tsx Implements debounced thumbnail auto-save on layout change and passes save state to navigation.
backend/database/schema.sql Adds thumbnail JSONB column to canvases.
backend/app/api/routes/canvases.py Adds thumbnail support to list/get/shared responses and PATCH update request handling.
Comments suppressed due to low confidence (1)

backend/app/api/routes/canvases.py:317

  • The new thumbnail update behavior (including allowing thumbnail=null to clear it and ensuring the value is returned in list/get responses) isn’t covered by the existing canvas route tests. Please add/extend tests to assert thumbnail round-trips and that clearing works, so this feature doesn’t regress.
@router.patch("/{canvas_id}", response_model=Dict[str, Any])
async def update_canvas(canvas_id: str, body: UpdateCanvasRequest, user_id: str = Depends(require_user)):
    supabase = get_supabase_client()
    permission = await get_canvas_permission(canvas_id, user_id, supabase)
    if permission not in ("owner", "edit"):
        raise HTTPException(status_code=403, detail="Edit access required")

    updates = body.model_dump(exclude_unset=True)
    # Drop None for name (NOT NULL) and description (nullable but not clearable via this endpoint);
    # allow thumbnail=None to pass through so clients can explicitly clear the thumbnail
    for field in ("name", "description"):
        if updates.get(field) is None:
            updates.pop(field, None)
    if not updates:
        raise HTTPException(status_code=400, detail="No fields to update")

    result = await asyncio.to_thread(
        lambda: supabase.table("canvases").update(updates).eq("id", canvas_id).execute()
    )
    return result.data[0]

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds canvas thumbnail support end-to-end (DB → API → client) and enhances the dashboard/canvas UX with previews, search/sort, rename, and a save indicator.

Changes:

  • Persist canvases.thumbnail (JSONB) in the backend and expose it via canvas list/get/shared APIs and PATCH updates.
  • Auto-generate and debounce-save thumbnails from the canvas layout, and surface a save-state indicator in the top navigation.
  • Update dashboard cards to show thumbnail previews, plus add search/sort controls and an owned-canvas rename action.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
frontend/lib/api/backendClient.ts Adds CanvasThumbnail types and extends canvas update payload to include thumbnail.
frontend/hooks/useCanvas.ts Adds renameCanvas helper that PATCHes canvas name and updates local state.
frontend/components/navigation/TopNavigation.tsx Replaces static “Auto-saved” badge with a save-state indicator (saving/saved).
frontend/components/dashboard/SharedCanvases.tsx Adds client-side search + sorting for shared canvases.
frontend/components/dashboard/MyCanvases.tsx Adds client-side search + sorting and wires rename callback into owned cards.
frontend/components/dashboard/CanvasCard.tsx Renders thumbnail previews, adds owned-canvas actions menu + rename modal, and updates card layout.
frontend/components/AutoVizAgent.tsx Implements debounced thumbnail auto-save based on layout key and plumbs save-state to top nav.
backend/database/schema.sql Adds thumbnail JSONB column to the canvases table (plus an ALTER for existing DBs).
backend/app/api/routes/canvases.py Accepts thumbnail in PATCH updates and includes it in canvas list/get/shared responses.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Implements an upgraded canvas “directory” experience in the dashboard (owned + shared canvases) with search/sort, renaming, and thumbnail previews that auto-save from the canvas editor, plus a live save indicator in the top navigation.

Changes:

  • Added thumbnail support across DB schema, backend canvas routes, and frontend API types.
  • Implemented debounced auto-save of canvas thumbnails from the editor and surfaced save status in TopNavigation.
  • Enhanced dashboard canvas lists with search + sorting and added a rename flow from canvas cards.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
frontend/lib/api/backendClient.ts Adds CanvasThumbnail types and updates PATCH typing to Partial<Canvas> including thumbnail.
frontend/hooks/useCanvas.ts Adds renameCanvas and merges partial PATCH responses into local state.
frontend/components/navigation/TopNavigation.tsx Replaces static “Auto-saved” badge with a SaveIndicator showing saving/saved state.
frontend/components/dashboard/SharedCanvases.tsx Adds search input + sort selector and uses filtered/sorted list.
frontend/components/dashboard/MyCanvases.tsx Adds search + sort; wires rename callback into owned canvas cards.
frontend/components/dashboard/CanvasCard.tsx Adds thumbnail preview rendering and a rename dialog + improved actions menu.
frontend/components/AutoVizAgent.tsx Adds debounced thumbnail auto-save to backend and passes save state to top nav.
backend/database/schema.sql Adds thumbnail JSONB to canvases (plus an ALTER TABLE ... IF NOT EXISTS migration line).
backend/app/api/routes/canvases.py Adds thumbnail to list/get responses and supports updating it via PATCH.
Comments suppressed due to low confidence (1)

backend/app/api/routes/canvases.py:317

  • The new thumbnail update behavior isn’t covered by the existing canvases route tests. Adding tests for PATCHing thumbnail (set + clear with null) and verifying it’s returned by GET/list endpoints would help prevent regressions in the autosave/preview feature.
@router.patch("/{canvas_id}", response_model=Dict[str, Any])
async def update_canvas(canvas_id: str, body: UpdateCanvasRequest, user_id: str = Depends(require_user)):
    supabase = get_supabase_client()
    permission = await get_canvas_permission(canvas_id, user_id, supabase)
    if permission not in ("owner", "edit"):
        raise HTTPException(status_code=403, detail="Edit access required")

    updates = body.model_dump(exclude_unset=True)
    # Drop None for name (NOT NULL) and description (nullable but not clearable via this endpoint);
    # allow thumbnail=None to pass through so clients can explicitly clear the thumbnail
    for field in ("name", "description"):
        if updates.get(field) is None:
            updates.pop(field, None)
    if not updates:
        raise HTTPException(status_code=400, detail="No fields to update")

    result = await asyncio.to_thread(
        lambda: supabase.table("canvases").update(updates).eq("id", canvas_id).execute()
    )
    return result.data[0]

@calebyhan calebyhan merged commit efc4a62 into main Mar 17, 2026
6 checks passed
@calebyhan calebyhan deleted the feature/dashboard branch March 17, 2026 06:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature: canvas directory page

2 participants