Skip to content

Asset Library — Implementation Progress

Branch: implement-asset-library

What's done

Core infrastructure (committed)

  • Vuex store (src/store/modules/assetLibrary.ts) — full state management with mock data, folder tree built from real Vuex data (brands/campaigns/CGs), round-robin asset distribution, upload simulation
  • Folder tree built from live store data (enterprise → brand → campaign → CG), lazy-loads creatives via API when CG is clicked
  • Mutations: addAssetLibraryAsset, removeAssetLibraryAsset, renameAssetLibraryAsset, moveAssetLibraryAsset, setFolderChildren
  • Actions: fetchAssetLibrary, fetchCreativesForGroup, uploadAssetToLibrary, deleteAssetFromLibrary
  • Getters: assetLibraryAssets, assetLibraryFolders, assetLibraryFiltered, assetLibraryFlatFolders, assetLibraryBreadcrumb, assetLibrarySubfolders, assetLibraryGetById

UI components (committed)

  • AssetLibraryDialog (src/components/dialogs/AssetLibraryDialog.vue) — modal wrapper, opens via $root.$emit('open-asset-library')
  • AssetLibraryContent — main layout with sidebar (type filters), toolbar (upload button, view toggle), column browser
  • AssetColumnBrowser — Finder-style column navigation with keyboard support (arrow keys, Enter, Tab), auto-navigates to current scope context
  • AssetColumn — single column showing folders + assets, drag-and-drop upload zone
  • AssetPreviewPanel — right-side panel showing asset details (thumbnail, metadata, scope), font preview with live FontFace loading

Features (committed)

  • Search across assets (name + alias)
  • Type filtering (All / Images / Fonts / Videos) with lock when in picker mode
  • Upload via button or drag-and-drop, auto-detects file type
  • Scope-aware uploads (uploads to currently selected folder)
  • Auto-navigation to current creative's scope when opened from builder
  • Picker mode (selectable prop) — locks type filter, shows Select button

Features (uncommitted — current session)

  • Right-click context menu on assets in columns — Rename, Move to…, Delete (red)
  • Preview panel action buttons — Rename, Move to…, Delete below asset info
  • Delete confirmation — ConfirmDialog with asset name, dispatches deleteAssetFromLibrary
  • Move dialog — native <select> showing flat folder tree indented by depth, commits moveAssetLibraryAsset
  • Rename wiring — connected existing TextInputDialog to new event flow (context menu + preview panel → browser → content)
  • Folder icon colors — brand=#31b56f (green), campaign=#9e61a5 (purple), creativeGroup=#ab413f (rust), creative=#b43640 (red)

Files modified (uncommitted)

FileChanges
AssetColumn.vuefolderLevel prop, folderIconColor computed, context menu (v-menu), openContextMenu method
AssetPreviewPanel.vue.preview-actions section with Rename/Move/Delete buttons, styled with hover states
AssetColumnBrowser.vueForwards :folder-level prop, bubbles rename-asset/move-asset/delete-asset events from both column and preview panel
AssetLibraryContent.vueConfirmDialog import + component, move v-dialog with folder <select>, onRenameAsset/onDeleteAsset/onMoveAsset handlers, onDeleteConfirm/onMoveConfirm methods, assetLibraryFlatFolders getter

What's NOT done yet

Must-have for v1

  • [ ] Grid viewviewMode toggle exists but only column/list view is implemented. Grid view (card thumbnails) is wired in toolbar but doesn't render differently yet.
  • [ ] Breadcrumb / scope indicator — show current path in toolbar (e.g. "Kristiania › Høyskolen Kristiania › Studiestart 2026")
  • [ ] Empty state for upload — nicer empty state when a folder has no assets, with upload CTA
  • [ ] Loading states — spinner/skeleton while fetchAssetLibrary runs

Should-have for v1

  • [ ] Bulk select / bulk delete — checkbox selection, batch operations
  • [ ] Asset replacement — upload new version of existing asset (same ID, new URL)
  • [ ] Drag-and-drop reorder within column (not just upload)
  • [ ] Sort options — by name, date, type, size

v2 (requires backend)

  • [ ] Real API integration — swap mock data for API calls (see backend-spec.md)
  • [ ] CDN upload — Cloudflare R2 or similar, signed upload URLs
  • [ ] URL-type assets — bookmarked URLs with alias (removed from v1 scope)
  • [ ] Search across metadata — search by font family, dimensions, etc.
  • [ ] Asset usage tracking — which creatives use which assets
  • [ ] Permission checks — scope-based write access

Integration points (partially done)

  • [x] Font picker (TypefaceSection.vue) — opens asset library in picker mode with initialType: 'font'
  • [ ] Image picker — same pattern for image operators in builder
  • [ ] Video picker — same pattern for video operators
  • [ ] Builder sidebar — quick-access panel showing assets for current creative's scope

Architecture notes

Event flow for asset actions

AssetColumn / AssetPreviewPanel
  → @rename-asset / @move-asset / @delete-asset
    → AssetColumnBrowser (bubbles up)
      → @rename-asset / @move-asset / @delete-asset
        → AssetLibraryContent (opens dialogs, commits mutations)

Context menu pattern

Follows BlocksList.vue pattern: v-menu with position-x/position-y data, opened via @contextmenu.prevent handler that sets coordinates from MouseEvent.clientX/clientY.

Folder colors

Hardcoded hex values passed to <Icon :color> prop. When a folder is selected (white background), color is cleared to let CSS color: $global-white take over.

Internal documentation