Refactor components
Implement context mechanism to pass default attributes to descendant components.
This commit is contained in:
1 parent
d46d133878
commit
ee8c43747e
35 files changed
+334
-262
No files matched your search
+4
-4
@@ -2,7 +2,8 @@
|
||||
|
||||
import m from "mithril";
|
||||
|
||||
const menu = {
|
||||
export default function menu() {
|
||||
return {
|
||||
view: vnode => {
|
||||
const active = { [vnode.attrs.page]: "active" };
|
||||
const tabs = [];
|
||||
@@ -59,6 +60,5 @@ const menu = {
|
||||
|
||||
return m("nav#side-menu", m("ul", tabs));
|
||||
}
|
||||
};
|
||||
|
||||
export default menu;
|
||||
};
|
||||
}
|
||||
@@ -17,6 +17,7 @@ import * as filesPage from "./files-page";
|
||||
import * as configPage from "./config-page";
|
||||
import Authorizer from "../lib//common/authorizer";
|
||||
import * as notifications from "./notifications";
|
||||
import { contextifyComponent } from "./components";
|
||||
|
||||
window.authorizer = new Authorizer(window.permissionSets);
|
||||
|
||||
@@ -49,7 +50,7 @@ function pagify(pageName, page) {
|
||||
lastRenderTimestamp = Date.now();
|
||||
let p;
|
||||
if (state && state.error) p = m(errorPage.component, state);
|
||||
else p = m(page.component, state);
|
||||
else p = m(contextifyComponent(page.component), state);
|
||||
fulfill();
|
||||
return m(layout, { page: pageName }, p);
|
||||
}
|
||||
|
||||
+71
-4
@@ -1,5 +1,6 @@
|
||||
"use strict";
|
||||
|
||||
import m from "mithril";
|
||||
import parameter from "./components/parameter";
|
||||
import parameterList from "./components/parameter-list";
|
||||
import parameterTable from "./components/parameter-table";
|
||||
@@ -12,6 +13,7 @@ import deviceActions from "./components/device-actions";
|
||||
import tags from "./components/tags";
|
||||
import ping from "./components/ping";
|
||||
import deviceLink from "./components/device-link";
|
||||
import longTextComponent from "./long-text-component";
|
||||
|
||||
const comps = {
|
||||
parameter,
|
||||
@@ -25,11 +27,76 @@ const comps = {
|
||||
"device-actions": deviceActions,
|
||||
tags,
|
||||
ping,
|
||||
"device-link": deviceLink
|
||||
"device-link": deviceLink,
|
||||
"long-text": longTextComponent
|
||||
};
|
||||
|
||||
export function get(name) {
|
||||
const c = comps[name];
|
||||
if (!c) throw new Error(`No such component '${name}'`);
|
||||
const contextifiedComponents = new WeakMap();
|
||||
const vnodeContext = new WeakMap();
|
||||
|
||||
function contextFn(context, ...argumentsList) {
|
||||
const vnode = Reflect.apply(M, undefined, argumentsList);
|
||||
vnodeContext.set(vnode, context);
|
||||
return vnode;
|
||||
}
|
||||
|
||||
const M = new Proxy(m, {
|
||||
apply: (target, thisArg, argumentsList) => {
|
||||
const c = argumentsList[0];
|
||||
if (typeof c !== "string") argumentsList[0] = contextifyComponent(c);
|
||||
else if (comps[c]) argumentsList[0] = contextifyComponent(comps[c]);
|
||||
|
||||
return Reflect.apply(target, undefined, argumentsList);
|
||||
},
|
||||
get: (target, prop) => {
|
||||
if (prop === "context") return contextFn;
|
||||
else return Reflect.get(target, prop);
|
||||
}
|
||||
});
|
||||
|
||||
function applyContext(vnode, parentContext) {
|
||||
if (Array.isArray(vnode)) {
|
||||
for (const c of vnode) applyContext(c, parentContext);
|
||||
} else if (vnode && typeof vnode === "object" && vnode.tag) {
|
||||
const vc = Object.assign({}, parentContext, vnodeContext.get(vnode));
|
||||
vnodeContext.set(vnode, vc);
|
||||
vnode.attrs = Object.assign({}, vc, vnode.attrs);
|
||||
if (vnode.children && vnode.children.length)
|
||||
for (const c of vnode.children) applyContext(c, vc);
|
||||
}
|
||||
}
|
||||
|
||||
export function contextifyComponent(component) {
|
||||
let c = contextifiedComponents.get(component);
|
||||
if (!c) {
|
||||
if (typeof component !== "function") {
|
||||
c = Object.assign({}, component);
|
||||
const view = component.view;
|
||||
c.view = vnode => {
|
||||
const context = vnodeContext.get(vnode) || {};
|
||||
const res = view(vnode, M);
|
||||
applyContext(res, context);
|
||||
return res;
|
||||
};
|
||||
} else if (!component.prototype.view) {
|
||||
c = initialNode => {
|
||||
const state = component(initialNode);
|
||||
const view = state.view;
|
||||
state.view = vnode => {
|
||||
const context = vnodeContext.get(vnode) || {};
|
||||
const res = view(vnode, M);
|
||||
applyContext(res, context);
|
||||
return res;
|
||||
};
|
||||
return state;
|
||||
};
|
||||
} else {
|
||||
// TODO support class components
|
||||
throw new Error("Class components not supported");
|
||||
}
|
||||
contextifiedComponents.set(component, c);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
export { M as m };
|
||||
@@ -1,9 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
import m from "mithril";
|
||||
import * as components from "../components";
|
||||
import { m } from "../components";
|
||||
import * as taskQueue from "../task-queue";
|
||||
import longTextComponent from "../long-text-component";
|
||||
import { parse } from "../../lib/common/expression-parser";
|
||||
import memoize from "../../lib/common/memoize";
|
||||
|
||||
@@ -13,7 +11,8 @@ function escapeRegExp(str) {
|
||||
return str.replace(/[-[\]/{}()*+?.\\^$|]/g, "\\$&");
|
||||
}
|
||||
|
||||
const component = {
|
||||
export default function component() {
|
||||
return {
|
||||
view: vnode => {
|
||||
const device = vnode.attrs.device;
|
||||
|
||||
@@ -50,7 +49,7 @@ const component = {
|
||||
if (p.object === false) {
|
||||
val.push(
|
||||
m(
|
||||
components.get("parameter"),
|
||||
"parameter",
|
||||
Object.assign({ device: device, parameter: memoizedParse(k) })
|
||||
)
|
||||
);
|
||||
@@ -112,7 +111,7 @@ const component = {
|
||||
return m(
|
||||
"tr",
|
||||
attrs,
|
||||
m("td.left", m(longTextComponent, { text: k })),
|
||||
m("td.left", m("long-text", { text: k })),
|
||||
m("td.right", val)
|
||||
);
|
||||
});
|
||||
@@ -132,6 +131,5 @@ const component = {
|
||||
m(".parameter-list", m("table", m("tbody", rows)))
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default component;
|
||||
};
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
"use strict";
|
||||
|
||||
import m from "mithril";
|
||||
import * as components from "../components";
|
||||
import { m } from "../components";
|
||||
import * as store from "../store";
|
||||
|
||||
const component = {
|
||||
export default function component() {
|
||||
return {
|
||||
view: vnode => {
|
||||
if (vnode.attrs.filter) {
|
||||
if (!store.evaluateExpression(vnode.attrs.filter, vnode.attrs.device))
|
||||
@@ -13,12 +13,10 @@ const component = {
|
||||
|
||||
const children = Object.values(vnode.attrs.components).map(c => {
|
||||
if (typeof c !== "object") return `${c}`;
|
||||
const attrs = Object.assign({}, vnode.attrs, c);
|
||||
return m(components.get(attrs.type), attrs);
|
||||
return m(c.type, c);
|
||||
});
|
||||
if (vnode.attrs.element) return m(vnode.attrs.element, children);
|
||||
else return children;
|
||||
}
|
||||
};
|
||||
|
||||
export default component;
|
||||
};
|
||||
}
|
||||
@@ -1,11 +1,12 @@
|
||||
"use strict";
|
||||
|
||||
import m from "mithril";
|
||||
import { m } from "../components";
|
||||
import * as taskQueue from "../task-queue";
|
||||
import * as notifications from "../notifications";
|
||||
import * as store from "../store";
|
||||
|
||||
const component = {
|
||||
export default function component() {
|
||||
return {
|
||||
view: vnode => {
|
||||
const device = vnode.attrs.device;
|
||||
|
||||
@@ -85,6 +86,5 @@ const component = {
|
||||
|
||||
return m(".actions-bar", buttons);
|
||||
}
|
||||
};
|
||||
|
||||
export default component;
|
||||
};
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
"use strict";
|
||||
|
||||
import m from "mithril";
|
||||
import { m } from "../components";
|
||||
import * as store from "../store";
|
||||
import * as notifications from "../notifications";
|
||||
|
||||
const component = {
|
||||
export default function component() {
|
||||
return {
|
||||
view: vnode => {
|
||||
const device = vnode.attrs.device;
|
||||
const deviceId = device["DeviceID.ID"].value[0];
|
||||
@@ -14,9 +15,13 @@ const component = {
|
||||
["<", ["PARAM", "_id"], `${deviceId}:zzzz`]
|
||||
]);
|
||||
|
||||
const headers = ["Channel", "Code", "Message", "Retries", "Timestamp"].map(
|
||||
l => m("th", l)
|
||||
);
|
||||
const headers = [
|
||||
"Channel",
|
||||
"Code",
|
||||
"Message",
|
||||
"Retries",
|
||||
"Timestamp"
|
||||
].map(l => m("th", l));
|
||||
const thead = m("thead", m("tr", headers));
|
||||
|
||||
const rows = [];
|
||||
@@ -66,6 +71,5 @@ const component = {
|
||||
|
||||
return m("table.table", thead, tbody);
|
||||
}
|
||||
};
|
||||
|
||||
export default component;
|
||||
};
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
"use strict";
|
||||
|
||||
import m from "mithril";
|
||||
import * as components from "../components";
|
||||
import { m } from "../components";
|
||||
|
||||
const component = {
|
||||
export default function component() {
|
||||
return {
|
||||
view: vnode => {
|
||||
let deviceId;
|
||||
if (vnode.attrs.device)
|
||||
@@ -12,7 +12,7 @@ const component = {
|
||||
const children = Object.values(vnode.attrs.components).map(c => {
|
||||
if (typeof c !== "object") return `${c}`;
|
||||
const attrs = Object.assign({}, vnode.attrs, c);
|
||||
return m(components.get(attrs.type), attrs);
|
||||
return m(attrs.type, attrs);
|
||||
});
|
||||
if (deviceId) {
|
||||
return m(
|
||||
@@ -24,6 +24,5 @@ const component = {
|
||||
return children;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default component;
|
||||
};
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
"use strict";
|
||||
|
||||
import m from "mithril";
|
||||
import { m } from "../components";
|
||||
import config from "../config";
|
||||
import * as store from "../store";
|
||||
|
||||
const CHARTS = config.ui.overview.charts;
|
||||
|
||||
const component = {
|
||||
export default function component() {
|
||||
return {
|
||||
view: vnode => {
|
||||
const device = vnode.attrs.device;
|
||||
const chart = CHARTS[vnode.attrs.chart];
|
||||
@@ -33,6 +34,5 @@ const component = {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
export default component;
|
||||
};
|
||||
}
|
||||
@@ -1,21 +1,20 @@
|
||||
"use strict";
|
||||
|
||||
import m from "mithril";
|
||||
import { get } from "../components";
|
||||
import memoize from "../../lib/common/memoize";
|
||||
import { m } from "../components";
|
||||
|
||||
const getChildAttrs = memoize((attrs, device) =>
|
||||
Object.assign({}, attrs, { device: device })
|
||||
);
|
||||
|
||||
export default {
|
||||
export default function component() {
|
||||
return {
|
||||
view: vnode => {
|
||||
const device = vnode.attrs.device;
|
||||
|
||||
const rows = Object.values(vnode.attrs.parameters).map(parameter => {
|
||||
const p = m(
|
||||
get(parameter.type || "parameter"),
|
||||
getChildAttrs(parameter, device)
|
||||
const p = m.context(
|
||||
{
|
||||
device: device,
|
||||
parameter: parameter.parameter
|
||||
},
|
||||
parameter.type || "parameter",
|
||||
parameter
|
||||
);
|
||||
|
||||
return m(
|
||||
@@ -32,4 +31,5 @@ export default {
|
||||
|
||||
return m("table.parameter-list", rows);
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
"use strict";
|
||||
|
||||
import m from "mithril";
|
||||
import * as components from "../components";
|
||||
import { m } from "../components";
|
||||
import * as taskQueue from "../task-queue";
|
||||
import * as store from "../store";
|
||||
import * as expressionParser from "../../lib/common/expression-parser";
|
||||
|
||||
const component = {
|
||||
export default function component() {
|
||||
return {
|
||||
oninit: vnode => {
|
||||
const obj = vnode.attrs.parameter;
|
||||
if (!Array.isArray(obj) || !obj[0] === "PARAM")
|
||||
@@ -55,12 +55,15 @@ const component = {
|
||||
});
|
||||
return m(
|
||||
"td",
|
||||
m(
|
||||
components.get(p.type || "parameter"),
|
||||
m.context(
|
||||
{
|
||||
device: device,
|
||||
parameter: param
|
||||
},
|
||||
p.type || "parameter",
|
||||
Object.assign({}, p, {
|
||||
device: device,
|
||||
parameter: param,
|
||||
label: ""
|
||||
parameter: param
|
||||
})
|
||||
)
|
||||
);
|
||||
@@ -127,6 +130,5 @@ const component = {
|
||||
|
||||
return [label, m("table.table", thead, m("tbody", rows))];
|
||||
}
|
||||
};
|
||||
|
||||
export default component;
|
||||
};
|
||||
}
|
||||
@@ -1,12 +1,11 @@
|
||||
"use strict";
|
||||
|
||||
import m from "mithril";
|
||||
import { m } from "../components";
|
||||
import * as taskQueue from "../task-queue";
|
||||
import * as store from "../store";
|
||||
import * as expression from "../../lib/common/expression";
|
||||
import memoize from "../../lib/common/memoize";
|
||||
import timeAgo from "../timeago";
|
||||
import longTextComponent from "../long-text-component";
|
||||
|
||||
const evaluateParam = memoize((exp, obj, now) => {
|
||||
let timestamp = now;
|
||||
@@ -32,7 +31,8 @@ const evaluateParam = memoize((exp, obj, now) => {
|
||||
return { value, timestamp, parameter };
|
||||
});
|
||||
|
||||
const component = {
|
||||
export default function component() {
|
||||
return {
|
||||
view: vnode => {
|
||||
const device = vnode.attrs.device;
|
||||
|
||||
@@ -68,7 +68,7 @@ const component = {
|
||||
);
|
||||
}
|
||||
|
||||
const el = m(longTextComponent, { text: `${value}` });
|
||||
const el = m("long-text", { text: `${value}` });
|
||||
|
||||
return m(
|
||||
"span",
|
||||
@@ -88,6 +88,5 @@ const component = {
|
||||
edit
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default component;
|
||||
};
|
||||
}
|
||||
@@ -1,11 +1,12 @@
|
||||
"use strict";
|
||||
|
||||
import m from "mithril";
|
||||
import { m } from "../components";
|
||||
import * as store from "../store";
|
||||
|
||||
const REFRESH_INTERVAL = 3000;
|
||||
|
||||
const component = {
|
||||
export default function component() {
|
||||
return {
|
||||
oninit: vnode => {
|
||||
vnode.state.timestamp = 0;
|
||||
vnode.state.ping = null;
|
||||
@@ -51,6 +52,5 @@ const component = {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
export default component;
|
||||
};
|
||||
}
|
||||
@@ -1,11 +1,12 @@
|
||||
"use strict";
|
||||
|
||||
import m from "mithril";
|
||||
import { m } from "../components";
|
||||
import * as taskQueue from "../task-queue";
|
||||
import * as store from "../store";
|
||||
import * as notifications from "../notifications";
|
||||
|
||||
const component = {
|
||||
export default function component() {
|
||||
return {
|
||||
view: vnode => {
|
||||
const device = vnode.attrs.device;
|
||||
|
||||
@@ -66,6 +67,5 @@ const component = {
|
||||
"Summon"
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default component;
|
||||
};
|
||||
}
|
||||
+13
-7
@@ -1,10 +1,11 @@
|
||||
"use strict";
|
||||
|
||||
import m from "mithril";
|
||||
import { m } from "../components";
|
||||
import * as notifications from "../notifications";
|
||||
import * as store from "../store";
|
||||
|
||||
const component = {
|
||||
export default function component() {
|
||||
return {
|
||||
view: vnode => {
|
||||
const device = vnode.attrs.device;
|
||||
let writable = true;
|
||||
@@ -34,12 +35,18 @@ const component = {
|
||||
.updateTags(deviceId, { [tag]: false })
|
||||
.then(() => {
|
||||
e.target.disabled = false;
|
||||
notifications.push("success", `${deviceId}: Tags updated`);
|
||||
notifications.push(
|
||||
"success",
|
||||
`${deviceId}: Tags updated`
|
||||
);
|
||||
store.fulfill(0, Date.now());
|
||||
})
|
||||
.catch(err => {
|
||||
e.target.disabled = false;
|
||||
notifications.push("error", `${deviceId}: ${err.message}`);
|
||||
notifications.push(
|
||||
"error",
|
||||
`${deviceId}: ${err.message}`
|
||||
);
|
||||
});
|
||||
}
|
||||
},
|
||||
@@ -79,6 +86,5 @@ const component = {
|
||||
)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default component;
|
||||
};
|
||||
}
|
||||
+8
-14
@@ -1,12 +1,10 @@
|
||||
"use strict";
|
||||
|
||||
import m from "mithril";
|
||||
|
||||
import { m } from "./components";
|
||||
import * as store from "./store";
|
||||
import * as notifications from "./notifications";
|
||||
import putFormComponent from "./put-form-component";
|
||||
import * as overlay from "./overlay";
|
||||
import longTextComponent from "./long-text-component";
|
||||
import * as expressionParser from "../lib/common/expression-parser";
|
||||
import { loadCodeMirror } from "./dynamic-loader";
|
||||
|
||||
@@ -84,7 +82,7 @@ function escapeRegExp(str) {
|
||||
return str.replace(/[-[\]/{}()*+?.\\^$|]/g, "\\$&");
|
||||
}
|
||||
|
||||
function init() {
|
||||
export function init() {
|
||||
if (!window.authorizer.hasAccess("config", 2)) {
|
||||
return Promise.reject(
|
||||
new Error("You are not authorized to view this page")
|
||||
@@ -177,14 +175,10 @@ function renderTable(confsResponse, searchString) {
|
||||
m(
|
||||
"tr",
|
||||
attrs,
|
||||
m("td.left", m(longTextComponent, { text: conf._id })),
|
||||
m("td.left", m("long-text", { text: conf._id })),
|
||||
m(
|
||||
"td.right",
|
||||
m("span", [
|
||||
m(longTextComponent, { text: `${conf.value}` }),
|
||||
edit,
|
||||
del
|
||||
])
|
||||
m("span", [m("long-text", { text: `${conf.value}` }), edit, del])
|
||||
)
|
||||
)
|
||||
);
|
||||
@@ -196,7 +190,8 @@ function renderTable(confsResponse, searchString) {
|
||||
return m("table", m("tbody", rows));
|
||||
}
|
||||
|
||||
const component = {
|
||||
export function component() {
|
||||
return {
|
||||
view: vnode => {
|
||||
document.title = "Config - GenieACS";
|
||||
|
||||
@@ -270,6 +265,5 @@ const component = {
|
||||
)
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
export { init, component };
|
||||
};
|
||||
}
|
||||
+9
-18
@@ -1,12 +1,10 @@
|
||||
"use strict";
|
||||
|
||||
import m from "mithril";
|
||||
|
||||
import { m } from "./components";
|
||||
import config from "./config";
|
||||
import * as store from "./store";
|
||||
import * as components from "./components";
|
||||
|
||||
function init(args) {
|
||||
export function init(args) {
|
||||
if (!window.authorizer.hasAccess("devices", 2)) {
|
||||
return Promise.reject(
|
||||
new Error("You are not authorized to view this page")
|
||||
@@ -19,7 +17,8 @@ function init(args) {
|
||||
});
|
||||
}
|
||||
|
||||
const component = {
|
||||
export function component() {
|
||||
return {
|
||||
view: vnode => {
|
||||
document.title = `${vnode.attrs.deviceId} - Devices - GenieACS`;
|
||||
|
||||
@@ -28,18 +27,10 @@ const component = {
|
||||
const conf = config.ui.device;
|
||||
const cmps = [];
|
||||
|
||||
for (const c of Object.values(conf)) {
|
||||
cmps.push(
|
||||
m(components.get(c["type"]), Object.assign({ device: dev[0] }, c))
|
||||
);
|
||||
}
|
||||
for (const c of Object.values(conf))
|
||||
cmps.push(m.context({ device: dev[0] }, c["type"], c));
|
||||
|
||||
return [
|
||||
m("h1", vnode.attrs.deviceId),
|
||||
m("span", dev[0]["InternetGatewayDevice.DeviceInfo.SerialNumber"]),
|
||||
cmps
|
||||
];
|
||||
return [m("h1", vnode.attrs.deviceId), cmps];
|
||||
}
|
||||
};
|
||||
|
||||
export { init, component };
|
||||
};
|
||||
}
|
||||
+16
-16
@@ -1,11 +1,9 @@
|
||||
"use strict";
|
||||
|
||||
import m from "mithril";
|
||||
|
||||
import { m } from "./components";
|
||||
import config from "./config";
|
||||
import filterComponent from "./filter-component";
|
||||
import * as store from "./store";
|
||||
import * as components from "./components";
|
||||
import * as taskQueue from "./task-queue";
|
||||
import * as notifications from "./notifications";
|
||||
import { evaluate, extractParams } from "../lib/common/expression";
|
||||
@@ -36,10 +34,6 @@ const getDownloadUrl = memoize((filter, indexParameters) => {
|
||||
})}`;
|
||||
});
|
||||
|
||||
const getChildAttrs = memoize((attrs, device) =>
|
||||
Object.assign({}, attrs, { device: device })
|
||||
);
|
||||
|
||||
const unpackSmartQuery = memoize(query => {
|
||||
return expressionParser.map(query, e => {
|
||||
if (Array.isArray(e) && e[0] === "FUNC" && e[1] === "Q")
|
||||
@@ -48,7 +42,7 @@ const unpackSmartQuery = memoize(query => {
|
||||
});
|
||||
});
|
||||
|
||||
function init(args) {
|
||||
export function init(args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!window.authorizer.hasAccess("devices", 2))
|
||||
return void reject(new Error("You are not authorized to view this page"));
|
||||
@@ -138,8 +132,11 @@ function renderTable(
|
||||
},
|
||||
m("td", checkbox),
|
||||
parameters.map(p => {
|
||||
const attrs = getChildAttrs(p, device);
|
||||
const comp = m(components.get(attrs.type || "parameter"), attrs);
|
||||
const comp = m.context(
|
||||
{ device: device, parameter: p.parameter },
|
||||
p.type || "parameter",
|
||||
p
|
||||
);
|
||||
return m("td", comp);
|
||||
}),
|
||||
m(
|
||||
@@ -339,12 +336,14 @@ function renderActions(selected) {
|
||||
return m(".actions-bar", buttons);
|
||||
}
|
||||
|
||||
const component = {
|
||||
export function component() {
|
||||
return {
|
||||
view: vnode => {
|
||||
document.title = "Devices - GenieACS";
|
||||
|
||||
function showMore() {
|
||||
vnode.state.showCount = (vnode.state.showCount || PAGE_SIZE) + PAGE_SIZE;
|
||||
vnode.state.showCount =
|
||||
(vnode.state.showCount || PAGE_SIZE) + PAGE_SIZE;
|
||||
m.redraw();
|
||||
}
|
||||
|
||||
@@ -361,7 +360,9 @@ const component = {
|
||||
}
|
||||
|
||||
const sort = vnode.attrs.sort ? memoizedJsonParse(vnode.attrs.sort) : {};
|
||||
let filter = vnode.attrs.filter ? memoizedParse(vnode.attrs.filter) : true;
|
||||
let filter = vnode.attrs.filter
|
||||
? memoizedParse(vnode.attrs.filter)
|
||||
: true;
|
||||
filter = unpackSmartQuery(filter);
|
||||
|
||||
const devs = store.fetch("devices", filter, {
|
||||
@@ -404,6 +405,5 @@ const component = {
|
||||
renderActions(selected)
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
export { init, component };
|
||||
};
|
||||
}
|
||||
@@ -312,7 +312,8 @@ function renderNotifications(notifs) {
|
||||
return notificationElements;
|
||||
}
|
||||
|
||||
const component = {
|
||||
export default function component() {
|
||||
return {
|
||||
view: vnode => {
|
||||
const queue = taskQueue.getQueue();
|
||||
const staging = taskQueue.getStaging();
|
||||
@@ -332,7 +333,8 @@ const component = {
|
||||
}
|
||||
|
||||
function resizeDrawer() {
|
||||
let height = statusElement.dom.offsetTop + statusElement.dom.offsetHeight;
|
||||
let height =
|
||||
statusElement.dom.offsetTop + statusElement.dom.offsetHeight;
|
||||
if (stagingElements.length) {
|
||||
for (const s of stagingElements)
|
||||
height = Math.max(height, s.dom.offsetTop + s.dom.offsetHeight);
|
||||
@@ -493,6 +495,5 @@ const component = {
|
||||
)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default component;
|
||||
};
|
||||
}
|
||||
+5
-5
@@ -1,12 +1,12 @@
|
||||
"use strict";
|
||||
|
||||
import m from "mithril";
|
||||
import { m } from "./components";
|
||||
|
||||
const component = {
|
||||
export function component() {
|
||||
return {
|
||||
view: function(vnode) {
|
||||
document.title = "Error! - GenieACS";
|
||||
return m("p.error", vnode.attrs.error);
|
||||
}
|
||||
};
|
||||
|
||||
export { component };
|
||||
};
|
||||
}
|
||||
+16
-18
@@ -1,6 +1,6 @@
|
||||
"use strict";
|
||||
|
||||
import m from "mithril";
|
||||
import { m } from "./components";
|
||||
import config from "./config";
|
||||
import filterComponent from "./filter-component";
|
||||
import * as store from "./store";
|
||||
@@ -9,7 +9,6 @@ import memoize from "../lib/common/memoize";
|
||||
import * as smartQuery from "./smart-query";
|
||||
import { map, parse } from "../lib/common/expression-parser";
|
||||
import { loadYaml, yaml } from "./dynamic-loader";
|
||||
import longTextComponent from "./long-text-component";
|
||||
|
||||
const PAGE_SIZE = config.ui.pageSize || 10;
|
||||
|
||||
@@ -47,7 +46,7 @@ const unpackSmartQuery = memoize(query => {
|
||||
});
|
||||
});
|
||||
|
||||
function init(args) {
|
||||
export function init(args) {
|
||||
if (!window.authorizer.hasAccess("faults", 2)) {
|
||||
return Promise.reject(
|
||||
new Error("You are not authorized to view this page")
|
||||
@@ -136,17 +135,13 @@ function renderTable(
|
||||
|
||||
const tds = [m("td", checkbox)];
|
||||
for (const attr of attributes) {
|
||||
if (attr.id === "device") {
|
||||
if (attr.id === "device")
|
||||
tds.push(m("td", m("a", { href: deviceHref }, f[attr.id])));
|
||||
} else if (attr.id === "timestamp") {
|
||||
else if (attr.id === "timestamp")
|
||||
tds.push(m("td", new Date(f[attr.id]).toLocaleString()));
|
||||
} else if (attr.id === "detail") {
|
||||
tds.push(
|
||||
m("td", m(longTextComponent, { text: yaml.stringify(f[attr.id]) }))
|
||||
);
|
||||
} else {
|
||||
tds.push(m("td", f[attr.id]));
|
||||
}
|
||||
else if (attr.id === "detail")
|
||||
tds.push(m("td", m("long-text", { text: yaml.stringify(f[attr.id]) })));
|
||||
else tds.push(m("td", f[attr.id]));
|
||||
}
|
||||
|
||||
rows.push(
|
||||
@@ -234,12 +229,14 @@ function renderTable(
|
||||
];
|
||||
}
|
||||
|
||||
const component = {
|
||||
export function component() {
|
||||
return {
|
||||
view: vnode => {
|
||||
document.title = "Faults - GenieACS";
|
||||
|
||||
function showMore() {
|
||||
vnode.state.showCount = (vnode.state.showCount || PAGE_SIZE) + PAGE_SIZE;
|
||||
vnode.state.showCount =
|
||||
(vnode.state.showCount || PAGE_SIZE) + PAGE_SIZE;
|
||||
m.redraw();
|
||||
}
|
||||
|
||||
@@ -256,7 +253,9 @@ const component = {
|
||||
}
|
||||
|
||||
const sort = vnode.attrs.sort ? memoizedJsonParse(vnode.attrs.sort) : {};
|
||||
let filter = vnode.attrs.filter ? memoizedParse(vnode.attrs.filter) : true;
|
||||
let filter = vnode.attrs.filter
|
||||
? memoizedParse(vnode.attrs.filter)
|
||||
: true;
|
||||
filter = unpackSmartQuery(filter);
|
||||
|
||||
const faults = store.fetch("faults", filter, {
|
||||
@@ -292,6 +291,5 @@ const component = {
|
||||
)
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
export { init, component };
|
||||
};
|
||||
}
|
||||
+11
-9
@@ -1,7 +1,6 @@
|
||||
"use strict";
|
||||
|
||||
import m from "mithril";
|
||||
|
||||
import { m } from "./components";
|
||||
import config from "./config";
|
||||
import filterComponent from "./filter-component";
|
||||
import * as store from "./store";
|
||||
@@ -110,7 +109,7 @@ const getDownloadUrl = memoize(filter => {
|
||||
})}`;
|
||||
});
|
||||
|
||||
function init(args) {
|
||||
export function init(args) {
|
||||
if (!window.authorizer.hasAccess("files", 2)) {
|
||||
return Promise.reject(
|
||||
new Error("You are not authorized to view this page")
|
||||
@@ -319,12 +318,14 @@ function renderTable(
|
||||
];
|
||||
}
|
||||
|
||||
const component = {
|
||||
export function component() {
|
||||
return {
|
||||
view: vnode => {
|
||||
document.title = "Files - GenieACS";
|
||||
|
||||
function showMore() {
|
||||
vnode.state.showCount = (vnode.state.showCount || PAGE_SIZE) + PAGE_SIZE;
|
||||
vnode.state.showCount =
|
||||
(vnode.state.showCount || PAGE_SIZE) + PAGE_SIZE;
|
||||
m.redraw();
|
||||
}
|
||||
|
||||
@@ -341,7 +342,9 @@ const component = {
|
||||
}
|
||||
|
||||
const sort = vnode.attrs.sort ? memoizedJsonParse(vnode.attrs.sort) : {};
|
||||
let filter = vnode.attrs.filter ? memoizedParse(vnode.attrs.filter) : true;
|
||||
let filter = vnode.attrs.filter
|
||||
? memoizedParse(vnode.attrs.filter)
|
||||
: true;
|
||||
filter = unpackSmartQuery(filter);
|
||||
|
||||
const files = store.fetch("files", filter, {
|
||||
@@ -378,6 +381,5 @@ const component = {
|
||||
)
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
export { init, component };
|
||||
};
|
||||
}
|
||||
@@ -56,9 +56,13 @@ const splitFilter = memoize(filter => {
|
||||
return list;
|
||||
});
|
||||
|
||||
const component = {
|
||||
export default function component() {
|
||||
return {
|
||||
view: vnode => {
|
||||
if (!vnode.state.filterList || vnode.attrs.filter !== vnode.state.filter) {
|
||||
if (
|
||||
!vnode.state.filterList ||
|
||||
vnode.attrs.filter !== vnode.state.filter
|
||||
) {
|
||||
vnode.state.filterInvalid = 0;
|
||||
vnode.state.filter = vnode.attrs.filter;
|
||||
vnode.state.filterList = splitFilter(vnode.attrs.filter);
|
||||
@@ -110,6 +114,5 @@ const component = {
|
||||
)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default component;
|
||||
};
|
||||
}
|
||||
+4
-5
@@ -1,7 +1,6 @@
|
||||
"use strict";
|
||||
|
||||
import m from "mithril";
|
||||
|
||||
import menu from "./menu";
|
||||
import drawerComponent from "./drawer-component";
|
||||
import userMenu from "./user-menu";
|
||||
@@ -16,7 +15,8 @@ const adminPages = [
|
||||
"config"
|
||||
];
|
||||
|
||||
const layout = {
|
||||
export default function layout() {
|
||||
return {
|
||||
view: vnode => {
|
||||
let sideMenu, group;
|
||||
if (adminPages.includes(vnode.attrs.page)) {
|
||||
@@ -39,6 +39,5 @@ const layout = {
|
||||
overlay.render()
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
export default layout;
|
||||
};
|
||||
}
|
||||
+6
-7
@@ -1,15 +1,15 @@
|
||||
"use strict";
|
||||
|
||||
import m from "mithril";
|
||||
|
||||
import { m } from "./components";
|
||||
import * as store from "./store";
|
||||
import * as notifications from "./notifications";
|
||||
|
||||
function init(args) {
|
||||
export function init(args) {
|
||||
return Promise.resolve(args);
|
||||
}
|
||||
|
||||
const component = {
|
||||
export function component() {
|
||||
return {
|
||||
view: vnode => {
|
||||
if (window.username) m.route.set(vnode.attrs.continue || "/");
|
||||
|
||||
@@ -67,6 +67,5 @@ const component = {
|
||||
)
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
export { init, component };
|
||||
};
|
||||
}
|
||||
@@ -3,7 +3,8 @@
|
||||
import m from "mithril";
|
||||
import * as overlay from "./overlay";
|
||||
|
||||
const component = {
|
||||
export default function component() {
|
||||
return {
|
||||
view: vnode => {
|
||||
const text = vnode.attrs.text;
|
||||
const element = vnode.attrs.element || "span";
|
||||
@@ -51,6 +52,5 @@ const component = {
|
||||
text
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default component;
|
||||
};
|
||||
}
|
||||
+10
-5
@@ -2,7 +2,8 @@
|
||||
|
||||
import m from "mithril";
|
||||
|
||||
const menu = {
|
||||
export default function menu() {
|
||||
return {
|
||||
view: vnode => {
|
||||
const active = { [vnode.attrs.page]: "active" };
|
||||
|
||||
@@ -37,7 +38,12 @@ const menu = {
|
||||
);
|
||||
}
|
||||
|
||||
const adminPages = ["presets", "provisions", "virtualParameters", "files"];
|
||||
const adminPages = [
|
||||
"presets",
|
||||
"provisions",
|
||||
"virtualParameters",
|
||||
"files"
|
||||
];
|
||||
for (const page of adminPages) {
|
||||
if (window.authorizer.hasAccess(page, 2)) {
|
||||
tabs.push(
|
||||
@@ -53,6 +59,5 @@ const menu = {
|
||||
|
||||
return m("nav", m("ul", tabs));
|
||||
}
|
||||
};
|
||||
|
||||
export default menu;
|
||||
};
|
||||
}
|
||||
+2
-4
@@ -4,7 +4,7 @@ import m from "mithril";
|
||||
|
||||
const notifications = new Set();
|
||||
|
||||
function push(type, message) {
|
||||
export function push(type, message) {
|
||||
const n = { type: type, message: message, timestamp: Date.now() };
|
||||
notifications.add(n);
|
||||
m.redraw();
|
||||
@@ -14,8 +14,6 @@ function push(type, message) {
|
||||
}, 4000);
|
||||
}
|
||||
|
||||
function getNotifications() {
|
||||
export function getNotifications() {
|
||||
return notifications;
|
||||
}
|
||||
|
||||
export { push, getNotifications };
|
||||
+7
-7
@@ -1,6 +1,6 @@
|
||||
"use strict";
|
||||
|
||||
import m from "mithril";
|
||||
import { m } from "./components";
|
||||
import config from "./config";
|
||||
import * as store from "./store";
|
||||
import pieChartComponent from "./pie-chart-component";
|
||||
@@ -26,7 +26,7 @@ function queryCharts(charts) {
|
||||
return charts;
|
||||
}
|
||||
|
||||
const init = function() {
|
||||
export function init() {
|
||||
if (!window.authorizer.hasAccess("devices", 1)) {
|
||||
return Promise.reject(
|
||||
new Error("You are not authorized to view this page")
|
||||
@@ -34,9 +34,10 @@ const init = function() {
|
||||
}
|
||||
|
||||
return Promise.resolve({ charts: queryCharts(CHARTS) });
|
||||
};
|
||||
}
|
||||
|
||||
const component = {
|
||||
export function component() {
|
||||
return {
|
||||
view: vnode => {
|
||||
document.title = "Overview - GenieACS";
|
||||
const children = [];
|
||||
@@ -59,6 +60,5 @@ const component = {
|
||||
|
||||
return children;
|
||||
}
|
||||
};
|
||||
|
||||
export { init, component };
|
||||
};
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
"use strict";
|
||||
|
||||
import m from "mithril";
|
||||
import { m } from "./components";
|
||||
import { stringify } from "../lib/common/expression-parser";
|
||||
import memoize from "../lib/common/memoize";
|
||||
|
||||
@@ -115,10 +115,10 @@ const drawChart = function(chartData) {
|
||||
]);
|
||||
};
|
||||
|
||||
const component = {
|
||||
export default function component() {
|
||||
return {
|
||||
view: vnode => {
|
||||
return drawChart(vnode.attrs.chart);
|
||||
}
|
||||
};
|
||||
|
||||
export default component;
|
||||
};
|
||||
}
|
||||
+11
-9
@@ -1,7 +1,6 @@
|
||||
"use strict";
|
||||
|
||||
import m from "mithril";
|
||||
|
||||
import { m } from "./components";
|
||||
import config from "./config";
|
||||
import filterComponent from "./filter-component";
|
||||
import * as overlay from "./overlay";
|
||||
@@ -108,7 +107,7 @@ const getDownloadUrl = memoize(filter => {
|
||||
})}`;
|
||||
});
|
||||
|
||||
function init(args) {
|
||||
export function init(args) {
|
||||
if (!window.authorizer.hasAccess("presets", 2)) {
|
||||
return Promise.reject(
|
||||
new Error("You are not authorized to view this page")
|
||||
@@ -383,12 +382,14 @@ function renderTable(
|
||||
];
|
||||
}
|
||||
|
||||
const component = {
|
||||
export function component() {
|
||||
return {
|
||||
view: vnode => {
|
||||
document.title = "Presets - GenieACS";
|
||||
|
||||
function showMore() {
|
||||
vnode.state.showCount = (vnode.state.showCount || PAGE_SIZE) + PAGE_SIZE;
|
||||
vnode.state.showCount =
|
||||
(vnode.state.showCount || PAGE_SIZE) + PAGE_SIZE;
|
||||
m.redraw();
|
||||
}
|
||||
|
||||
@@ -405,7 +406,9 @@ const component = {
|
||||
}
|
||||
|
||||
const sort = vnode.attrs.sort ? memoizedJsonParse(vnode.attrs.sort) : {};
|
||||
let filter = vnode.attrs.filter ? memoizedParse(vnode.attrs.filter) : true;
|
||||
let filter = vnode.attrs.filter
|
||||
? memoizedParse(vnode.attrs.filter)
|
||||
: true;
|
||||
filter = unpackSmartQuery(filter);
|
||||
|
||||
const presets = store.fetch("presets", filter, {
|
||||
@@ -464,6 +467,5 @@ const component = {
|
||||
)
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
export { init, component };
|
||||
};
|
||||
}
|
||||
+11
-9
@@ -1,7 +1,6 @@
|
||||
"use strict";
|
||||
|
||||
import m from "mithril";
|
||||
|
||||
import { m } from "./components";
|
||||
import config from "./config";
|
||||
import filterComponent from "./filter-component";
|
||||
import * as store from "./store";
|
||||
@@ -98,7 +97,7 @@ const getDownloadUrl = memoize(filter => {
|
||||
})}`;
|
||||
});
|
||||
|
||||
function init(args) {
|
||||
export function init(args) {
|
||||
if (!window.authorizer.hasAccess("provisions", 2)) {
|
||||
return Promise.reject(
|
||||
new Error("You are not authorized to view this page")
|
||||
@@ -371,12 +370,14 @@ function renderTable(
|
||||
];
|
||||
}
|
||||
|
||||
const component = {
|
||||
export function component() {
|
||||
return {
|
||||
view: vnode => {
|
||||
document.title = "Provisions - GenieACS";
|
||||
|
||||
function showMore() {
|
||||
vnode.state.showCount = (vnode.state.showCount || PAGE_SIZE) + PAGE_SIZE;
|
||||
vnode.state.showCount =
|
||||
(vnode.state.showCount || PAGE_SIZE) + PAGE_SIZE;
|
||||
m.redraw();
|
||||
}
|
||||
|
||||
@@ -393,7 +394,9 @@ const component = {
|
||||
}
|
||||
|
||||
const sort = vnode.attrs.sort ? memoizedJsonParse(vnode.attrs.sort) : {};
|
||||
let filter = vnode.attrs.filter ? memoizedParse(vnode.attrs.filter) : true;
|
||||
let filter = vnode.attrs.filter
|
||||
? memoizedParse(vnode.attrs.filter)
|
||||
: true;
|
||||
filter = unpackSmartQuery(filter);
|
||||
|
||||
const provisions = store.fetch("provisions", filter, {
|
||||
@@ -432,6 +435,5 @@ const component = {
|
||||
)
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
export { init, component };
|
||||
};
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
"use strict";
|
||||
|
||||
import m from "mithril";
|
||||
import { m } from "./components";
|
||||
import { codeMirror } from "./dynamic-loader";
|
||||
|
||||
const singular = {
|
||||
@@ -93,7 +93,8 @@ function createField(current, attr, focus) {
|
||||
});
|
||||
}
|
||||
|
||||
const component = {
|
||||
export default function component() {
|
||||
return {
|
||||
view: vnode => {
|
||||
const actionHandler = vnode.attrs.actionHandler;
|
||||
const attributes = vnode.attrs.attributes;
|
||||
@@ -153,7 +154,8 @@ const component = {
|
||||
const children = [
|
||||
m(
|
||||
"h1",
|
||||
`${current.isNew ? "New" : "Editing"} ${singular[resource] || resource}`
|
||||
`${current.isNew ? "New" : "Editing"} ${singular[resource] ||
|
||||
resource}`
|
||||
),
|
||||
m(
|
||||
"form",
|
||||
@@ -178,6 +180,5 @@ const component = {
|
||||
|
||||
return m("div.put-form", children);
|
||||
}
|
||||
};
|
||||
|
||||
export default component;
|
||||
};
|
||||
}
|
||||
+6
-5
@@ -5,7 +5,8 @@ import m from "mithril";
|
||||
import * as store from "./store";
|
||||
import * as notifications from "./notifications";
|
||||
|
||||
const userMenu = {
|
||||
export default function userMenu() {
|
||||
return {
|
||||
view: () => {
|
||||
if (window.username) {
|
||||
return m(
|
||||
@@ -38,13 +39,13 @@ const userMenu = {
|
||||
m(
|
||||
"a",
|
||||
{
|
||||
href: "#!/login?" + m.buildQueryString({ continue: m.route.get() })
|
||||
href:
|
||||
"#!/login?" + m.buildQueryString({ continue: m.route.get() })
|
||||
},
|
||||
"Log in"
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default userMenu;
|
||||
};
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
"use strict";
|
||||
|
||||
import m from "mithril";
|
||||
|
||||
import { m } from "./components";
|
||||
import config from "./config";
|
||||
import filterComponent from "./filter-component";
|
||||
import * as store from "./store";
|
||||
@@ -98,7 +97,7 @@ const getDownloadUrl = memoize(filter => {
|
||||
})}`;
|
||||
});
|
||||
|
||||
function init(args) {
|
||||
export function init(args) {
|
||||
if (!window.authorizer.hasAccess("virtualParameters", 2)) {
|
||||
return Promise.reject(
|
||||
new Error("You are not authorized to view this page")
|
||||
@@ -381,12 +380,14 @@ function renderTable(
|
||||
];
|
||||
}
|
||||
|
||||
const component = {
|
||||
export function component() {
|
||||
return {
|
||||
view: vnode => {
|
||||
document.title = "Virtual Parameters - GenieACS";
|
||||
|
||||
function showMore() {
|
||||
vnode.state.showCount = (vnode.state.showCount || PAGE_SIZE) + PAGE_SIZE;
|
||||
vnode.state.showCount =
|
||||
(vnode.state.showCount || PAGE_SIZE) + PAGE_SIZE;
|
||||
m.redraw();
|
||||
}
|
||||
|
||||
@@ -403,7 +404,9 @@ const component = {
|
||||
}
|
||||
|
||||
const sort = vnode.attrs.sort ? memoizedJsonParse(vnode.attrs.sort) : {};
|
||||
let filter = vnode.attrs.filter ? memoizedParse(vnode.attrs.filter) : true;
|
||||
let filter = vnode.attrs.filter
|
||||
? memoizedParse(vnode.attrs.filter)
|
||||
: true;
|
||||
filter = unpackSmartQuery(filter);
|
||||
|
||||
const virtualParameters = store.fetch("virtualParameters", filter, {
|
||||
@@ -442,6 +445,5 @@ const component = {
|
||||
)
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
export { init, component };
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user