Skip to content

feat(app): allow per-map layer labels for shared layers - #861

Merged
antontranelis merged 2 commits into
mainfrom
feat/per-map-layer-labels
Aug 29, 2026
Merged

feat(app): allow per-map layer labels for shared layers#861
antontranelis merged 2 commits into
mainfrom
feat/per-map-layer-labels

Conversation

@antontranelis

Copy link
Copy Markdown
Member

Problem

A layer can be attached to several maps, and that is how content is shared between them. Its name and menuText are global though, so a layer shown on both a German and an English map has to settle on one language.

Approach

The layers_maps junction 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, name and menuText, override the layer's own labels for that map only. layersApi requests 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_maps on 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ärten layers resolve to Trees / Gardens, while the German map returns no overrides and keeps the layer labels.

Tests

app had no test setup, so this adds a minimal one: vitest as a dev dependency and a test:unit script, with the test block in the existing app/vite.config.ts.

The label overlay lives in its own module app/src/api/layerLabels.ts so 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, expanded maps_id object, junction rows of other maps and dangling rows ignored, and the un-expanded junction left untouched.

npx tsc --noEmit, eslint --max-warnings 0 and vitest run all pass in app.

🤖 Generated with Claude Code

antontranelis and others added 2 commits August 28, 2026 16:02
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>
@antontranelis
antontranelis merged commit 6aeb18f into main Aug 29, 2026
26 checks passed
@antontranelis
antontranelis deleted the feat/per-map-layer-labels branch August 29, 2026 12:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant