feat(schema): multiple option for image/file fields (ordered media galleries) - #1
feat(schema): multiple option for image/file fields (ordered media galleries)#1Rimander wants to merge 1 commit into
Conversation
…lleries) Adds validation.multiple to image/file fields: the value becomes an ordered array of media values stored in the existing TEXT column, with zod array validation (single<->array round-trip preprocess), per-item MIME allowlist enforcement, media-usage extraction with indexed paths, and runtime normalization per item. The admin gains an "Allow multiple" toggle in the field editor, a multi-select mode in the media picker, and a sortable gallery renderer for image/file fields. Also repairs a corrupt Arabic plural translation (unbalanced ICU braces for "(# item)/(# items)") that crashed any component rendering that count badge in Arabic, including the existing RepeaterField. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Scope checkThis PR changes 1,048 lines across 17 files. Large PRs are harder to review and more likely to be closed without review. If this scope is intentional, no action needed. A maintainer will review it. If not, please consider splitting this into smaller PRs. See CONTRIBUTING.md for contribution guidelines. |
|
I have read the CLA Document and I hereby sign the CLA You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot. |
Lunaria Status Overview🌕 This pull request will trigger status changes. Learn moreBy default, every PR changing files present in the Lunaria configuration's You can change this by adding one of the keywords present in the Tracked Files
Warnings reference
|
What does this PR do?
Adds a
multipleoption (stored asvalidation.multiple) toimageandfilefields so editors can manage an ordered set of media on one entry — photo galleries, slideshows, download lists — instead of a single item. This is the "multiple: truemodifier on existing image/file fields" shape requested for gallery-style content, chosen over a newgalleryfield type: the column type is unchanged (TEXT storing JSON), so existing fields can be upgraded in place with no migration, and the flag composes withallowedMimeTypes,minItems/maxItems.Core:
FieldValidation.multiple+ API zod acceptance (fieldValidation), so the flag survives create/update field calls.z.array()whenmultipleis set, applyingminItems/maxItems. Toggle round-trips are safe both ways: a stored single object validates (wrapped into a one-item array) after enablingmultiple, and a one-element array unwraps after disabling it (Auto save validation errors emdash-cms/emdash#867-class autosave protection).gallery[0],gallery[1], …).normalizeMediaFieldsenriches each array item from the media provider.Array<{...}>for multiple fields.Admin:
MediaPickerModalgains an additive multi-select mode (multiple+onSelectMany); single-select behavior is untouched.MultiMediaFieldRendererrenders the ordered list with drag-and-drop reordering (same dnd-kit pattern asRepeaterField) for both image and file fields.Also fixes a corrupt Arabic translation (
{0, plural, one {(# item)} other {(# items)}}had unbalanced ICU braces) that crashed any component rendering that count badge in Arabic — including the pre-existingRepeaterField. This is a surgical one-line repair of a broken catalog entry, not extraction churn; without it the new gallery renderer (which reuses the same msgid) crashes for Arabic users. Reproduced and verified with@lingui/coredirectly.Closes #
Type of change
Checklist
pnpm typecheckpassespnpm lintpassespnpm testpasses (or targeted tests for my change) — full core suite (4690 tests) and admin suite (1100 tests)pnpm formathas been runar/messages.podiff is a deliberate one-line fix of a corrupt ICU plural entry (see description), not extracted catalog churn.AI-generated code disclosure
Screenshots / test output
Verified end-to-end in the
demos/simpledev app (Node + SQLite):imagefield with "Allow multiple" in the field editor;validationpersisted as{"multiple": true}(type staysimage, column stays TEXT).gallery?: Array<{ id: string; ... }>.🤖 Generated with Claude Code