feat(media): reusable media management
Sprint 22. - MediaAsset gains folder (flat) and MediaListParams gains folder/tag filters; MediaRepository.listFolders() derives the folder list from existing records - upload validation: 10MB size cap, mime allow-list (jpeg/png/webp/gif/ svg+xml/pdf), real error messages surfaced through MediaLibraryFacade instead of a generic swallowed string - SVG uploads are sanitized (script tags and on*= attributes stripped) before storage - raster images (excl. gif) are downscaled to a 2000px max dimension and re-encoded via canvas before storage - compression, not a crop UI - tag editing (window.prompt, comma-separated) via MediaLibraryFacade.updateTags() - MediaPickerComponent wired into Project Editor branding (logo, compact logo, favicon) alongside its existing category/product usage - confirmed no image fields exist on Static Pages or as a dedicated hero field to wire docs/ADMIN.md updated with the new Sprint 22 section including the storage abstraction note (MediaRepository was already the abstraction). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
<input
|
||||
#fileInput
|
||||
type="file"
|
||||
accept="image/*,application/pdf"
|
||||
accept="image/jpeg,image/png,image/webp,image/gif,image/svg+xml,application/pdf"
|
||||
hidden
|
||||
(change)="onFileSelected($event)"
|
||||
/>
|
||||
@@ -23,6 +23,10 @@
|
||||
</app-button>
|
||||
</div>
|
||||
|
||||
@if (facade.error()) {
|
||||
<p class="media-picker__error">{{ facade.error() }}</p>
|
||||
}
|
||||
|
||||
@if (facade.loading()) {
|
||||
<div class="media-picker__grid">
|
||||
@for (i of [1, 2, 3, 4]; track i) {
|
||||
|
||||
Reference in New Issue
Block a user