// Copyright Epic Games, Inc. All Rights Reserved. "use strict"; import { WidgetHost } from "../util/widgets.js" import { Fetcher } from "../util/fetcher.js" //////////////////////////////////////////////////////////////////////////////// export class PageBase extends WidgetHost { constructor(parent, params) { super(parent) this._params = params; } set_title(name) { var value = document.title; if (name.length && value.length) name = value + " - " + name; document.title = name; } get_param(name, fallback=undefined) { var ret = this._params.get(name); if (ret != undefined) return ret; if (fallback != undefined) this.set_param(name, fallback); return fallback; } set_param(name, value, update=true) { this._params.set(name, value); if (!update) return value; const url = new URL(window.location); for (var [key, xfer] of this._params) url.searchParams.set(key, xfer); history.replaceState(null, "", url); return value; } reload() { window.location.reload(); } } //////////////////////////////////////////////////////////////////////////////// export class ZenPage extends PageBase { constructor(parent, ...args) { super(parent, ...args); super.set_title("zen"); this.add_branding(parent); this.add_service_nav(parent); this.generate_crumbs(); } add_branding(parent) { var banner = parent.tag("zen-banner"); banner.attr("subtitle", "Server"); banner.attr("tagline", "Local Storage Service"); banner.attr("logo-src", "favicon.ico"); banner.attr("load", "0"); this._banner = banner; this._poll_status(); } static _mode_taglines = { "Server": "Local Storage Service", "Proxy": "Proxy Service", "Compute": "Compute Service", "Hub": "Hub Service", }; async _poll_status() { try { var cbo = await new Fetcher().resource("/status/status").cbo(); if (cbo) { var obj = cbo.as_object(); var mode = obj.find("serverMode"); if (mode) { var modeStr = mode.as_value(); this._banner.attr("subtitle", modeStr); var tagline = ZenPage._mode_taglines[modeStr] || modeStr; var hostname = obj.find("hostname"); if (hostname) tagline += " \u2014 " + hostname.as_value(); this._banner.attr("tagline", tagline); } var cpu = obj.find("cpuUsagePercent"); if (cpu) { this._banner.attr("load", cpu.as_value().toFixed(1)); } } } catch (e) { console.warn("status poll:", e); } setTimeout(() => this._poll_status(), 2000); } add_service_nav(parent) { const nav = parent.tag().id("service_nav"); // Map service base URIs to dashboard links, this table is also used to detemine // which links to show based on the services that are currently registered. const service_dashboards = [ { base_uri: "/sessions/", label: "Sessions", href: "/dashboard/?page=sessions" }, { base_uri: "/z$/", label: "Cache", href: "/dashboard/?page=cache" }, { base_uri: "/prj/", label: "Projects", href: "/dashboard/?page=projects" }, { base_uri: "/compute/", label: "Compute", href: "/dashboard/?page=compute" }, { base_uri: "/orch/", label: "Orchestrator", href: "/dashboard/?page=orchestrator" }, { base_uri: "/hub/", label: "Hub", href: "/dashboard/?page=hub" }, { base_uri: "/proxy/", label: "Proxy", href: "/dashboard/?page=proxy" }, ]; nav.tag("a").text("Home").attr("href", "/dashboard/"); this._info_link = nav.tag("a").text("Info").attr("href", "/dashboard/?page=info"); new Fetcher().resource("/api/").json().then((data) => { const services = data.services || []; const uris = new Set(services.map(s => s.base_uri)); const links = service_dashboards.filter(d => uris.has(d.base_uri)); // Insert service links before the Info link const info_elem = this._info_link.inner(); for (const link of links) { const a = document.createElement("a"); a.textContent = link.label; a.href = link.href; info_elem.parentNode.insertBefore(a, info_elem); } }).catch(() => {}); } set_title(...args) { super.set_title(...args); } generate_crumbs() { var auto_name = this.get_param("page") || "start"; if (auto_name == "start") return; const crumbs = this.tag().id("crumbs"); const new_crumb = function(name, search=undefined) { crumbs.tag(); var crumb = crumbs.tag().text(name); if (search != undefined) crumb.on_click((x) => window.location.search = x, search); }; new_crumb("home", ""); var project = this.get_param("project"); if (project != undefined) { auto_name = project; var oplog = this.get_param("oplog"); if (oplog != undefined) { new_crumb(auto_name, `?page=project&project=${project}`); auto_name = oplog; var opkey = this.get_param("opkey") if (opkey != undefined) { new_crumb(auto_name, `?page=oplog&project=${project}&oplog=${oplog}`); auto_name = opkey.split("/").pop().split("\\").pop(); // Check if we're viewing cook artifacts var page = this.get_param("page"); var hash = this.get_param("hash"); if (hash != undefined && page == "cookartifacts") { new_crumb(auto_name, `?page=entry&project=${project}&oplog=${oplog}&opkey=${opkey}`); auto_name = "cook artifacts"; } } } } new_crumb(auto_name); } }