export default function (config) { const tab = new TabBuilder(config); 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"); }); }); }); return config; } /** * The TabBuilder class implements a helper function to create a dashboard tab. */ class TabBuilder extends Function { constructor(config) { super(); this.config = config; return new Proxy(this, { apply: (target, _, args) => target._tab(...args) }); } _tab(...args) { const [title, summary, self, fn] = this._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] = this._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] = this._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] = this._getargs(args, {}); self.query = query; self.legend = legend; if (self.query == undefined) self.query = self.legend; this.currentPanel.series.push(self); } _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; } }