mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-05 10:53:59 +00:00
feat(ui): render application templates as Vue views mounted before wiring
Templates listed in build/applicationViews.js expand to mount hosts, and mountApplicationViews() renders them before translation and wiring. Markup tests read the page through a server-side render helper, the i18n scanner reads view templates, and Vue preserves whitespace so views keep the exact DOM. No template is converted yet.
This commit is contained in:
1 parent
b7e7058a5c
commit
9d24945143
32 files changed
+243
-63
No files matched your search
@@ -52,7 +52,7 @@ import {
|
||||
} from '../i18n/index.js';
|
||||
import { applyLocaleChoice, mountLocalePicker } from './localePicker.js';
|
||||
import { PanelNavigation } from './panelNavigation.js';
|
||||
import { createUiRuntime } from './vueRuntime.js';
|
||||
import { applicationPinia, createUiRuntime } from './vueRuntime.js';
|
||||
|
||||
/**
|
||||
* Central UI orchestrator for the God's Eye View application.
|
||||
@@ -136,7 +136,7 @@ export class StyleManager extends ShellFacade {
|
||||
this._mobileShell?.sharedCollapsed(panelId),
|
||||
});
|
||||
// Vue views share this runtime and its stores; dispose unmounts them.
|
||||
this._ui = createUiRuntime();
|
||||
this._ui = createUiRuntime({ pinia: applicationPinia() });
|
||||
this._feedback = new ShellFeedback({
|
||||
readLayers: () => this._dataManager?.getAll?.() || [],
|
||||
});
|
||||
|
||||
@@ -2,11 +2,11 @@ import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { readFileSync } from 'node:fs';
|
||||
|
||||
import { expandApplicationHtml } from '../../build/application-html.js';
|
||||
import { renderApplicationHtml } from '../testSupport/applicationHtml.mjs';
|
||||
import { createBrowserViteConfig } from '../../build/vite.js';
|
||||
import { R820T_GAIN_STEPS_DB } from '../sdr/gain.js';
|
||||
|
||||
const html = expandApplicationHtml(
|
||||
const html = await renderApplicationHtml(
|
||||
readFileSync(new URL('../../index.html', import.meta.url), 'utf8'),
|
||||
);
|
||||
const css = readFileSync(
|
||||
|
||||
@@ -98,3 +98,9 @@
|
||||
font: 600 9px/14px var(--font-mono);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Application view hosts (src/ui/views): the view's own elements lay out as
|
||||
children of the page, as the static markup they replace did. */
|
||||
.gev-view {
|
||||
display: contents;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import { createApp } from 'vue';
|
||||
import { applicationPinia } from '../vueRuntime.js';
|
||||
|
||||
/**
|
||||
* Application views by template name (build/applicationViews.js lists the
|
||||
* same names). Each renders the markup its static template held.
|
||||
*/
|
||||
export const APPLICATION_VIEWS = Object.freeze({});
|
||||
|
||||
const mounted = new WeakSet();
|
||||
|
||||
/**
|
||||
* Render every application view into its host. Views belong to the page, as
|
||||
* their static markup did, so they are never unmounted. Call before anything
|
||||
* reads or translates the page; repeated calls are harmless.
|
||||
* @param {Document} [doc] Page document.
|
||||
*/
|
||||
export function mountApplicationViews(doc = globalThis.document) {
|
||||
for (const host of doc?.querySelectorAll?.('[data-gev-view]') ?? []) {
|
||||
if (mounted.has(host)) continue;
|
||||
const name = host.getAttribute('data-gev-view');
|
||||
const view = APPLICATION_VIEWS[name];
|
||||
if (!view) throw new Error(`Unknown application view: ${name}`);
|
||||
createApp(view).use(applicationPinia()).mount(host);
|
||||
mounted.add(host);
|
||||
}
|
||||
}
|
||||
+16
-4
@@ -1,13 +1,25 @@
|
||||
import { createApp } from 'vue';
|
||||
import { createPinia } from 'pinia';
|
||||
|
||||
let pagePinia = null;
|
||||
|
||||
/**
|
||||
* Create the application's Vue runtime: one Pinia instance shared by every
|
||||
* view the shell mounts, and the mounts themselves for teardown.
|
||||
* The page's Pinia instance, shared by the application views and the shell,
|
||||
* so a view and a shell control read the same stores.
|
||||
* @returns {import('pinia').Pinia}
|
||||
*/
|
||||
export function applicationPinia() {
|
||||
pagePinia ??= createPinia();
|
||||
return pagePinia;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Vue runtime: one Pinia instance shared by every view it mounts,
|
||||
* and the mounts themselves for teardown.
|
||||
* @param {{pinia?: import('pinia').Pinia}} [options]
|
||||
* @returns {{pinia: import('pinia').Pinia, mount: Function, destroy: Function}}
|
||||
*/
|
||||
export function createUiRuntime() {
|
||||
const pinia = createPinia();
|
||||
export function createUiRuntime({ pinia = createPinia() } = {}) {
|
||||
const apps = new Set();
|
||||
return {
|
||||
pinia,
|
||||
|
||||
Reference in new issue
Block a user