Cross-cutting · File upload, gallery & image modal

The shared upload and media-browsing layer behind store images, proposal images and audio, centre branding, app-button images, intranet files and CSV uploads — with type and size restrictions, aspect-ratio guidance, a gallery picker and a full-size image modal.

AreaCross-cutting
Routes(used by most editors)
Centre modulesalways available
Staff levelsas per the host screen
Modelsintranet-file
UI labelerror.file.type.not_allowed
Coverage5 use cases · 1 happy · 5 failure

How it works

api-files.uploadFile(file, …) is the single upload entry point and returns a file_url that models store as a string rather than as a binary relationship, which is why the same component works for images, audio, PDFs and CSVs. Three shared error strings cover every caller (error.file.type.not_allowed, error.file.oversize, error.file.not_allowed), so a failed upload reads the same everywhere even though the limits differ by context — the proposal audio limit of 10 MB, for example, is only stated in its own message. enums/aspectRatio and enums/orientations drive the cropping guidance, and img-modal provides the zoom view.

Use cases

Why someone opens this (5)

  • Uploading a store logo at the right aspect ratio.
  • Attaching a hero image to a proposal, or picking one already uploaded from the gallery.
  • Uploading a PDF to the intranet document library.
  • Attaching an audio description to a proposal for accessibility.
  • Uploading a CSV as part of an import.

Path map

flowchart LR
    F(["File upload, gallery and image modal"]):::feat
    F --> H1["Image uploaded and attached"]:::ok
    F -.-> X1["Disallowed file type"]:::bad
    F -.-> X2["File too large"]:::bad
    F -.-> X3["Upload rejected"]:::bad
    F -.-> X4["Required image left empty"]:::bad
    F -.-> X5["Orphaned uploads"]:::bad
    classDef feat fill:#8c5a3c,stroke:#8c5a3c,color:#ffffff,font-weight:bold
    classDef ok fill:#e3f1ea,stroke:#0d6b42,color:#0d4a2e
    classDef bad fill:#f7e6e2,stroke:#9a2d1c,color:#6e1f13

Happy paths

Image uploaded and attached

  1. User opens the file field in an editor and selects an image within the allowed types and size.
  2. api-files.uploadFile stores it and returns the URL.
  3. The URL is written to the model attribute and the thumbnail renders.
  4. The gallery can be used later to reuse the same asset.

Failure paths

QA checklist

Tick these off while regression-testing this feature. The boxes are plain Markdown, so progress is visible in git diffs.

  • ✅ Image uploaded and attached
  • ⛔ Disallowed file type
  • ⛔ File too large
  • ⛔ Upload rejected
  • ⛔ Required image left empty
  • ⛔ Orphaned uploads

Implementation


Generated from doc/feature-inventory.json · id xc-file-manager · commit 276788ca6