WIP Gospel x Internet adopts the kit's useShareableView for its share links
Query mode, the published names as an alias map (links already shared keep restoring), write only on our own leaves. The board's own writer now keeps only view/group/panel/tree. NOT READY: an old multi-value link (band=yes|partial) reads back as one value until the kit reads '|' on parse; the model check pins that case and fails until it does.
This commit is contained in:
parent
9d7d630fd6
commit
9296aa9cc6
14 changed files with 68 additions and 40 deletions
|
|
@ -23,6 +23,8 @@
|
|||
*/
|
||||
import { ref, computed, onMounted, onBeforeUnmount, watch, getCurrentInstance } from 'vue'
|
||||
import { useDashboardLayout } from '@map/composables/useDashboardLayout.js'
|
||||
import { useShareableView } from '@map/composables/useShareableView.js'
|
||||
import { SHARE_FACETS } from './src/model.js'
|
||||
import { useShadowStyles } from '@map/composables/useShadowStyles.js'
|
||||
import { listLabel } from '@map/lists/peopleGroupList.js'
|
||||
import { useBoard } from './src/useBoard.js'
|
||||
|
|
@ -66,6 +68,11 @@ onBeforeUnmount(() => { if (selTimer) clearTimeout(selTimer) })
|
|||
// board opens already in its state: no flash of the default view, and the first render mounts the panel
|
||||
// the preset asks for (the language tree included) where a headless mount check can see it.
|
||||
board.readUrl()
|
||||
// SHARE LINKS FROM THE KIT (useShareableView, query mode): the filters and the typed search live in the
|
||||
// URL under the board's published names (?access= ?band= ?country= …, the alias map keeps links already
|
||||
// shared working), restored on every load, written ONLY on our own leaves (urlState:'query') so a
|
||||
// partner's address bar is never rewritten. facetKeys is explicit: its default reads nothing on a cold load.
|
||||
useShareableView(bus, { mode: 'query', write: board.profileConfig.value?.urlState === 'query', facetKeys: SHARE_FACETS })
|
||||
|
||||
// ── responsive: one panel at a time under 760px (ResizeObserver on the shell, not @container: a
|
||||
// container query cannot target the container itself, which is unreliable inside a shadow root) ──────
|
||||
|
|
|
|||
|
|
@ -141,6 +141,19 @@ for (const n of ix.nodes) if (!n.p) { const x = scZero.get(n.id); gy += x.g + x.
|
|||
ok(gy === 0, `with only zero-access groups in scope, no family counts a green or yellow language (${gy})`)
|
||||
bus.clearFilters()
|
||||
|
||||
// 12. share links through the kit (useShareableView): the board's published names map to its bus keys,
|
||||
// and a link already shared restores (single values, and multi-values written with '|')
|
||||
const SV = await import(resolve(REPO, 'library/composables/useShareableView.js'))
|
||||
const r1 = SV.parseQuery('?access=bridge&country=IND&wayin=deaf&app=Telegram%20Messenger', M.SHARE_FACETS)
|
||||
ok(r1.filters.access_level === 'bridge' && r1.filters.country === 'IND' && r1.filters.way_in === 'deaf' && r1.filters.messaging === 'Telegram Messenger',
|
||||
'kit parser maps ?access= ?wayin= ?app= to the bus keys (old single-value links restore)')
|
||||
const r2 = SV.parseQuery('?band=yes|partial', M.SHARE_FACETS)
|
||||
ok(Array.isArray(r2.filters.band) && r2.filters.band.join(',') === 'yes,partial', `an old multi-value link (band=yes|partial) restores as two values (got ${JSON.stringify(r2.filters.band)})`)
|
||||
const w = SV.serializeQuery({ access_level: 'bridge', band: ['yes', 'partial'] }, '', '?view=zero&utm_source=x', { facetKeys: M.SHARE_FACETS })
|
||||
ok(w.includes('access=bridge') && w.includes('view=zero') && w.includes('utm_source=x') && !w.includes('access_level'), `the kit writes the published names and keeps the board's own params (${w})`)
|
||||
const mine = M.buildQuery({ view: 'zero', filterSet: { band: 'yes' }, keep: '?band=yes,partial', filters: false })
|
||||
ok(mine.includes('band=yes%2Cpartial') && mine.includes('view=zero'), 'the board\'s own writer leaves the filter params to the kit (filters:false)')
|
||||
|
||||
// 11. translation readiness: current against its snapshot, every roster language present, the no-NT set is
|
||||
// the tree's, the 31 codes Glottolog lacks read as UNKNOWN (null) not "none", and the signal count is a
|
||||
// recount of the five named facts (no hidden weighting)
|
||||
|
|
|
|||
|
|
@ -82,6 +82,9 @@ export const URL_KEYS = {
|
|||
app: 'messaging',
|
||||
}
|
||||
export const VIEWS = ['board', 'zero', 'province', 'platforms']
|
||||
/** The board's URL filter names -> bus keys, for the kit's useShareableView (query mode, alias map).
|
||||
* The published names are kept so links already shared keep restoring. */
|
||||
export const SHARE_FACETS = Object.fromEntries(Object.entries(URL_KEYS))
|
||||
|
||||
/** Parse `?view=&access=…&group=` into { view, filters, group }. Unknown views fall back to board. */
|
||||
export function parseQuery(search) {
|
||||
|
|
@ -109,13 +112,15 @@ export function parseQuery(search) {
|
|||
}
|
||||
|
||||
/** The inverse: filterSet + view + group -> a query string (no leading '?'), stable key order. */
|
||||
export function buildQuery({ view, filterSet, group, keep, panel, tree } = {}) {
|
||||
export function buildQuery({ view, filterSet, group, keep, panel, tree, filters = true } = {}) {
|
||||
const q = new URLSearchParams(keep || '')
|
||||
for (const name of [...Object.keys(URL_KEYS), 'view', 'group', 'panel', 'tree']) q.delete(name)
|
||||
// filters:false = the FILTER params belong to another writer (the kit's useShareableView): neither
|
||||
// delete nor write them, so the two writers never fight over one address bar
|
||||
for (const name of [...(filters ? Object.keys(URL_KEYS) : []), 'view', 'group', 'panel', 'tree']) q.delete(name)
|
||||
if (view && view !== 'board') q.set('view', view)
|
||||
if (panel === 'tree') q.set('panel', 'tree')
|
||||
if (tree) q.set('tree', tree)
|
||||
for (const [name, key] of Object.entries(URL_KEYS)) {
|
||||
if (filters) for (const [name, key] of Object.entries(URL_KEYS)) {
|
||||
if (tree && key === 'language') continue
|
||||
const v = filterSet?.[key]
|
||||
if (v === undefined || v === null || v === '') continue
|
||||
|
|
|
|||
|
|
@ -164,9 +164,12 @@ export function useBoard() {
|
|||
const q = M.parseQuery(location.search)
|
||||
const hostView = cfg().view
|
||||
setView(q.view !== 'board' ? q.view : (M.VIEWS.includes(hostView) ? hostView : 'board'))
|
||||
// Explicit facets in the URL (or the host's profile-config `filters`) narrow the preset further.
|
||||
// The host's profile-config `filters` narrow the preset; URL FILTER params are read by the kit's
|
||||
// useShareableView (board.vue), except Gospel Resources' ?codes= / ?code=, which are this board's.
|
||||
const hostFilters = cfg().filters && typeof cfg().filters === 'object' ? cfg().filters : {}
|
||||
for (const [k, v] of Object.entries({ ...hostFilters, ...q.filters })) if (k in M.FACET_ACC) bus.setFilter(k, v)
|
||||
for (const [k, v] of Object.entries(hostFilters)) if (k in M.FACET_ACC) bus.setFilter(k, v)
|
||||
const codes = [...new URLSearchParams(location.search).getAll('codes'), ...new URLSearchParams(location.search).getAll('code')].length ? q.filters.language : null
|
||||
if (codes) bus.setFilter('language', codes)
|
||||
const group = q.group || cfg().group || ''
|
||||
if (group) pendingGroup = group
|
||||
const panel = q.panel === 'tree' || cfg().panel === 'tree' ? 'tree' : 'map'
|
||||
|
|
@ -186,7 +189,7 @@ export function useBoard() {
|
|||
function syncUrl() {
|
||||
if (!writeUrl.value || typeof history === 'undefined') return
|
||||
const qs = M.buildQuery({ view: view.value, filterSet: bus.filterSet, group: openSlug.value, keep: location.search,
|
||||
panel: centre.value, tree: treeNode.value })
|
||||
panel: centre.value, tree: treeNode.value, filters: false })
|
||||
const next = location.pathname + (qs ? '?' + qs : '') + location.hash
|
||||
if (next !== location.pathname + location.search + location.hash) {
|
||||
try { history.replaceState(history.state, '', next) } catch (_) { /* sandboxed */ }
|
||||
|
|
|
|||
|
|
@ -604,7 +604,7 @@
|
|||
"bundle": "gospel-internet",
|
||||
"scriptUrl": "./gospel-internet/gospel-internet.js",
|
||||
"output": "dx-maps/gospel-internet/gospel-internet.js",
|
||||
"integrity": "sha384-wRWCJhXf3QrvCUO5i22k46dpJFvQWnI8dmA1jLl2l4YkiomWTVYPjTfXlKz3HRez",
|
||||
"integrity": "sha384-3be8zy4914UlmNZka99aGQPzEbp80c2Zr4ES+kvPMwW7SEzWNfxYEJgqgpbHr18d",
|
||||
"elements": [
|
||||
"gospel-internet-board"
|
||||
],
|
||||
|
|
@ -623,7 +623,7 @@
|
|||
"scriptUrl": "./gospel-internet/gospel-internet.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./gospel-internet/board/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-internet/gospel-internet.js\" integrity=\"sha384-wRWCJhXf3QrvCUO5i22k46dpJFvQWnI8dmA1jLl2l4YkiomWTVYPjTfXlKz3HRez\" crossorigin=\"anonymous\"></script>\n<gospel-internet-board profile-config='{\"profile\":\"board\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-internet-board>"
|
||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-internet/gospel-internet.js\" integrity=\"sha384-3be8zy4914UlmNZka99aGQPzEbp80c2Zr4ES+kvPMwW7SEzWNfxYEJgqgpbHr18d\" crossorigin=\"anonymous\"></script>\n<gospel-internet-board profile-config='{\"profile\":\"board\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-internet-board>"
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
|
||||
<script src="../../gospel-internet.js" integrity="sha384-wRWCJhXf3QrvCUO5i22k46dpJFvQWnI8dmA1jLl2l4YkiomWTVYPjTfXlKz3HRez" crossorigin="anonymous"></script>
|
||||
<script src="../../gospel-internet.js" integrity="sha384-3be8zy4914UlmNZka99aGQPzEbp80c2Zr4ES+kvPMwW7SEzWNfxYEJgqgpbHr18d" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
|
||||
<script src="../gospel-internet.js" integrity="sha384-wRWCJhXf3QrvCUO5i22k46dpJFvQWnI8dmA1jLl2l4YkiomWTVYPjTfXlKz3HRez" crossorigin="anonymous"></script>
|
||||
<script src="../gospel-internet.js" integrity="sha384-3be8zy4914UlmNZka99aGQPzEbp80c2Zr4ES+kvPMwW7SEzWNfxYEJgqgpbHr18d" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
|
||||
<script src="../../gospel-internet.js" integrity="sha384-wRWCJhXf3QrvCUO5i22k46dpJFvQWnI8dmA1jLl2l4YkiomWTVYPjTfXlKz3HRez" crossorigin="anonymous"></script>
|
||||
<script src="../../gospel-internet.js" integrity="sha384-3be8zy4914UlmNZka99aGQPzEbp80c2Zr4ES+kvPMwW7SEzWNfxYEJgqgpbHr18d" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
|
||||
<script src="../../gospel-internet.js" integrity="sha384-wRWCJhXf3QrvCUO5i22k46dpJFvQWnI8dmA1jLl2l4YkiomWTVYPjTfXlKz3HRez" crossorigin="anonymous"></script>
|
||||
<script src="../../gospel-internet.js" integrity="sha384-3be8zy4914UlmNZka99aGQPzEbp80c2Zr4ES+kvPMwW7SEzWNfxYEJgqgpbHr18d" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
|
||||
<script src="../../gospel-internet.js" integrity="sha384-wRWCJhXf3QrvCUO5i22k46dpJFvQWnI8dmA1jLl2l4YkiomWTVYPjTfXlKz3HRez" crossorigin="anonymous"></script>
|
||||
<script src="../../gospel-internet.js" integrity="sha384-3be8zy4914UlmNZka99aGQPzEbp80c2Zr4ES+kvPMwW7SEzWNfxYEJgqgpbHr18d" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
|
||||
<script src="../../gospel-internet.js" integrity="sha384-wRWCJhXf3QrvCUO5i22k46dpJFvQWnI8dmA1jLl2l4YkiomWTVYPjTfXlKz3HRez" crossorigin="anonymous"></script>
|
||||
<script src="../../gospel-internet.js" integrity="sha384-3be8zy4914UlmNZka99aGQPzEbp80c2Zr4ES+kvPMwW7SEzWNfxYEJgqgpbHr18d" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
<script>window.MAP_APP_API_URL = "https://pray.doxa.life";</script>
|
||||
<!-- Bundle IIFE — registers the <gospel-internet-board> custom element. -->
|
||||
<script src="../../gospel-internet.js" integrity="sha384-wRWCJhXf3QrvCUO5i22k46dpJFvQWnI8dmA1jLl2l4YkiomWTVYPjTfXlKz3HRez" crossorigin="anonymous"></script>
|
||||
<script src="../../gospel-internet.js" integrity="sha384-3be8zy4914UlmNZka99aGQPzEbp80c2Zr4ES+kvPMwW7SEzWNfxYEJgqgpbHr18d" crossorigin="anonymous"></script>
|
||||
|
||||
<script>
|
||||
// Mapbox token resolution — the A3 ladder, in precedence order:
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -604,7 +604,7 @@
|
|||
"bundle": "gospel-internet",
|
||||
"scriptUrl": "./gospel-internet/gospel-internet.js",
|
||||
"output": "dx-maps/gospel-internet/gospel-internet.js",
|
||||
"integrity": "sha384-wRWCJhXf3QrvCUO5i22k46dpJFvQWnI8dmA1jLl2l4YkiomWTVYPjTfXlKz3HRez",
|
||||
"integrity": "sha384-3be8zy4914UlmNZka99aGQPzEbp80c2Zr4ES+kvPMwW7SEzWNfxYEJgqgpbHr18d",
|
||||
"elements": [
|
||||
"gospel-internet-board"
|
||||
],
|
||||
|
|
@ -623,7 +623,7 @@
|
|||
"scriptUrl": "./gospel-internet/gospel-internet.js",
|
||||
"embed": {
|
||||
"iframe": "<iframe src=\"./gospel-internet/board/index.html?utm_source=YOUR_SOURCE\" width=\"100%\" height=\"600\" style=\"border:none;border-radius:12px;\" allowfullscreen></iframe>",
|
||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-internet/gospel-internet.js\" integrity=\"sha384-wRWCJhXf3QrvCUO5i22k46dpJFvQWnI8dmA1jLl2l4YkiomWTVYPjTfXlKz3HRez\" crossorigin=\"anonymous\"></script>\n<gospel-internet-board profile-config='{\"profile\":\"board\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-internet-board>"
|
||||
"script": "<!-- Mapbox engine, fetched early. Keep it only with a real Mapbox token in \"tk\": without one (or with \"provider\":\"maplibre\") the map draws with MapLibre and this line must go -->\n<link rel=\"preload\" as=\"script\" href=\"https://api.mapbox.com/mapbox-gl-js/v3.24.0/mapbox-gl.js\" integrity=\"sha384-tO0clamXONKwbiz7O6xJpUeyJbTSPugC+xM9clvfFvKTH3i8SmCawHGdf5quMWmZ\" crossorigin=\"anonymous\">\n<script>window.MAP_APP_API_URL=\"https://pray.doxa.life\";</script>\n<script src=\"./gospel-internet/gospel-internet.js\" integrity=\"sha384-3be8zy4914UlmNZka99aGQPzEbp80c2Zr4ES+kvPMwW7SEzWNfxYEJgqgpbHr18d\" crossorigin=\"anonymous\"></script>\n<gospel-internet-board profile-config='{\"profile\":\"board\",\"tk\":\"YOUR_MAPBOX_TOKEN\",\"utmSource\":\"YOUR_SOURCE\",\"assetsBase\":\"YOUR_TREE_URL/assets\"}'></gospel-internet-board>"
|
||||
},
|
||||
"instances": [
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue