From c727c874113208483dff25f00bcb63ab4cc949e1 Mon Sep 17 00:00:00 2001
From: doxa-maps-88655c70
<88627970+doxa-maps-88655c70@users.noreply.github.com>
Date: Fri, 25 Sep 2026 19:19:07 +0000
Subject: [PATCH 1/2] Plugin Studio header: language, map engine and Settings
set the props every plugin gets
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Driver, 2026-09-25: "the studio at the top needs a localization dropdown, a map dropdown to swap
between Mapbox and MapLibre, and a settings button to add a Mapbox token or the URL it comes from…
the header needs to let you swap between props… so the studio becomes more functionally useful."
The header now reads: Language ▾ · 🗺 Map engine ▾ · ⚙ Settings.
- Map engine: Mapbox (needs a token) / MapLibre (no token needed) / each map's own default. The choice
is handed to every pane as its profile-config provider and published as window.MAP_PROVIDER for
maps nested inside composites; changing it re-mounts the maps.
- ⚙ Settings replaces the separate 🔑 button: the Mapbox public token (sk.… refused) or a token-service
URL, with a status line that says which is in use — and that MapLibre needs none.
- Kept in this browser (localStorage); one menu open at a time. New labels in all 11 locales.
Browser-tested on the built dx-maps tree: the header shows the three controls; MapLibre sets the pane's
provider and window.MAP_PROVIDER and survives a reload; Settings then says no token is needed; Mapbox
plus a pasted token puts both on the pane; "each map's own" clears the provider.
---
library/i18n/locales/ar/studio.json | 8 +-
library/i18n/locales/de/studio.json | 8 +-
library/i18n/locales/en/studio.json | 8 +-
library/i18n/locales/es/studio.json | 8 +-
library/i18n/locales/fr/studio.json | 8 +-
library/i18n/locales/hi/studio.json | 8 +-
library/i18n/locales/it/studio.json | 8 +-
library/i18n/locales/pt/studio.json | 8 +-
library/i18n/locales/ro/studio.json | 8 +-
library/i18n/locales/ru/studio.json | 8 +-
library/i18n/locales/zh/studio.json | 8 +-
.../plugin-studio/plugin-studio.vue | 113 +++++++++++++-----
public/dx-maps/doxa-maps-spa/manifest.json | 4 +-
public/dx-maps/index.html | 2 +-
public/dx-maps/manifest.json | 4 +-
public/dx-maps/plugin-studio/plugin-studio.js | 21 ++--
.../plugin-studio/plugin-studio/index.html | 2 +-
.../plugin-studio/studio/index.html | 2 +-
18 files changed, 178 insertions(+), 58 deletions(-)
diff --git a/library/i18n/locales/ar/studio.json b/library/i18n/locales/ar/studio.json
index c3b519408..faa061824 100644
--- a/library/i18n/locales/ar/studio.json
+++ b/library/i18n/locales/ar/studio.json
@@ -39,5 +39,11 @@
"tokenSourceNone": "لا يوجد رمز Mapbox: لا يمكن تحميل خرائط Mapbox (خرائط MapLibre لا تحتاج رمزًا)",
"tokenSecret": "هذا رمز سري (sk.…). الصق رمزًا عامًا (pk.…): هذه الصفحة عامة.",
"tokenNotPk": "يبدأ رمز Mapbox العام بـ pk.",
- "tokenUrlFailed": "تعذّر الحصول على رمز من هذا الرابط: {why}"
+ "tokenUrlFailed": "تعذّر الحصول على رمز من هذا الرابط: {why}",
+ "settings": "الإعدادات",
+ "mapEngine": "محرّك الخرائط",
+ "engineDefault": "الافتراضي لكل خريطة",
+ "engineMapboxNote": "يحتاج إلى رمز",
+ "engineMaplibreNote": "لا يحتاج إلى رمز",
+ "tokenNotNeeded": "تم اختيار MapLibre: خرائطه لا تحتاج إلى رمز Mapbox"
}
diff --git a/library/i18n/locales/de/studio.json b/library/i18n/locales/de/studio.json
index 5210ca9d5..8e9f1c2f1 100644
--- a/library/i18n/locales/de/studio.json
+++ b/library/i18n/locales/de/studio.json
@@ -39,5 +39,11 @@
"tokenSourceNone": "Kein Mapbox-Token: Mapbox-Karten können nicht laden (MapLibre-Karten brauchen keinen)",
"tokenSecret": "Das ist ein geheimer Token (sk.…). Fügen Sie einen öffentlichen ein (pk.…): Diese Seite ist öffentlich.",
"tokenNotPk": "Ein öffentlicher Mapbox-Token beginnt mit pk.",
- "tokenUrlFailed": "Von dieser URL kam kein Token: {why}"
+ "tokenUrlFailed": "Von dieser URL kam kein Token: {why}",
+ "settings": "Einstellungen",
+ "mapEngine": "Karten-Engine",
+ "engineDefault": "Je Karte eigenes",
+ "engineMapboxNote": "braucht einen Token",
+ "engineMaplibreNote": "kein Token nötig",
+ "tokenNotNeeded": "MapLibre ist gewählt: Seine Karten brauchen keinen Mapbox-Token"
}
diff --git a/library/i18n/locales/en/studio.json b/library/i18n/locales/en/studio.json
index cc8ff20ef..d7b826e92 100644
--- a/library/i18n/locales/en/studio.json
+++ b/library/i18n/locales/en/studio.json
@@ -39,5 +39,11 @@
"tokenSourceNone": "No Mapbox token: Mapbox maps cannot load (MapLibre maps need none)",
"tokenSecret": "That is a secret token (sk.…). Paste a public one (pk.…): this page is public.",
"tokenNotPk": "A Mapbox public token starts with pk.",
- "tokenUrlFailed": "Could not get a token from that URL: {why}"
+ "tokenUrlFailed": "Could not get a token from that URL: {why}",
+ "settings": "Settings",
+ "mapEngine": "Map engine",
+ "engineDefault": "Each map’s own",
+ "engineMapboxNote": "needs a token",
+ "engineMaplibreNote": "no token needed",
+ "tokenNotNeeded": "MapLibre is selected: its maps need no Mapbox token"
}
diff --git a/library/i18n/locales/es/studio.json b/library/i18n/locales/es/studio.json
index bc46827d9..6972a60f2 100644
--- a/library/i18n/locales/es/studio.json
+++ b/library/i18n/locales/es/studio.json
@@ -39,5 +39,11 @@
"tokenSourceNone": "Sin token de Mapbox: los mapas de Mapbox no cargan (los de MapLibre no lo necesitan)",
"tokenSecret": "Ese es un token secreto (sk.…). Pega uno público (pk.…): esta página es pública.",
"tokenNotPk": "Un token público de Mapbox empieza por pk.",
- "tokenUrlFailed": "No se pudo obtener un token de esa URL: {why}"
+ "tokenUrlFailed": "No se pudo obtener un token de esa URL: {why}",
+ "settings": "Ajustes",
+ "mapEngine": "Motor de mapas",
+ "engineDefault": "El de cada mapa",
+ "engineMapboxNote": "necesita un token",
+ "engineMaplibreNote": "no necesita token",
+ "tokenNotNeeded": "MapLibre está seleccionado: sus mapas no necesitan token de Mapbox"
}
diff --git a/library/i18n/locales/fr/studio.json b/library/i18n/locales/fr/studio.json
index 087d3e54e..a80829f4b 100644
--- a/library/i18n/locales/fr/studio.json
+++ b/library/i18n/locales/fr/studio.json
@@ -39,5 +39,11 @@
"tokenSourceNone": "Aucun jeton Mapbox : les cartes Mapbox ne peuvent pas charger (MapLibre n’en a pas besoin)",
"tokenSecret": "C’est un jeton secret (sk.…). Collez un jeton public (pk.…) : cette page est publique.",
"tokenNotPk": "Un jeton public Mapbox commence par pk.",
- "tokenUrlFailed": "Impossible d’obtenir un jeton depuis cette URL : {why}"
+ "tokenUrlFailed": "Impossible d’obtenir un jeton depuis cette URL : {why}",
+ "settings": "Paramètres",
+ "mapEngine": "Moteur de carte",
+ "engineDefault": "Celui de chaque carte",
+ "engineMapboxNote": "nécessite un jeton",
+ "engineMaplibreNote": "aucun jeton requis",
+ "tokenNotNeeded": "MapLibre est sélectionné : ses cartes n’ont pas besoin de jeton Mapbox"
}
diff --git a/library/i18n/locales/hi/studio.json b/library/i18n/locales/hi/studio.json
index 050f635d3..47d7f54ff 100644
--- a/library/i18n/locales/hi/studio.json
+++ b/library/i18n/locales/hi/studio.json
@@ -39,5 +39,11 @@
"tokenSourceNone": "कोई Mapbox टोकन नहीं: Mapbox मानचित्र लोड नहीं हो सकते (MapLibre को इसकी ज़रूरत नहीं)",
"tokenSecret": "यह एक गुप्त टोकन है (sk.…)। सार्वजनिक टोकन (pk.…) चिपकाएँ: यह पेज सार्वजनिक है।",
"tokenNotPk": "Mapbox सार्वजनिक टोकन pk. से शुरू होता है",
- "tokenUrlFailed": "उस URL से टोकन नहीं मिल सका: {why}"
+ "tokenUrlFailed": "उस URL से टोकन नहीं मिल सका: {why}",
+ "settings": "सेटिंग्स",
+ "mapEngine": "मानचित्र इंजन",
+ "engineDefault": "हर मानचित्र का अपना",
+ "engineMapboxNote": "टोकन चाहिए",
+ "engineMaplibreNote": "टोकन की ज़रूरत नहीं",
+ "tokenNotNeeded": "MapLibre चुना गया है: इसके मानचित्रों को Mapbox टोकन नहीं चाहिए"
}
diff --git a/library/i18n/locales/it/studio.json b/library/i18n/locales/it/studio.json
index ac41b6df7..350287008 100644
--- a/library/i18n/locales/it/studio.json
+++ b/library/i18n/locales/it/studio.json
@@ -39,5 +39,11 @@
"tokenSourceNone": "Nessun token Mapbox: le mappe Mapbox non si caricano (MapLibre non ne ha bisogno)",
"tokenSecret": "Questo è un token segreto (sk.…). Incolla un token pubblico (pk.…): questa pagina è pubblica.",
"tokenNotPk": "Un token pubblico Mapbox inizia con pk.",
- "tokenUrlFailed": "Impossibile ottenere un token da quell’URL: {why}"
+ "tokenUrlFailed": "Impossibile ottenere un token da quell’URL: {why}",
+ "settings": "Impostazioni",
+ "mapEngine": "Motore mappe",
+ "engineDefault": "Quello di ogni mappa",
+ "engineMapboxNote": "richiede un token",
+ "engineMaplibreNote": "nessun token necessario",
+ "tokenNotNeeded": "MapLibre è selezionato: le sue mappe non richiedono un token Mapbox"
}
diff --git a/library/i18n/locales/pt/studio.json b/library/i18n/locales/pt/studio.json
index 9a824c894..aeca3abfb 100644
--- a/library/i18n/locales/pt/studio.json
+++ b/library/i18n/locales/pt/studio.json
@@ -39,5 +39,11 @@
"tokenSourceNone": "Sem token do Mapbox: os mapas Mapbox não carregam (os MapLibre não precisam)",
"tokenSecret": "Esse é um token secreto (sk.…). Cole um público (pk.…): esta página é pública.",
"tokenNotPk": "Um token público do Mapbox começa por pk.",
- "tokenUrlFailed": "Não foi possível obter um token desse URL: {why}"
+ "tokenUrlFailed": "Não foi possível obter um token desse URL: {why}",
+ "settings": "Definições",
+ "mapEngine": "Motor de mapas",
+ "engineDefault": "O de cada mapa",
+ "engineMapboxNote": "precisa de um token",
+ "engineMaplibreNote": "não precisa de token",
+ "tokenNotNeeded": "MapLibre está selecionado: os seus mapas não precisam de token do Mapbox"
}
diff --git a/library/i18n/locales/ro/studio.json b/library/i18n/locales/ro/studio.json
index 6665219ea..6f4a26b87 100644
--- a/library/i18n/locales/ro/studio.json
+++ b/library/i18n/locales/ro/studio.json
@@ -39,5 +39,11 @@
"tokenSourceNone": "Niciun token Mapbox: hărțile Mapbox nu se pot încărca (MapLibre nu are nevoie)",
"tokenSecret": "Acesta este un token secret (sk.…). Lipește unul public (pk.…): pagina este publică.",
"tokenNotPk": "Un token public Mapbox începe cu pk.",
- "tokenUrlFailed": "Nu s-a putut obține un token de la acea adresă: {why}"
+ "tokenUrlFailed": "Nu s-a putut obține un token de la acea adresă: {why}",
+ "settings": "Setări",
+ "mapEngine": "Motor hărți",
+ "engineDefault": "Al fiecărei hărți",
+ "engineMapboxNote": "necesită un token",
+ "engineMaplibreNote": "nu necesită token",
+ "tokenNotNeeded": "MapLibre este selectat: hărțile sale nu necesită token Mapbox"
}
diff --git a/library/i18n/locales/ru/studio.json b/library/i18n/locales/ru/studio.json
index 877fb6f0f..7447b0c47 100644
--- a/library/i18n/locales/ru/studio.json
+++ b/library/i18n/locales/ru/studio.json
@@ -39,5 +39,11 @@
"tokenSourceNone": "Нет токена Mapbox: карты Mapbox не загрузятся (MapLibre он не нужен)",
"tokenSecret": "Это секретный токен (sk.…). Вставьте публичный (pk.…): эта страница общедоступна.",
"tokenNotPk": "Публичный токен Mapbox начинается с pk.",
- "tokenUrlFailed": "Не удалось получить токен по этому адресу: {why}"
+ "tokenUrlFailed": "Не удалось получить токен по этому адресу: {why}",
+ "settings": "Настройки",
+ "mapEngine": "Движок карт",
+ "engineDefault": "Свой у каждой карты",
+ "engineMapboxNote": "нужен токен",
+ "engineMaplibreNote": "токен не нужен",
+ "tokenNotNeeded": "Выбран MapLibre: его картам не нужен токен Mapbox"
}
diff --git a/library/i18n/locales/zh/studio.json b/library/i18n/locales/zh/studio.json
index df56e8091..a9aa023d6 100644
--- a/library/i18n/locales/zh/studio.json
+++ b/library/i18n/locales/zh/studio.json
@@ -39,5 +39,11 @@
"tokenSourceNone": "没有 Mapbox 令牌:Mapbox 地图无法加载(MapLibre 地图不需要)",
"tokenSecret": "这是秘密令牌 (sk.…)。请粘贴公开令牌 (pk.…):此页面是公开的。",
"tokenNotPk": "Mapbox 公开令牌以 pk. 开头",
- "tokenUrlFailed": "无法从该网址获取令牌:{why}"
+ "tokenUrlFailed": "无法从该网址获取令牌:{why}",
+ "settings": "设置",
+ "mapEngine": "地图引擎",
+ "engineDefault": "各地图自身的",
+ "engineMapboxNote": "需要令牌",
+ "engineMaplibreNote": "无需令牌",
+ "tokenNotNeeded": "已选择 MapLibre:其地图无需 Mapbox 令牌"
}
diff --git a/plugin-designs/plugin-studio/plugin-studio.vue b/plugin-designs/plugin-studio/plugin-studio.vue
index baee84bf5..84961b822 100644
--- a/plugin-designs/plugin-studio/plugin-studio.vue
+++ b/plugin-designs/plugin-studio/plugin-studio.vue
@@ -83,34 +83,9 @@
app-wrapper-material/languages.js (persisted, offline, no dep) — same switcher as the SPA. -->
{{ countLabel }}
-
-
-
-
-
+
+
+
+