feat(app): allow per-map layer labels for shared layers - #861
Merged
Conversation
A layer can be attached to several maps, but its name and menu text were global. A map shared between a German and an English audience therefore had to settle on one language. The `layers_maps` junction row already means "this layer, on this map", so it is the natural place for the label. Two optional fields there, `name` and `menuText`, now override the layer's own labels for that map only. Blank or missing values fall back to the layer, so every existing map keeps its current labels untouched. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The label overrides were only created on the running instance, so a freshly seeded backend did not have them. `layersApi` requests `maps.name` and `maps.menuText`, which then made Directus reject the whole layer query and left the app with no layers to render — the E2E suite saw a blank page. Adding both fields to the snapshot keeps any newly seeded instance in step with the query. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
A layer can be attached to several maps, and that is how content is shared between them. Its
nameandmenuTextare global though, so a layer shown on both a German and an English map has to settle on one language.Approach
The
layers_mapsjunction row already carries the meaning "this layer, on this map", so the per-map label belongs there rather than on the layer or the map.Two optional fields on that junction,
nameandmenuText, override the layer's own labels for that map only.layersApirequests them alongside the existing fields and overlays them after fetching.Blank and missing values fall back to the layer's labels, so every existing map keeps its current labels untouched — no data migration, no behaviour change for maps that never set an override.
Directus fields
The matching fields have been added to
layers_mapson the production instance (both nullable strings,interface: input, with a note explaining the fallback). They are readable by the public role, which the frontend relies on.Verified against the live API: on Docutopia the shared
Bäume/Gärtenlayers resolve toTrees/Gardens, while the German map returns no overrides and keeps the layer labels.Tests
apphad no test setup, so this adds a minimal one:vitestas a dev dependency and atest:unitscript, with thetestblock in the existingapp/vite.config.ts.The label overlay lives in its own module
app/src/api/layerLabels.tsso it can be tested without pulling in the Directus client, which reads env vars at import time. Six cases are covered: override applied, blank override falls back, each label overridden independently, expandedmaps_idobject, junction rows of other maps and dangling rows ignored, and the un-expanded junction left untouched.npx tsc --noEmit,eslint --max-warnings 0andvitest runall pass inapp.🤖 Generated with Claude Code