Appearance
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 (
selectableprop) — 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, commitsmoveAssetLibraryAsset - 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)
| File | Changes |
|---|---|
AssetColumn.vue | folderLevel prop, folderIconColor computed, context menu (v-menu), openContextMenu method |
AssetPreviewPanel.vue | .preview-actions section with Rename/Move/Delete buttons, styled with hover states |
AssetColumnBrowser.vue | Forwards :folder-level prop, bubbles rename-asset/move-asset/delete-asset events from both column and preview panel |
AssetLibraryContent.vue | ConfirmDialog 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 view —
viewModetoggle 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
fetchAssetLibraryruns
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 withinitialType: '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.