Refactor components

Implement context mechanism to pass default attributes to descendant
components.
This commit is contained in:
Zaid Abdulla committed 2019-02-12 23:11:27 -08:00
1 parent d46d133878
commit ee8c43747e
35 files changed
+334 -262

No files matched your search

+4 -4
View File
@@ -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;
};
}
+2 -1
View File
@@ -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
View File
@@ -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 };
+7 -9
View File
@@ -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;
};
}
+6 -8
View File
@@ -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;
};
}
+5 -5
View File
@@ -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;
};
}
+12 -8
View File
@@ -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;
};
}
+6 -7
View File
@@ -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;
};
}
+5 -5
View File
@@ -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;
};
}
+12 -12
View File
@@ -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);
}
};
};
}
+12 -10
View File
@@ -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;
};
}
+6 -7
View File
@@ -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;
};
}
+5 -5
View File
@@ -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;
};
}
+5 -5
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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 };
};
}
+6 -5
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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 };
};
}
+8 -5
View File
@@ -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
View File
@@ -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
View File
@@ -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 };
};
}
+4 -4
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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 };
};
}
+5 -5
View File
@@ -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
View File
@@ -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
View File
@@ -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 };
};
}
+7 -6
View File
@@ -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
View File
@@ -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;
};
}
+11 -9
View File
@@ -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 };
};
}