client: bugfix new code
We now have a sidebar!
This commit is contained in:
parent
a24ba21ba8
commit
21d193a424
8 changed files with 74 additions and 40 deletions
|
@ -5,7 +5,8 @@
|
||||||
"main": "src/index.mjs",
|
"main": "src/index.mjs",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"No tests have been implemented yet\"",
|
"test": "echo \"No tests have been implemented yet\"",
|
||||||
"build": "node src/static/esbuild.mjs"
|
"build": "node src/static/esbuild.mjs",
|
||||||
|
"watch": "ESBUILD_WATCH=yes node src/static/esbuild.mjs"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|
|
@ -89,14 +89,18 @@ nav {
|
||||||
padding: 0.5em 0.75em;
|
padding: 0.5em 0.75em;
|
||||||
}
|
}
|
||||||
.nav-items a {
|
.nav-items a {
|
||||||
display: block;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0 0.5em;
|
||||||
|
|
||||||
color: inherit;
|
color: inherit;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
.nav-items .fa {
|
.nav-items span:last-child { flex: 1; }
|
||||||
margin: 0.1em 0.25em 0.1em 0.1em;
|
.nav-items .fa:not(.fa-stack):not(.fa-stack-1x):not(.fa-stack-2x):not(.fa-stack-3x) {
|
||||||
font-size: 200%;
|
font-size: 200%;
|
||||||
vertical-align: middle;
|
width: 1em;
|
||||||
|
height: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ import GlobalUI from './js/ui/GlobalUI.mjs';
|
||||||
import TableView from './js/ui/TableView.mjs';
|
import TableView from './js/ui/TableView.mjs';
|
||||||
|
|
||||||
window.addEventListener("load", async (_event) => {
|
window.addEventListener("load", async (_event) => {
|
||||||
const el_version = document.querySelector(".version");
|
|
||||||
const el_table = document.querySelector("main");
|
const el_table = document.querySelector("main");
|
||||||
|
|
||||||
globalThis.sysquery = new SystemQueryClient();
|
globalThis.sysquery = new SystemQueryClient();
|
||||||
|
@ -17,7 +16,7 @@ window.addEventListener("load", async (_event) => {
|
||||||
tableview: new TableView(el_table),
|
tableview: new TableView(el_table),
|
||||||
}
|
}
|
||||||
|
|
||||||
await ui.init();
|
await globalThis.sysui.ui.init();
|
||||||
|
|
||||||
|
|
||||||
globalThis.sysquery_router.navigate_current_hash();
|
globalThis.sysquery_router.navigate_current_hash();
|
||||||
|
|
|
@ -7,8 +7,12 @@ import crypto from 'crypto';
|
||||||
|
|
||||||
import esbuild from 'esbuild';
|
import esbuild from 'esbuild';
|
||||||
|
|
||||||
|
import log from '../lib/io/NamespacedLog.mjs'; const l = log("esbuild");
|
||||||
|
|
||||||
const __dirname = import.meta.url.slice(7, import.meta.url.lastIndexOf("/"));
|
const __dirname = import.meta.url.slice(7, import.meta.url.lastIndexOf("/"));
|
||||||
|
|
||||||
|
const outdir = path.resolve(__dirname, "../static-dist");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hashes the contents of a file.
|
* Hashes the contents of a file.
|
||||||
* @ref https://stackoverflow.com/a/44643479/1460422
|
* @ref https://stackoverflow.com/a/44643479/1460422
|
||||||
|
@ -29,33 +33,7 @@ function hash_file(hashName, path) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
(async () => {
|
async function do_html() {
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const outdir = path.resolve(__dirname, "../static-dist");
|
|
||||||
|
|
||||||
const result = await esbuild.build({
|
|
||||||
entryPoints: [
|
|
||||||
"./app.mjs",
|
|
||||||
"./app.css"
|
|
||||||
].map(filepath => path.resolve(__dirname, filepath)),
|
|
||||||
outdir,
|
|
||||||
bundle: true,
|
|
||||||
minify: true,
|
|
||||||
sourcemap: true,
|
|
||||||
treeShaking: true,
|
|
||||||
loader: {
|
|
||||||
".html": "text",
|
|
||||||
".svg": "file",
|
|
||||||
".woff2": "file",
|
|
||||||
".woff": "file",
|
|
||||||
".eot": "file",
|
|
||||||
".ttf": "file",
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if(result.errors.length > 0 || result.warnings.length > 0)
|
|
||||||
console.log(result);
|
|
||||||
|
|
||||||
// We *would* use SHA3 here, but we need to use SHA2 for subresource integrity
|
// We *would* use SHA3 here, but we need to use SHA2 for subresource integrity
|
||||||
let algorithm = "sha256";
|
let algorithm = "sha256";
|
||||||
let css_hash = await hash_file(algorithm, path.join(outdir, "app.css"));
|
let css_hash = await hash_file(algorithm, path.join(outdir, "app.css"));
|
||||||
|
@ -70,6 +48,49 @@ function hash_file(hashName, path) {
|
||||||
// TODO: Use fs.promises.copyFile() for index.html here, and also maybe find & replace for css/js filenames that we can then randomise?
|
// TODO: Use fs.promises.copyFile() for index.html here, and also maybe find & replace for css/js filenames that we can then randomise?
|
||||||
|
|
||||||
await fs.promises.writeFile(path.join(outdir, "index.html"), html);
|
await fs.promises.writeFile(path.join(outdir, "index.html"), html);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const result = await esbuild.build({
|
||||||
|
entryPoints: [
|
||||||
|
"./app.mjs",
|
||||||
|
"./app.css"
|
||||||
|
].map(filepath => path.resolve(__dirname, filepath)),
|
||||||
|
outdir,
|
||||||
|
bundle: true,
|
||||||
|
minify: true,
|
||||||
|
sourcemap: true,
|
||||||
|
treeShaking: true,
|
||||||
|
watch: typeof process.env.ESBUILD_WATCH === "undefined" ? false : {
|
||||||
|
async onRebuild(error, _result) {
|
||||||
|
if(error) {
|
||||||
|
l.error(error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(result.errors.length > 0 || result.warnings.length > 0)
|
||||||
|
console.log(result);
|
||||||
|
|
||||||
|
await do_html();
|
||||||
|
|
||||||
|
l.log(`Build successful`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
loader: {
|
||||||
|
".html": "text",
|
||||||
|
".svg": "file",
|
||||||
|
".woff2": "file",
|
||||||
|
".woff": "file",
|
||||||
|
".eot": "file",
|
||||||
|
".ttf": "file",
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if(result.errors.length > 0 || result.warnings.length > 0)
|
||||||
|
console.log(result);
|
||||||
|
|
||||||
|
await do_html();
|
||||||
// console.log(await esbuild.analyzeMetafile(result.metafile));
|
// console.log(await esbuild.analyzeMetafile(result.metafile));
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<!-- Any items specified here *must* have the "static" class, otherwise they'll be mistaken for a rogue dynamic item and stripped -->
|
<!-- Any items specified here *must* have the "static" class, otherwise they'll be mistaken for a rogue dynamic item and stripped -->
|
||||||
<li class="static"><a href="#settings">
|
<li class="static"><a href="#settings">
|
||||||
<span class="fa fa-cog fa-fw" aria-hidden="true"></span>
|
<span class="fa fa-cog fa-fw" aria-hidden="true"></span>
|
||||||
Settings
|
<span>settings</span>
|
||||||
</a></li>
|
</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
|
@ -4,7 +4,7 @@ import human_filesize from '../misc/human_filesize.mjs';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "CPU",
|
name: "CPU",
|
||||||
icon: microchip,
|
icon: "microchip",
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
name: "Frequency (GHz)",
|
name: "Frequency (GHz)",
|
||||||
|
|
|
@ -14,6 +14,8 @@ class GlobalUI {
|
||||||
async init() {
|
async init() {
|
||||||
const status = await globalThis.sysquery.status();
|
const status = await globalThis.sysquery.status();
|
||||||
|
|
||||||
|
const el_version = document.querySelector(".version");
|
||||||
|
|
||||||
// 1: Update version display
|
// 1: Update version display
|
||||||
el_version.replaceChildren(
|
el_version.replaceChildren(
|
||||||
document.createTextNode(status.version)
|
document.createTextNode(status.version)
|
||||||
|
@ -31,7 +33,14 @@ class GlobalUI {
|
||||||
// Generate new dynamic navigation items
|
// Generate new dynamic navigation items
|
||||||
const result = document.createDocumentFragment();
|
const result = document.createDocumentFragment();
|
||||||
for(const table_name of status.tables) {
|
for(const table_name of status.tables) {
|
||||||
result.append(...this.emel(`li>a[href=#table/?]>${forkawesome_emel(tabledefs[table_name].icon)}+{?}`, {
|
console.log(`[nav] new dynamic item ${table_name}, def`, tabledefs[table_name]);
|
||||||
|
const icondef = typeof tabledefs[table_name] === "undefined"
|
||||||
|
? "question-circle"
|
||||||
|
: tabledefs[table_name].icon;
|
||||||
|
|
||||||
|
const emel_icon = forkawesome_emel(icondef);
|
||||||
|
console.log(`emel_icon`, emel_icon);
|
||||||
|
result.append(this.emel(`li>a[href=#table/?]>${emel_icon}+span{?}`, {
|
||||||
placeholders: [ table_name, table_name ]
|
placeholders: [ table_name, table_name ]
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
export default function(def) {
|
export default function(def, fixed_width=true) {
|
||||||
if(typeof def === "string")
|
if(typeof def === "string")
|
||||||
return `span.fa.fa-${def}`;
|
return `span[class="fa fa-${def}${fixed_width?` fa-fw`:``}"]`;
|
||||||
if(def instanceof Array)
|
if(def instanceof Array)
|
||||||
return def.map(el, i => `span.fa.fa-${el}.fa-stack-${def.length-i}x`).join(`+`);
|
return `(span[class="fa-stack${fixed_width?` fa-fw`:``}"]>${def.map((el, i) => `span[class="fa fa-${el} fa-stack-${def.length-i}x${fixed_width?` fa-fw`:``}"]`).join(`+`)})`;
|
||||||
|
|
||||||
throw new Error(`Error: Expected def of type string or Array, but got variable of type ${typeof def}`);
|
throw new Error(`Error: Expected def of type string or Array, but got variable of type ${typeof def}`);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue