feat(viewer): Artistic Introduction pages + exporter data fixes (#1420)
Commit: ffdd2a0b6eb55ac63277fc99ef0fab7fefda1966
Date: 2026-07-05 01:29:55 +0200
Author: PascalHavelange
Commit Message
feat(viewer): Artistic Introduction pages + exporter data fixes (#1420)
* feat(viewer): add Artistic Introduction pages; fix exporter data gaps
Ports the legacy "Artistic Introduction" (gai) feature: a splash page
listing themes (e.g. "The Umayyads") and a per-theme page with
Monuments/Objects tabs, a thumbnail grid, and a detail panel showing
per-item captions and curatorial justification text, linking through
to the existing item detail page.
Getting there required two exporter fixes, since collections.json
didn't carry what the feature needs:
- internal_name is now included in the output, the only reliable way
to identify artintro collections among the many other features that
reuse the same generic `type` values.
- collection_item.extra (per-item caption/override text) is now
selected and mapped into a `caption` field per item, instead of only
exporting bare item ids.
Both fixes exposed a latent bug: parseJson() assumed MySQL JSON
columns came back as strings, but mysql2 auto-decodes them to
objects, so JSON.parse(object) silently threw and returned null.
Fixed in collection-exporter, item-exporter (monument history/patrons,
picture photographer/copyright), and partner-exporter (contact
persons, image credits).
The viewer also works around a handful of legacy translation gaps
where the importer falls back to a synthetic placeholder title
(e.g. "Artintro Page 17") when a language's page_title is empty --
falls back to the English title instead of leaking the placeholder.
* fix(tools): add README to tools
* fix (artistic introductions)
Added [artintro-root-collection-importer.ts](scripts/importer/src/importers/phase-01/artintro-root-collection-importer.ts) — a new `ArtintroRootCollectionImporter`, following the exact same shape as `ThgRootCollectionsImporter`/`ExploreRootCollectionsImporter`/`TravelsRootCollectionImporter`: idempotent (skips if `mwnf3:artintro:root` already exists), creates one "Artistic Introduction" collection as a child of the ISL project collection, with a translation.
Wired it into the pipeline:
- Registered in [phase-01/index.ts](scripts/importer/src/importers/phase-01/index.ts), [importers/index.ts](scripts/importer/src/importers/index.ts), and the CLI's dependency graph in [import.ts](scripts/importer/src/cli/import.ts) — runs after `project`/`language`, before `mwnf3-exhibition`.
- Updated [mwnf3-exhibition-importer.ts](scripts/importer/src/importers/phase-01/mwnf3-exhibition-importer.ts) so the existing artintro root (`mwnf3:artintros:1`) now nests under this new marker collection instead of directly under the ISL project collection — same `mwnf3:artintro:root` backward_compatibility key your exporter fix would key off of later.
**Verified** (type-check clean, lint clean, and dry-run against the real project/target DB via the tunnel — read-only, no writes):
- `artintro-root-collection` alone: correctly finds the ISL project collection and reports it would create the marker.
- `mwnf3-exhibition` with the new parent-lookup logic: no runtime errors.
* refactor(viewer,exporter): detect Artistic Introduction via parent collection
Now that ArtintroRootCollectionImporter creates a dedicated "Artistic
Introduction" marker collection (mwnf3:artintro:root, child of the ISL
project collection), the viewer no longer needs to guess membership
from internal_name prefixes.
- collection-exporter.ts: expose backward_compatibility on each
collection, so the marker can be resolved by its stable key.
- useInventoryData.js: resolve the artintro root as the marker's child,
then walk parent_id alone for themes and pages -- no internal_name
matching left in the detection path.
Requires the pending re-import to create the marker and reparent the
artintro root under it. Until then, the composable resolves no marker,
so the feature degrades gracefully to "not available" (verified: no
console errors, no crash) rather than silently going back to guessing.
* feat(viewer,importer,exporter): add Exhibitions pages
Ports the legacy "Exhibitions" feature: a splash page listing ISL
exhibitions, a per-exhibition splash (intro text + "Introduction" link
+ theme list), an Introduction page (exhibition-level text + directly
attached items), and a theme page (Monuments/Objects-style page tabs,
thumbnail grid, detail panel with per-item captions/justification, and
a multi-variant "detail" selector for items that have curated close-up
sub-images), linking through to the existing item detail page.
Same gap as Artistic Introduction: neither type='exhibition' nor the
mwnf3:exhibitions:{id} backward_compatibility key are project-scoped
in the legacy schema (shared with Baroque Art, Sharing History, THG).
Added ExhibitionsRootCollectionImporter (mirrors
ArtintroRootCollectionImporter) to create an unambiguous "Exhibitions"
marker collection under the ISL project collection; ISL exhibitions
now nest under it while every other project's exhibitions keep nesting
directly under their own project collection, unchanged. Exporter/viewer
resolve it by backward_compatibility with graceful degradation (no
crash) if the marker isn't present yet -- same pattern as artintro,
pending the upcoming re-import.
Also fixes a real, confirmed exporter bug found along the way:
collection_item.extra.details (nested "detail" sub-images -- close-up
variants of the same item, actively used by the Baroque Art project)
was imported into the DB but silently dropped by the exporter. Now
surfaced as a details[] array per item entry.
---------
Co-authored-by: Pascal HAVELANGE <havelangep@hotmail.com>
Files Changed
- ✅ Added:
scripts/exporter/README.md - 📝 Modified:
scripts/exporter/src/exporters/collection-exporter.ts - 📝 Modified:
scripts/exporter/src/exporters/item-exporter.ts - 📝 Modified:
scripts/exporter/src/exporters/partner-exporter.ts - 📝 Modified:
scripts/importer/README.md - 📝 Modified:
scripts/importer/src/cli/import.ts - 📝 Modified:
scripts/importer/src/importers/index.ts - ✅ Added:
scripts/importer/src/importers/phase-01/artintro-root-collection-importer.ts - ✅ Added:
scripts/importer/src/importers/phase-01/exhibitions-root-collection-importer.ts - 📝 Modified:
scripts/importer/src/importers/phase-01/index.ts - 📝 Modified:
scripts/importer/src/importers/phase-01/mwnf3-exhibition-importer.ts - 📝 Modified:
scripts/viewer/README.md - 📝 Modified:
scripts/viewer/package-lock.json - 📝 Modified:
scripts/viewer/package.json - 📝 Modified:
scripts/viewer/src/App.vue - 📝 Modified:
scripts/viewer/src/composables/useInventoryData.js - 📝 Modified:
scripts/viewer/src/router/index.js - ✅ Added:
scripts/viewer/src/views/ArtIntroEntrance.vue - ✅ Added:
scripts/viewer/src/views/ArtIntroTheme.vue - ✅ Added:
scripts/viewer/src/views/ExhibitionIntroduction.vue - ✅ Added:
scripts/viewer/src/views/ExhibitionSplash.vue - ✅ Added:
scripts/viewer/src/views/ExhibitionTheme.vue - ✅ Added:
scripts/viewer/src/views/ExhibitionsEntrance.vue - 📝 Modified:
scripts/viewer/src/views/Home.vue
Links
This documentation was automatically generated from Git commit data.