mirror of
https://github.com/Xahau/xahau-web.git
synced 2026-08-21 18:10:51 +00:00
@@ -45,6 +45,35 @@ const tr = (v: unknown): string => {
|
||||
return ''
|
||||
}
|
||||
|
||||
/**
|
||||
* Card tag text.
|
||||
*
|
||||
* Items carry vocabulary *keys* (`phase`, `note`) rather than per-locale
|
||||
* strings, so a wording change happens once in `labels.<locale>.tags` instead
|
||||
* of once per item per language. Renders "<phase> · <note>"; `note` is
|
||||
* optional. `tag` stays supported as a free-form escape hatch for one-offs.
|
||||
*
|
||||
* An unknown key is a build error, not a silently blank tag — the fallback
|
||||
* locale is checked too, so a key missing only from a translation still
|
||||
* renders (in the default locale) rather than breaking the page.
|
||||
*/
|
||||
const tagFor = (it: RoadmapItem): string => {
|
||||
if (!it.phase) return it.tag ? tr(it.tag) : ''
|
||||
|
||||
const pick = (kind: 'phases' | 'notes', key: string): string => {
|
||||
const here = data.labels[lang]?.tags?.[kind]?.[key]
|
||||
const base = data.labels[defaultLocale]?.tags?.[kind]?.[key]
|
||||
if (here ?? base) return (here ?? base) as string
|
||||
throw new Error(
|
||||
`roadmap.json: item "${it.id}" uses ${kind === 'phases' ? 'phase' : 'note'} ` +
|
||||
`"${key}", which is not defined in labels.${defaultLocale}.tags.${kind}.`,
|
||||
)
|
||||
}
|
||||
|
||||
const phase = pick('phases', it.phase)
|
||||
return it.note ? `${phase} · ${pick('notes', it.note)}` : phase
|
||||
}
|
||||
|
||||
const qToIdx = (q: string) => {
|
||||
const [y, qx] = q.split('-Q')
|
||||
return Number(y) * 4 + (Number(qx) - 1)
|
||||
@@ -209,7 +238,7 @@ const fmtItemPeriod = (item: RoadmapItem): string => {
|
||||
return (
|
||||
<article class={classes} style={`grid-column:${p.col} / span ${p.span};`}>
|
||||
<span class="xr-q-badge" aria-hidden="true">{fmtItemPeriod(it)}</span>
|
||||
{it.tag && <div class="k">{tr(it.tag)}</div>}
|
||||
{tagFor(it) && <div class="k">{tagFor(it)}</div>}
|
||||
<div class="n">{tr(it.title)}</div>
|
||||
{it.description && <div class="d">{tr(it.description)}</div>}
|
||||
<span class="peg" aria-hidden="true"></span>
|
||||
@@ -245,7 +274,7 @@ const fmtItemPeriod = (item: RoadmapItem): string => {
|
||||
<article class={classes} style={`grid-column:${p.col} / span ${p.span};`}>
|
||||
<span class="peg" aria-hidden="true"></span>
|
||||
<span class="xr-q-badge" aria-hidden="true">{fmtItemPeriod(it)}</span>
|
||||
{it.tag && <div class="k">{tr(it.tag)}</div>}
|
||||
{tagFor(it) && <div class="k">{tagFor(it)}</div>}
|
||||
<div class="n">{tr(it.title)}</div>
|
||||
{it.description && <div class="d">{tr(it.description)}</div>}
|
||||
</article>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"$comment": "Xahau roadmap source of truth. Edit this file to add/update/remove items. Committed JSON is rendered at build time by src/components/XahauRoadmap.astro — no runtime JS required.",
|
||||
|
||||
"$comment": "Xahau roadmap source of truth. Edit this file to add/update/remove items. Committed JSON is rendered at build time by src/components/XahauRoadmap.astro — no runtime JS required. Card tags come from `labels.<locale>.tags`: set `phase` (and optionally `note`) on an item instead of writing the tag text per locale.",
|
||||
"meta": {
|
||||
"updated": "2026-04-19",
|
||||
"window": {
|
||||
@@ -14,7 +13,6 @@
|
||||
"locales": ["en", "es", "pt-BR"]
|
||||
}
|
||||
},
|
||||
|
||||
"labels": {
|
||||
"en": {
|
||||
"title": "Xahau Roadmap",
|
||||
@@ -54,6 +52,33 @@
|
||||
"partnership": "Partnership",
|
||||
"launch": "Launch / public good"
|
||||
},
|
||||
"tags": {
|
||||
"$comment": "Card tag vocabulary. Items reference these by key via `phase` / `note`; the card renders \"<phase> · <note>\". Edit a word here and it changes everywhere it is used. A `note` is written to agree with the `phase` it follows (gender/number), so check before reusing one under a new phase.",
|
||||
"phases": {
|
||||
"feature": "Feature",
|
||||
"ongoing": "Ongoing",
|
||||
"live": "Live",
|
||||
"ga": "GA",
|
||||
"pilot": "Pilot",
|
||||
"launch": "Launch",
|
||||
"partnerships": "Partnerships",
|
||||
"enterprise": "Enterprise",
|
||||
"event": "Event"
|
||||
},
|
||||
"notes": {
|
||||
"activated": "Activated",
|
||||
"ready-for-amendment": "ready for amendment",
|
||||
"in-development": "in development",
|
||||
"alpha": "in alpha development",
|
||||
"beta": "in beta development",
|
||||
"audits-optimisations": "audits + optimisations",
|
||||
"remittance": "remittance",
|
||||
"payments": "payments",
|
||||
"public-good": "public good",
|
||||
"quarterly": "quarterly",
|
||||
"enterprise-devs": "enterprise + devs"
|
||||
}
|
||||
},
|
||||
"foot": "Directional - subject to change - xahau.network"
|
||||
},
|
||||
"es": {
|
||||
@@ -94,6 +119,33 @@
|
||||
"partnership": "Alianza",
|
||||
"launch": "Lanzamiento / bien público"
|
||||
},
|
||||
"tags": {
|
||||
"$comment": "Card tag vocabulary. Items reference these by key via `phase` / `note`; the card renders \"<phase> · <note>\". Edit a word here and it changes everywhere it is used. A `note` is written to agree with the `phase` it follows (gender/number), so check before reusing one under a new phase.",
|
||||
"phases": {
|
||||
"feature": "Función",
|
||||
"ongoing": "Continuo",
|
||||
"live": "En vivo",
|
||||
"ga": "GA",
|
||||
"pilot": "Piloto",
|
||||
"launch": "Lanzamiento",
|
||||
"partnerships": "Alianzas",
|
||||
"enterprise": "Empresarial",
|
||||
"event": "Evento"
|
||||
},
|
||||
"notes": {
|
||||
"activated": "activada",
|
||||
"ready-for-amendment": "lista para enmienda",
|
||||
"in-development": "en desarrollo",
|
||||
"alpha": "en desarrollo alfa",
|
||||
"beta": "en desarrollo beta",
|
||||
"audits-optimisations": "auditorías y optimizaciones",
|
||||
"remittance": "remesas",
|
||||
"payments": "pagos",
|
||||
"public-good": "bien público",
|
||||
"quarterly": "trimestral",
|
||||
"enterprise-devs": "empresas y desarrolladores"
|
||||
}
|
||||
},
|
||||
"foot": "Orientativo - sujeto a cambios - xahau.network"
|
||||
},
|
||||
"pt-BR": {
|
||||
@@ -134,22 +186,83 @@
|
||||
"partnership": "Parceria",
|
||||
"launch": "Lançamento / bem público"
|
||||
},
|
||||
"tags": {
|
||||
"$comment": "Card tag vocabulary. Items reference these by key via `phase` / `note`; the card renders \"<phase> · <note>\". Edit a word here and it changes everywhere it is used. A `note` is written to agree with the `phase` it follows (gender/number), so check before reusing one under a new phase.",
|
||||
"phases": {
|
||||
"feature": "Funcionalidade",
|
||||
"ongoing": "Contínuo",
|
||||
"live": "Ao vivo",
|
||||
"ga": "GA",
|
||||
"pilot": "Piloto",
|
||||
"launch": "Lançamento",
|
||||
"partnerships": "Parcerias",
|
||||
"enterprise": "Empresarial",
|
||||
"event": "Evento"
|
||||
},
|
||||
"notes": {
|
||||
"activated": "ativada",
|
||||
"ready-for-amendment": "pronta para emenda",
|
||||
"in-development": "em desenvolvimento",
|
||||
"alpha": "em desenvolvimento alfa",
|
||||
"beta": "em desenvolvimento beta",
|
||||
"audits-optimisations": "auditorias e otimizações",
|
||||
"remittance": "remessas",
|
||||
"payments": "pagamentos",
|
||||
"public-good": "bem público",
|
||||
"quarterly": "trimestral",
|
||||
"enterprise-devs": "empresas e desenvolvedores"
|
||||
}
|
||||
},
|
||||
"foot": "Direcional - sujeito a alterações - xahau.network"
|
||||
}
|
||||
},
|
||||
|
||||
"items": [
|
||||
{
|
||||
"id": "price-oracle",
|
||||
"lane": "tech",
|
||||
"status": "feature",
|
||||
"quarter": "2026-Q2",
|
||||
"span": 2,
|
||||
"phase": "feature",
|
||||
"note": "activated",
|
||||
"title": {
|
||||
"en": "PriceOracle",
|
||||
"es": "PriceOracle",
|
||||
"pt-BR": "PriceOracle"
|
||||
},
|
||||
"description": {
|
||||
"en": "Native on-ledger price feed primitive — tamper-resistant asset prices for DeFi, AMM and Hooks.",
|
||||
"es": "Primitiva nativa de precios en el ledger — precios de activos resistentes a manipulación para DeFi, AMM y Hooks.",
|
||||
"pt-BR": "Primitiva nativa de feed de preços no ledger — preços de ativos resistentes a adulterações para DeFi, AMM e Hooks."
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "iou-reward-claim",
|
||||
"lane": "tech",
|
||||
"status": "feature",
|
||||
"quarter": "2026-Q2",
|
||||
"endQuarter": "2026-Q3",
|
||||
"phase": "feature",
|
||||
"note": "activated",
|
||||
"title": {
|
||||
"en": "IOURewardClaim",
|
||||
"es": "IOURewardClaim",
|
||||
"pt-BR": "IOURewardClaim"
|
||||
},
|
||||
"description": {
|
||||
"en": "Extends the current RewardClaim for XAH to make it available for IOU tokens as well — letting projects use Hooks to distribute rewards based on a user's token holdings.",
|
||||
"es": "Extiende el RewardClaim actual de XAH para ofrecerlo también a tokens IOU — permitiendo a los proyectos usar Hooks para distribuir recompensas según las tenencias de tokens de un usuario.",
|
||||
"pt-BR": "Estende o RewardClaim atual do XAH para torná-lo disponível também para tokens IOU — permitindo que projetos usem Hooks para distribuir recompensas com base nas posições de tokens de um usuário."
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "rng",
|
||||
"lane": "tech",
|
||||
"status": "feature",
|
||||
"quarter": "2026-Q2",
|
||||
"endQuarter": "2026-Q2",
|
||||
"tag": {
|
||||
"en": "Feature · in beta development",
|
||||
"es": "Función · en desarrollo beta",
|
||||
"pt-BR": "Funcionalidade · em desenvolvimento beta"
|
||||
},
|
||||
"endQuarter": "2026-Q3",
|
||||
"phase": "feature",
|
||||
"note": "beta",
|
||||
"title": {
|
||||
"en": "Random Number Generator",
|
||||
"es": "Generador de números aleatorios",
|
||||
@@ -167,11 +280,8 @@
|
||||
"status": "feature",
|
||||
"quarter": "2026-Q2",
|
||||
"endQuarter": "2026-Q3",
|
||||
"tag": {
|
||||
"en": "Feature · in development",
|
||||
"es": "Función · en desarrollo",
|
||||
"pt-BR": "Funcionalidade · em desenvolvimento"
|
||||
},
|
||||
"phase": "feature",
|
||||
"note": "in-development",
|
||||
"title": {
|
||||
"en": "FeatureExport",
|
||||
"es": "FeatureExport",
|
||||
@@ -189,74 +299,32 @@
|
||||
"status": "feature",
|
||||
"quarter": "2026-Q2",
|
||||
"span": 2,
|
||||
"tag": {
|
||||
"en": "Feature · ready for amendment",
|
||||
"es": "Función · lista para enmienda",
|
||||
"pt-BR": "Funcionalidade · pronta para emenda"
|
||||
"phase": "feature",
|
||||
"note": "ready-for-amendment",
|
||||
"title": {
|
||||
"en": "AMM",
|
||||
"es": "AMM",
|
||||
"pt-BR": "AMM"
|
||||
},
|
||||
"title": { "en": "AMM", "es": "AMM", "pt-BR": "AMM" },
|
||||
"description": {
|
||||
"en": "Automated Market Maker primitive for deep native liquidity on the Xahau DEX. Merged into the xahaud dev branch, awaiting amendment vote.",
|
||||
"es": "Primitiva Automated Market Maker para liquidez nativa profunda en el DEX de Xahau. Integrada en la rama dev de xahaud, a la espera de la votación de enmienda.",
|
||||
"pt-BR": "Primitiva de Automated Market Maker para liquidez nativa profunda no DEX da Xahau. Integrada ao branch dev do xahaud, aguardando votação de emenda."
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "price-oracle",
|
||||
"lane": "tech",
|
||||
"status": "feature",
|
||||
"quarter": "2026-Q2",
|
||||
"span": 2,
|
||||
"tag": {
|
||||
"en": "Feature · ready for amendment",
|
||||
"es": "Función · lista para enmienda",
|
||||
"pt-BR": "Funcionalidade · pronta para emenda"
|
||||
},
|
||||
"title": {
|
||||
"en": "PriceOracle",
|
||||
"es": "PriceOracle",
|
||||
"pt-BR": "PriceOracle"
|
||||
},
|
||||
"description": {
|
||||
"en": "Native on-ledger price feed primitive — tamper-resistant asset prices for DeFi, AMM and Hooks. Merged into the xahaud dev branch, awaiting amendment vote.",
|
||||
"es": "Primitiva nativa de precios en el ledger — precios de activos resistentes a manipulación para DeFi, AMM y Hooks. Integrada en la rama dev de xahaud, a la espera de la votación de enmienda.",
|
||||
"pt-BR": "Primitiva nativa de feed de preços no ledger — preços de ativos resistentes a adulterações para DeFi, AMM e Hooks. Integrada ao branch dev do xahaud, aguardando votação de emenda."
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "iou-reward-claim",
|
||||
"lane": "tech",
|
||||
"status": "feature",
|
||||
"quarter": "2026-Q2",
|
||||
"endQuarter": "2026-Q3",
|
||||
"tag": {
|
||||
"en": "Feature · in development",
|
||||
"es": "Función · en desarrollo",
|
||||
"pt-BR": "Funcionalidade · em desenvolvimento"
|
||||
},
|
||||
"title": {
|
||||
"en": "IOURewardClaim",
|
||||
"es": "IOURewardClaim",
|
||||
"pt-BR": "IOURewardClaim"
|
||||
},
|
||||
"description": {
|
||||
"en": "Extends the current RewardClaim for XAH to make it available for IOU tokens as well — letting projects use Hooks to distribute rewards based on a user's token holdings.",
|
||||
"es": "Extiende el RewardClaim actual de XAH para ofrecerlo también a tokens IOU — permitiendo a los proyectos usar Hooks para distribuir recompensas según las tenencias de tokens de un usuario.",
|
||||
"pt-BR": "Estende o RewardClaim atual do XAH para torná-lo disponível também para tokens IOU — permitindo que projetos usem Hooks para distribuir recompensas com base nas posições de tokens de um usuário."
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "named-hook",
|
||||
"lane": "tech",
|
||||
"status": "feature",
|
||||
"quarter": "2026-Q3",
|
||||
"endQuarter": "2026-Q4",
|
||||
"tag": {
|
||||
"en": "Feature · in development",
|
||||
"es": "Función · en desarrollo",
|
||||
"pt-BR": "Funcionalidade · em desenvolvimento"
|
||||
"phase": "feature",
|
||||
"note": "ready-for-amendment",
|
||||
"title": {
|
||||
"en": "NamedHook",
|
||||
"es": "NamedHook",
|
||||
"pt-BR": "NamedHook"
|
||||
},
|
||||
"title": { "en": "NamedHook", "es": "NamedHook", "pt-BR": "NamedHook" },
|
||||
"description": {
|
||||
"en": "Allows names to be set to identify Hooks, so different Hooks can be invoked even within the same transaction type.",
|
||||
"es": "Permite asignar nombres para identificar Hooks, de modo que se puedan invocar diferentes Hooks incluso dentro del mismo tipo de transacción.",
|
||||
@@ -269,12 +337,13 @@
|
||||
"status": "feature",
|
||||
"quarter": "2026-Q2",
|
||||
"span": 3,
|
||||
"tag": {
|
||||
"en": "Feature · in alpha development",
|
||||
"es": "Función · en desarrollo alfa",
|
||||
"pt-BR": "Funcionalidade · em desenvolvimento alfa"
|
||||
"phase": "feature",
|
||||
"note": "alpha",
|
||||
"title": {
|
||||
"en": "JSHooks",
|
||||
"es": "JSHooks",
|
||||
"pt-BR": "JSHooks"
|
||||
},
|
||||
"title": { "en": "JSHooks", "es": "JSHooks", "pt-BR": "JSHooks" },
|
||||
"description": {
|
||||
"en": "JavaScript runtime for Hooks — write Xahau smart-contract logic in JavaScript alongside the existing WebAssembly runtime, broadening the developer surface.",
|
||||
"es": "Entorno de ejecución JavaScript para Hooks — escribir la lógica de smart contracts en JavaScript junto al entorno WebAssembly existente, ampliando la superficie para desarrolladores.",
|
||||
@@ -287,11 +356,8 @@
|
||||
"status": "feature",
|
||||
"quarter": "2026-Q2",
|
||||
"openEnded": true,
|
||||
"tag": {
|
||||
"en": "Ongoing · audits + optimisations",
|
||||
"es": "Continuo · auditorías y optimizaciones",
|
||||
"pt-BR": "Contínuo · auditorias e otimizações"
|
||||
},
|
||||
"phase": "ongoing",
|
||||
"note": "audits-optimisations",
|
||||
"title": {
|
||||
"en": "Audit & optimisations",
|
||||
"es": "Auditorías y optimizaciones",
|
||||
@@ -303,19 +369,15 @@
|
||||
"pt-BR": "Auditorias de segurança e melhorias de desempenho contínuas no protocolo, Hooks e ferramentas."
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"id": "coopbank-eur",
|
||||
"lane": "rollout",
|
||||
"status": "live",
|
||||
"quarter": "2026-Q2",
|
||||
"openEnded": false,
|
||||
"span": 2,
|
||||
"tag": {
|
||||
"en": "Live · remittance",
|
||||
"es": "En vivo · remesas",
|
||||
"pt-BR": "Ao vivo · remessas"
|
||||
},
|
||||
"openEnded": false,
|
||||
"phase": "live",
|
||||
"note": "remittance",
|
||||
"title": {
|
||||
"en": "COOP Bank EUR corridor scale-up to entire country.",
|
||||
"es": "Escalado del corredor EUR de COOP Bank a todo el país.",
|
||||
@@ -333,7 +395,7 @@
|
||||
"status": "partnership",
|
||||
"quarter": "2026-Q2",
|
||||
"endQuarter": "2026-Q3",
|
||||
"tag": { "en": "Launch", "es": "Lanzamiento", "pt-BR": "Lançamento" },
|
||||
"phase": "launch",
|
||||
"title": {
|
||||
"en": "USD stablecoin on Xahau",
|
||||
"es": "Stablecoin USD en Xahau",
|
||||
@@ -351,7 +413,7 @@
|
||||
"status": "partnership",
|
||||
"quarter": "2026-Q4",
|
||||
"openEnded": true,
|
||||
"tag": { "en": "Launch", "es": "Lanzamiento", "pt-BR": "Lançamento" },
|
||||
"phase": "launch",
|
||||
"title": {
|
||||
"en": "Currencies from multiple countries on Xahau",
|
||||
"es": "Divisas de múltiples países en Xahau",
|
||||
@@ -369,7 +431,7 @@
|
||||
"status": "partnership",
|
||||
"quarter": "2026-Q3",
|
||||
"endQuarter": "2026-Q4",
|
||||
"tag": { "en": "Launch", "es": "Lanzamiento", "pt-BR": "Lançamento" },
|
||||
"phase": "launch",
|
||||
"title": {
|
||||
"en": "GBP stablecoin on Xahau",
|
||||
"es": "Stablecoin GBP en Xahau",
|
||||
@@ -387,7 +449,7 @@
|
||||
"status": "pilot",
|
||||
"quarter": "2026-Q3",
|
||||
"endQuarter": "2026-Q4",
|
||||
"tag": { "en": "Pilot", "es": "Piloto", "pt-BR": "Piloto" },
|
||||
"phase": "pilot",
|
||||
"title": {
|
||||
"en": "USD corridor pilot",
|
||||
"es": "Piloto del corredor USD",
|
||||
@@ -405,7 +467,7 @@
|
||||
"status": "partnership",
|
||||
"quarter": "2026-Q4",
|
||||
"openEnded": true,
|
||||
"tag": { "en": "Partnerships", "es": "Alianzas", "pt-BR": "Parcerias" },
|
||||
"phase": "partnerships",
|
||||
"title": {
|
||||
"en": "Additional bank & remittance partners",
|
||||
"es": "Bancos y socios de remesas adicionales",
|
||||
@@ -423,11 +485,8 @@
|
||||
"status": "live",
|
||||
"quarter": "2027-Q1",
|
||||
"span": 1,
|
||||
"tag": {
|
||||
"en": "GA · remittance",
|
||||
"es": "GA · remesas",
|
||||
"pt-BR": "GA · remessas"
|
||||
},
|
||||
"phase": "ga",
|
||||
"note": "remittance",
|
||||
"title": {
|
||||
"en": "Corridor expansion · GA",
|
||||
"es": "Expansión de corredores · GA",
|
||||
@@ -445,11 +504,8 @@
|
||||
"status": "pilot",
|
||||
"quarter": "2027-Q2",
|
||||
"endQuarter": "2027-Q3",
|
||||
"tag": {
|
||||
"en": "Pilot · payments",
|
||||
"es": "Piloto · pagos",
|
||||
"pt-BR": "Piloto · pagamentos"
|
||||
},
|
||||
"phase": "pilot",
|
||||
"note": "payments",
|
||||
"title": {
|
||||
"en": "Merchant settlement pilot",
|
||||
"es": "Piloto de liquidación para comercios",
|
||||
@@ -461,18 +517,13 @@
|
||||
"pt-BR": "Liquidação com stablecoins e conformidade baseada em Hooks para comerciantes."
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"id": "enterprise-ga",
|
||||
"lane": "rollout",
|
||||
"status": "partnership",
|
||||
"quarter": "2027-Q3",
|
||||
"openEnded": true,
|
||||
"tag": {
|
||||
"en": "Enterprise",
|
||||
"es": "Empresarial",
|
||||
"pt-BR": "Empresarial"
|
||||
},
|
||||
"phase": "enterprise",
|
||||
"title": {
|
||||
"en": "Enterprise settlement GA",
|
||||
"es": "GA de liquidación empresarial",
|
||||
@@ -484,18 +535,14 @@
|
||||
"pt-BR": "Oferta de produção para parceiros regulamentados, construída sobre componentes Hooks auditados."
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"id": "ngo-donations",
|
||||
"lane": "rollout",
|
||||
"status": "launch",
|
||||
"quarter": "2026-Q4",
|
||||
"openEnded": true,
|
||||
"tag": {
|
||||
"en": "Launch · public good",
|
||||
"es": "Lanzamiento · bien público",
|
||||
"pt-BR": "Lançamento · bem público"
|
||||
},
|
||||
"phase": "launch",
|
||||
"note": "public-good",
|
||||
"title": {
|
||||
"en": "NGO donation platform",
|
||||
"es": "Plataforma de donaciones para ONG",
|
||||
@@ -535,11 +582,8 @@
|
||||
"status": "launch",
|
||||
"quarter": "2026-Q2",
|
||||
"openEnded": true,
|
||||
"tag": {
|
||||
"en": "Event · quarterly",
|
||||
"es": "Evento · trimestral",
|
||||
"pt-BR": "Evento · trimestral"
|
||||
},
|
||||
"phase": "event",
|
||||
"note": "quarterly",
|
||||
"title": {
|
||||
"en": "Xahau Connect",
|
||||
"es": "Xahau Connect",
|
||||
@@ -556,11 +600,8 @@
|
||||
"lane": "rollout",
|
||||
"status": "launch",
|
||||
"quarter": "2026-Q4",
|
||||
"tag": {
|
||||
"en": "Event · enterprise + devs",
|
||||
"es": "Evento · empresas y desarrolladores",
|
||||
"pt-BR": "Evento · empresas e desenvolvedores"
|
||||
},
|
||||
"phase": "event",
|
||||
"note": "enterprise-devs",
|
||||
"title": {
|
||||
"en": "InFTF event",
|
||||
"es": "Evento InFTF",
|
||||
|
||||
@@ -29,6 +29,14 @@ export const roadmapItem = z.object({
|
||||
// Ongoing activity with no firm end date. Stretches to the end of the visible
|
||||
// window and renders a "continues" indicator. Overrides `span`/`endQuarter`.
|
||||
openEnded: z.boolean().optional().default(false),
|
||||
// Card tag, built from the shared vocabulary in `labels.<locale>.tags`.
|
||||
// `phase` is the base word ('feature' -> "Feature"), `note` the optional
|
||||
// qualifier ('activated' -> "Activated"); the card renders "phase · note".
|
||||
// Both are keys, not text — translations live in `labels`, not on the item.
|
||||
phase: z.string().min(1).optional(),
|
||||
note: z.string().min(1).optional(),
|
||||
// Escape hatch for one-off tags that aren't part of the vocabulary.
|
||||
// Ignored when `phase` is set. Prefer `phase`/`note` for anything reusable.
|
||||
tag: localized.optional(),
|
||||
title: localized,
|
||||
description: localized.optional(),
|
||||
@@ -59,6 +67,13 @@ export const roadmapLabels = z.object({
|
||||
partnership: z.string(),
|
||||
launch: z.string(),
|
||||
}),
|
||||
// Tag vocabulary — see `phase`/`note` on roadmapItem. Open records so a new
|
||||
// key only has to be added to the JSON, not here; XahauRoadmap.astro fails
|
||||
// the build if an item points at a key that doesn't exist.
|
||||
tags: z.object({
|
||||
phases: z.record(z.string(), z.string()),
|
||||
notes: z.record(z.string(), z.string()),
|
||||
}),
|
||||
foot: z.string(),
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user