-
Notifications
You must be signed in to change notification settings - Fork 30
Customization
Iván SZKIBA edited this page Dec 4, 2023
·
9 revisions
This page is about configuration customization.
The long-term goal is to eliminate the need for customization. Many features have already been created that partially make customization unnecessary (foldable sections, gRPC, browser, WebSockets charts). Until the development reaches this long-term goal, it is possible to customize the dashboard configuration.
Warning
The customization of the configuration is not an official dashboard feature, use at your own risk. It is possible that the customization changes in a way that is not backward compatible.
function customize(config, { tab }) {
tab("Custom", ({ section }) => {
section("Sample Section", ({ panel }) => {
panel("Sample Panel", ({ panel, serie }) => {
panel.summary = "Example full width panel";
panel.fullWidth = true;
serie("http_reqs[?!tags && rate]", "Request Rate");
serie("http_req_duration[?!tags && p95]", "Request Duration p(95)");
serie("http_req_failed[?!tags && rate ]", "Request Failed");
});
});
});
}
// --- Helpers ---
export default function (config) {
const builder = new Builder(config);
customize(config, { tab: (...args) => builder.tab(...args) });
return config;
}
class Builder {
constructor(config) {
this.config = config;
}
tab(...args) {
const [title, summary, self, fn] = getargs(args, { sections: [] });
self.title = title;
self.summary = summary;
if (!self.id) self.id = `tab-${this.config.tabs.length}`;
this.currentTab = self;
fn({ tab: self, section: (...args) => this.section(...args) });
this.config.tabs.push(self);
delete this.currentTab;
}
section(...args) {
const [title, summary, self, fn] = getargs(args, { panels: [] });
self.title = title;
self.summary = summary;
if (!self.id) self.id = `${this.currentTab.id}.section-${this.currentTab.sections.length}`;
this.currentSection = self;
fn({ section: self, panel: (...args) => this.panel(...args) });
this.currentTab.sections.push(self);
delete this.currentSection;
}
panel(...args) {
const [title, kind, self, fn] = getargs(args, { series: [] });
self.title = title;
if (kind) self.kind = kind;
if (!self.id) self.id = `${this.currentSection.id}.panel-${this.currentSection.panels.length}`;
this.currentPanel = self;
fn({ panel: self, serie: (...args) => this.serie(...args) });
if (!self.kind) self.kind = "chart";
this.currentSection.panels.push(self);
delete this.currentPanel;
}
serie(...args) {
const [query, legend, self] = getargs(args, {});
self.query = query;
self.legend = legend;
if (self.query == undefined) self.query = self.legend;
this.currentPanel.series.push(self);
}
}
function getargs(args, obj) {
const ret = [];
let idx = 0;
ret.push(typeof args[idx] == "string" ? args[idx++] : undefined);
ret.push(typeof args[idx] == "string" ? args[idx++] : undefined);
ret.push(typeof args[idx] == "object" ? Object.assign(obj, args[idx++]) : obj);
ret.push(typeof args[idx] == "function" ? args[idx++] : () => {});
return ret;
}