Plugin Studio header: language, map engine and Settings set the props every plugin gets
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.
This commit is contained in:
parent
2509a6e347
commit
c727c87411
18 changed files with 178 additions and 58 deletions
|
|
@ -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"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 टोकन नहीं चाहिए"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 令牌"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,34 +83,9 @@
|
|||
app-wrapper-material/languages.js (persisted, offline, no dep) — same switcher as the SPA. -->
|
||||
<template #meta>
|
||||
<span class="ps-count">{{ countLabel }}</span>
|
||||
<!-- MAP TOKEN (Driver request 2026-09-25): paste a Mapbox public token, or point the studio at a
|
||||
token service (e.g. https://doxa.life/api/maps/token). Kept in THIS browser only; every map
|
||||
pane (and every map nested inside a composite) is re-mounted with it. -->
|
||||
<span class="ps-token">
|
||||
<button type="button" class="ps-locale-btn ps-token-btn" :aria-expanded="String(tokenOpen)"
|
||||
:title="tokenStatus" @click="tokenOpen = !tokenOpen">
|
||||
<span aria-hidden="true">🔑</span>
|
||||
<span class="ps-locale-name">{{ tr('mapToken') }}</span>
|
||||
<span class="ps-token-dot" :class="'is-' + tokenSource" aria-hidden="true"></span>
|
||||
</button>
|
||||
<form v-if="tokenOpen" class="ps-token-panel" @submit.prevent="applyToken">
|
||||
<label class="ps-token-label">{{ tr('tokenPaste') }}
|
||||
<input class="ps-token-input" v-model.trim="tokenDraft" placeholder="pk.eyJ…" autocomplete="off" spellcheck="false" />
|
||||
</label>
|
||||
<label class="ps-token-label">{{ tr('tokenUrlLabel') }}
|
||||
<input class="ps-token-input" v-model.trim="urlDraft" type="url" placeholder="https://doxa.life/api/maps/token" autocomplete="off" spellcheck="false" />
|
||||
</label>
|
||||
<div class="ps-token-row">
|
||||
<button type="submit" class="ps-token-apply" :disabled="tokenBusy">{{ tr('tokenApply') }}</button>
|
||||
<button type="button" class="ps-token-clear" @click="clearToken">{{ tr('tokenClear') }}</button>
|
||||
</div>
|
||||
<p class="ps-token-status" :class="{ err: !!tokenErr }" role="status">{{ tokenErr || tokenStatus }}</p>
|
||||
<p class="ps-token-note">{{ tr('tokenStoredHere') }}</p>
|
||||
</form>
|
||||
</span>
|
||||
<span class="ps-locale">
|
||||
<button type="button" class="ps-locale-btn" :aria-expanded="String(localeOpen)"
|
||||
:aria-label="tr('changeLanguage')" @click="localeOpen = !localeOpen">
|
||||
:aria-label="tr('changeLanguage')" @click="localeOpen = !localeOpen; engineOpen = false; settingsOpen = false">
|
||||
<span class="ps-flag">{{ activeLang.flag }}</span>
|
||||
<span class="ps-locale-name">{{ activeLang.nativeName }}</span>
|
||||
<span class="ps-dots" aria-hidden="true">⋮</span>
|
||||
|
|
@ -125,6 +100,49 @@
|
|||
</li>
|
||||
</ul>
|
||||
</span>
|
||||
<!-- THE HEADER SETS THE PROPS EVERY PLUGIN GETS (Driver, 2026-09-25): language (above), the map
|
||||
ENGINE, and — under Settings — the Mapbox token or the URL it comes from. Each is kept in THIS
|
||||
browser (localStorage), handed to every pane as its profile-config prop, and published on the
|
||||
window for maps nested inside composites; changing one re-mounts the maps. -->
|
||||
<span class="ps-locale ps-engine">
|
||||
<button type="button" class="ps-locale-btn" :aria-expanded="String(engineOpen)"
|
||||
:aria-label="tr('mapEngine')" :title="tr('mapEngine')" @click="engineOpen = !engineOpen; localeOpen = false; settingsOpen = false">
|
||||
<span aria-hidden="true">🗺</span>
|
||||
<span class="ps-locale-name">{{ engineLabel }}</span>
|
||||
<span class="ps-dots" aria-hidden="true">⋮</span>
|
||||
</button>
|
||||
<ul class="ps-locale-menu" v-if="engineOpen" role="listbox" :aria-label="tr('mapEngine')">
|
||||
<li v-for="e in engines" :key="e.id || 'default'" role="option" :aria-selected="String(e.id === userProvider)">
|
||||
<button type="button" class="ps-locale-opt" :class="{ active: e.id === userProvider }" @click="setProvider(e.id)">
|
||||
<span class="ps-locale-name">{{ e.label }}</span>
|
||||
<span class="ps-locale-en">{{ e.note }}</span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</span>
|
||||
<span class="ps-token">
|
||||
<button type="button" class="ps-locale-btn ps-token-btn" :aria-expanded="String(settingsOpen)"
|
||||
:aria-label="tr('settings')" :title="tokenStatus" @click="settingsOpen = !settingsOpen; localeOpen = false; engineOpen = false">
|
||||
<span aria-hidden="true">⚙</span>
|
||||
<span class="ps-locale-name">{{ tr('settings') }}</span>
|
||||
<span class="ps-token-dot" :class="'is-' + tokenSource" aria-hidden="true"></span>
|
||||
</button>
|
||||
<form v-if="settingsOpen" class="ps-token-panel" @submit.prevent="applyToken">
|
||||
<p class="ps-token-head">{{ tr('mapToken') }}</p>
|
||||
<label class="ps-token-label">{{ tr('tokenPaste') }}
|
||||
<input class="ps-token-input" v-model.trim="tokenDraft" placeholder="pk.eyJ…" autocomplete="off" spellcheck="false" />
|
||||
</label>
|
||||
<label class="ps-token-label">{{ tr('tokenUrlLabel') }}
|
||||
<input class="ps-token-input" v-model.trim="urlDraft" type="url" placeholder="https://doxa.life/api/maps/token" autocomplete="off" spellcheck="false" />
|
||||
</label>
|
||||
<div class="ps-token-row">
|
||||
<button type="submit" class="ps-token-apply" :disabled="tokenBusy">{{ tr('tokenApply') }}</button>
|
||||
<button type="button" class="ps-token-clear" @click="clearToken">{{ tr('tokenClear') }}</button>
|
||||
</div>
|
||||
<p class="ps-token-status" :class="{ err: !!tokenErr }" role="status">{{ tokenErr || tokenStatus }}</p>
|
||||
<p class="ps-token-note">{{ tr('tokenStoredHere') }}</p>
|
||||
</form>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<!-- Toolbar strip: the active element's identity and copy-embed. Kept to ONE line on purpose —
|
||||
|
|
@ -192,6 +210,7 @@ import { SWITCHER_LANGUAGES, loadLocale, saveLocale, getLanguage, normaliseLocal
|
|||
// never sent anywhere but Mapbox (the token) or the URL the reader typed (the service).
|
||||
const TOKEN_KEY = 'plugin-studio:mapbox-token'
|
||||
const TOKEN_URL_KEY = 'plugin-studio:mapbox-token-url'
|
||||
const PROVIDER_KEY = 'plugin-studio:map-provider' // 'mapbox' | 'maplibre' | '' (each map's own default)
|
||||
function readStored(k) { try { return (typeof window !== 'undefined' && window.localStorage.getItem(k)) || '' } catch (_) { return '' } }
|
||||
function writeStored(k, v) { try { if (v) window.localStorage.setItem(k, v); else window.localStorage.removeItem(k) } catch (_) { /* storage unavailable */ } }
|
||||
|
||||
|
|
@ -217,6 +236,7 @@ const PS_SHADOW_CSS = `
|
|||
.ps-token-apply { background:#92b195; border-color:#92b195; color:#fff; }
|
||||
.ps-token-apply:disabled { opacity:.6; cursor:progress; }
|
||||
.ps-token-status { margin:0; }
|
||||
.ps-token-head { margin:0; font-weight:600; font-size:12px; }
|
||||
.ps-token-status.err { color:#b3412f; }
|
||||
.ps-token-note { margin:0; color:#6d766e; }
|
||||
.ps-locale { position:relative; display:inline-flex; }
|
||||
|
|
@ -465,7 +485,9 @@ export default defineComponent({
|
|||
locale: this.initialLocale(),
|
||||
localeOpen: false,
|
||||
// Map token control — the reader's own entry, persisted in localStorage (never in the build).
|
||||
tokenOpen: false,
|
||||
settingsOpen: false,
|
||||
engineOpen: false,
|
||||
userProvider: readStored(PROVIDER_KEY),
|
||||
tokenBusy: false,
|
||||
tokenErr: '',
|
||||
tokenDraft: readStored(TOKEN_KEY),
|
||||
|
|
@ -618,6 +640,20 @@ export default defineComponent({
|
|||
effectiveTk() {
|
||||
return this.userTk || this.fetchedTk || this.tk || this.cfg.tk || this.bakedTk || ''
|
||||
},
|
||||
effectiveProvider() {
|
||||
const p = this.userProvider || this.provider || this.cfg.provider || ''
|
||||
return p === 'maplibre' || p === 'mapbox' ? p : ''
|
||||
},
|
||||
engines() {
|
||||
return [
|
||||
{ id: '', label: this.tr('engineDefault'), note: '' },
|
||||
{ id: 'mapbox', label: 'Mapbox', note: this.tr('engineMapboxNote') },
|
||||
{ id: 'maplibre', label: 'MapLibre', note: this.tr('engineMaplibreNote') },
|
||||
]
|
||||
},
|
||||
engineLabel() {
|
||||
return this.userProvider === 'mapbox' ? 'Mapbox' : this.userProvider === 'maplibre' ? 'MapLibre' : this.tr('engineDefault')
|
||||
},
|
||||
tokenSource() {
|
||||
if (this.userTk) return 'yours'
|
||||
if (this.fetchedTk) return 'url'
|
||||
|
|
@ -625,6 +661,7 @@ export default defineComponent({
|
|||
return 'none'
|
||||
},
|
||||
tokenStatus() {
|
||||
if (this.effectiveProvider === 'maplibre') return this.tr('tokenNotNeeded')
|
||||
if (this.tokenSource === 'yours') return this.tr('tokenSourceYours')
|
||||
if (this.tokenSource === 'url') return this.tr('tokenSourceUrl', { url: this.userTokenUrl })
|
||||
if (this.tokenSource === 'built') return this.tr('tokenSourceBuilt')
|
||||
|
|
@ -643,6 +680,7 @@ export default defineComponent({
|
|||
mounted() {
|
||||
// Read once: after applyToken sets window.MAP_TOKEN it would no longer be "the page's own".
|
||||
this.bakedTk = (typeof window !== 'undefined' && window.MAP_TOKEN) || ''
|
||||
if (this.userProvider) this.publishProvider()
|
||||
if (this.userTk) this.publishToken()
|
||||
else if (this.userTokenUrl) this.fetchToken(this.userTokenUrl).then((t) => { if (t) { this.fetchedTk = t; this.publishToken() } }).catch(() => {})
|
||||
this.loadManifest()
|
||||
|
|
@ -684,9 +722,24 @@ export default defineComponent({
|
|||
writeStored(TOKEN_URL_KEY, this.userTokenUrl)
|
||||
this.publishToken()
|
||||
this.remountPanes()
|
||||
this.tokenOpen = false
|
||||
this.settingsOpen = false
|
||||
} finally { this.tokenBusy = false }
|
||||
},
|
||||
setProvider(id) {
|
||||
this.engineOpen = false
|
||||
if (id === this.userProvider) return
|
||||
this.userProvider = id
|
||||
writeStored(PROVIDER_KEY, id)
|
||||
this.publishProvider()
|
||||
this.remountPanes()
|
||||
},
|
||||
// Maps nested inside a composite fall back to window.MAP_PROVIDER (resolveMapProvider's ladder:
|
||||
// profile-config.provider → ?provider= → window.MAP_PROVIDER), so the choice is published there too.
|
||||
publishProvider() {
|
||||
if (typeof window === 'undefined') return
|
||||
if (this.effectiveProvider) window.MAP_PROVIDER = this.effectiveProvider
|
||||
else if ('MAP_PROVIDER' in window) delete window.MAP_PROVIDER
|
||||
},
|
||||
clearToken() {
|
||||
this.tokenDraft = ''; this.urlDraft = ''; this.tokenErr = ''
|
||||
this.userTk = ''; this.userTokenUrl = ''; this.fetchedTk = ''
|
||||
|
|
@ -744,8 +797,7 @@ export default defineComponent({
|
|||
const pc = { profile: row.profile, instanceId: 'ps-' + row.key.replace(/\//g, '-'), locale }
|
||||
if (this.effectiveTk) pc.tk = this.effectiveTk
|
||||
if (this.tokenUrl || this.cfg.tokenUrl) pc.tokenUrl = this.tokenUrl || this.cfg.tokenUrl
|
||||
const wantProvider = this.provider || this.cfg.provider
|
||||
if (wantProvider === 'maplibre' || wantProvider === 'mapbox') pc.provider = wantProvider
|
||||
if (this.effectiveProvider) pc.provider = this.effectiveProvider
|
||||
if (this.base) pc.treeBase = this.base
|
||||
return pc
|
||||
},
|
||||
|
|
@ -1019,6 +1071,7 @@ export default defineComponent({
|
|||
.ps-token-apply { background:#92b195; border-color:#92b195; color:#fff; }
|
||||
.ps-token-apply:disabled { opacity:.6; cursor:progress; }
|
||||
.ps-token-status { margin:0; }
|
||||
.ps-token-head { margin:0; font-weight:600; font-size:12px; }
|
||||
.ps-token-status.err { color:#b3412f; }
|
||||
.ps-token-note { margin:0; color:#6d766e; }
|
||||
.ps-locale { position: relative; display: inline-flex; }
|
||||
|
|
|
|||
|
|
@ -782,7 +782,7 @@
|
|||
"bundle": "plugin-studio",
|
||||
"scriptUrl": "./plugin-studio/plugin-studio.js",
|
||||
"output": "dx-maps/plugin-studio/plugin-studio.js",
|
||||
"integrity": "sha384-iwq2RhhEc/Rx5dfEVoxYtxYjBd+1w47smMC8IDs0VglbZBt9RqwzrFu0SOuPGrBd",
|
||||
"integrity": "sha384-diiEvybWLwF+XuXh9aAkhzgJCZN9bPezKiAd6ANxLVjR1kHXSg4T+XFI7XHrX0Zb",
|
||||
"elements": [
|
||||
"plugin-studio"
|
||||
],
|
||||
|
|
@ -810,7 +810,7 @@
|
|||
"scriptUrl": "./plugin-studio/plugin-studio.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./plugin-studio/plugin-studio/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./plugin-studio/plugin-studio.js\" integrity=\"sha384-iwq2RhhEc/Rx5dfEVoxYtxYjBd+1w47smMC8IDs0VglbZBt9RqwzrFu0SOuPGrBd\" crossorigin=\"anonymous\"></script>\n<plugin-studio profile-config='{\"profile\":\"plugin-studio\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></plugin-studio>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./plugin-studio/plugin-studio.js\" integrity=\"sha384-diiEvybWLwF+XuXh9aAkhzgJCZN9bPezKiAd6ANxLVjR1kHXSg4T+XFI7XHrX0Zb\" crossorigin=\"anonymous\"></script>\n<plugin-studio profile-config='{\"profile\":\"plugin-studio\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></plugin-studio>"
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -14,6 +14,6 @@
|
|||
</head>
|
||||
<body>
|
||||
<plugin-studio tree-base="."></plugin-studio>
|
||||
<script src="./plugin-studio/plugin-studio.js" integrity="sha384-iwq2RhhEc/Rx5dfEVoxYtxYjBd+1w47smMC8IDs0VglbZBt9RqwzrFu0SOuPGrBd" crossorigin="anonymous"></script>
|
||||
<script src="./plugin-studio/plugin-studio.js" integrity="sha384-diiEvybWLwF+XuXh9aAkhzgJCZN9bPezKiAd6ANxLVjR1kHXSg4T+XFI7XHrX0Zb" crossorigin="anonymous"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -782,7 +782,7 @@
|
|||
"bundle": "plugin-studio",
|
||||
"scriptUrl": "./plugin-studio/plugin-studio.js",
|
||||
"output": "dx-maps/plugin-studio/plugin-studio.js",
|
||||
"integrity": "sha384-iwq2RhhEc/Rx5dfEVoxYtxYjBd+1w47smMC8IDs0VglbZBt9RqwzrFu0SOuPGrBd",
|
||||
"integrity": "sha384-diiEvybWLwF+XuXh9aAkhzgJCZN9bPezKiAd6ANxLVjR1kHXSg4T+XFI7XHrX0Zb",
|
||||
"elements": [
|
||||
"plugin-studio"
|
||||
],
|
||||
|
|
@ -810,7 +810,7 @@
|
|||
"scriptUrl": "./plugin-studio/plugin-studio.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./plugin-studio/plugin-studio/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./plugin-studio/plugin-studio.js\" integrity=\"sha384-iwq2RhhEc/Rx5dfEVoxYtxYjBd+1w47smMC8IDs0VglbZBt9RqwzrFu0SOuPGrBd\" crossorigin=\"anonymous\"></script>\n<plugin-studio profile-config='{\"profile\":\"plugin-studio\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></plugin-studio>"
|
||||
"script": "<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./plugin-studio/plugin-studio.js\" integrity=\"sha384-diiEvybWLwF+XuXh9aAkhzgJCZN9bPezKiAd6ANxLVjR1kHXSg4T+XFI7XHrX0Zb\" crossorigin=\"anonymous\"></script>\n<plugin-studio profile-config='{\"profile\":\"plugin-studio\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></plugin-studio>"
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <plugin-studio> custom element. -->
|
||||
<script src="../plugin-studio.js" integrity="sha384-iwq2RhhEc/Rx5dfEVoxYtxYjBd+1w47smMC8IDs0VglbZBt9RqwzrFu0SOuPGrBd" crossorigin="anonymous"></script>
|
||||
<script src="../plugin-studio.js" integrity="sha384-diiEvybWLwF+XuXh9aAkhzgJCZN9bPezKiAd6ANxLVjR1kHXSg4T+XFI7XHrX0Zb" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <plugin-studio> custom element. -->
|
||||
<script src="../../plugin-studio.js" integrity="sha384-iwq2RhhEc/Rx5dfEVoxYtxYjBd+1w47smMC8IDs0VglbZBt9RqwzrFu0SOuPGrBd" crossorigin="anonymous"></script>
|
||||
<script src="../../plugin-studio.js" integrity="sha384-diiEvybWLwF+XuXh9aAkhzgJCZN9bPezKiAd6ANxLVjR1kHXSg4T+XFI7XHrX0Zb" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
Loading…
Reference in a new issue