aboutsummaryrefslogtreecommitdiff
path: root/src/zenserver/frontend/html/util/component.js
diff options
context:
space:
mode:
authorMartin Ridgers <[email protected]>2024-11-18 08:41:46 +0100
committerGitHub Enterprise <[email protected]>2024-11-18 08:41:46 +0100
commitcca69117b7ffac5cdd8933148ed9c94dd241528d (patch)
treeba9dfce342e86d9cbdf6cf54059e1e7d618eecee /src/zenserver/frontend/html/util/component.js
parentoplog prep gc fix (#216) (diff)
downloadzen-cca69117b7ffac5cdd8933148ed9c94dd241528d.tar.xz
zen-cca69117b7ffac5cdd8933148ed9c94dd241528d.zip
Dashboard: oplog tree view (#217)
* Turned tables and progress bars and friends into "widgets!" * A step to abstracting away a page's the internal DOM structure * Folded sector creation into Page and pivoted it to a widget host * Try and keep start/count as numbers regardless of input * No need for the entry table to be defined up front now * Add op count and log sixe to oplog list page * Cache left side toolbar object * Bounds count page start when building list of oplog entrie * Start/end navigation tools * Build rest of entry page while waiting for indexer to load * Consistent naming with other pages * Spacially consolidate fetching code * Hide fetch latency to speed up index generation workers * Extract dashboard structure from zen.js monolith * Fix breadcrumbs after restructuring * Add view link to actions cell of oplogs list * Generator to enumerate names of entries in indexer * Methods for simple traversal of component relations * is() to check if a component is of a certain type * Extend attr() to get and unset a component's attributes * Unsetting all styles of anchor tags was underisrable * Restore page name as id of container element * A tree view of an oplog * Move helper class out to private module scope * Small tweak to use left var that already exists * Changelog update * Updated frontend .zip archive
Diffstat (limited to 'src/zenserver/frontend/html/util/component.js')
-rw-r--r--src/zenserver/frontend/html/util/component.js158
1 files changed, 158 insertions, 0 deletions
diff --git a/src/zenserver/frontend/html/util/component.js b/src/zenserver/frontend/html/util/component.js
new file mode 100644
index 000000000..39a9f2fe6
--- /dev/null
+++ b/src/zenserver/frontend/html/util/component.js
@@ -0,0 +1,158 @@
+// Copyright Epic Games, Inc. All Rights Reserved.
+
+"use strict";
+
+////////////////////////////////////////////////////////////////////////////////
+class ComponentBase
+{
+ constructor(element)
+ {
+ if (element instanceof ComponentBase)
+ element = element._element;
+
+ this._element = element;
+ }
+
+ inner()
+ {
+ return this._element;
+ }
+
+ parent()
+ {
+ return this.new_component(this._element.parentElement);
+ }
+
+ first_child()
+ {
+ return this.new_component(this._element.firstElementChild);
+ }
+
+ next_sibling()
+ {
+ return this.new_component(this._element.nextElementSibling);
+ }
+
+ destroy()
+ {
+ this._element.parentNode.removeChild(this._element);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+class ComponentDom extends ComponentBase
+{
+ is(tag)
+ {
+ return this._element.tagName == tag.toUpperCase();
+ }
+
+ tag(tag="div")
+ {
+ var element = document.createElement(tag);
+ this._element.appendChild(element);
+ return this.new_component(element);
+ }
+
+ retag(new_tag)
+ {
+ if (this._element.tagName == new_tag.toUpperCase())
+ return this;
+
+ var element = document.createElement(new_tag);
+ element.innerHTML = this._element.innerHTML;
+ this._element.parentNode.replaceChild(element, this._element);
+ this._element = element;
+ return this;
+ }
+
+ text(value)
+ {
+ value = (value == undefined) ? "undefined" : value.toString();
+ this._element.innerHTML = (value != "") ? value : "";
+ return this;
+ }
+
+ id(value)
+ {
+ this._element.id = value;
+ return this;
+ }
+
+ classify(value)
+ {
+ this._element.classList.add(value);
+ return this;
+ }
+
+ style(key, value)
+ {
+ this._element.style[key] = value;
+ return this;
+ }
+
+ attr(key, value=undefined)
+ {
+ if (value === undefined)
+ return this._element.getAttribute(key);
+ else if (value === null)
+ this._element.removeAttribute(key);
+ else
+ this._element.setAttribute(key, value);
+ return this;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+class ComponentInteract extends ComponentDom
+{
+ link(resource=undefined, query_params={})
+ {
+ if (resource != undefined)
+ {
+ var href = resource;
+ var sep = "?";
+ for (const key in query_params)
+ {
+ href += sep + key + "=" + query_params[key];
+ sep = "&";
+ }
+ }
+ else
+ href = "javascript:void(0);";
+
+ var text = this._element.innerHTML;
+ this._element.innerHTML = "";
+ this.tag("a").text(text).attr("href", href);
+ return this;
+ }
+
+ on(what, func, ...args)
+ {
+ const thunk = (src) => {
+ if (src.target != this._element)
+ return;
+
+ func(...args);
+ src.stopPropagation();
+ };
+
+ this._element.addEventListener(what, thunk);
+ return this;
+ }
+
+ on_click(func, ...args)
+ {
+ this.classify("zen_action");
+ return this.on("click", func, ...args);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+export class Component extends ComponentInteract
+{
+ new_component(...args)
+ {
+ return new Component(...args);
+ }
+}