Improve devices page filter
This commit is contained in:
1 parent
ea2e3707e3
commit
a7e07cbde9
3 files changed
+78
-54
No files matched your search
@@ -69,6 +69,9 @@ i {
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
border-top-left-radius: 6px;
|
border-top-left-radius: 6px;
|
||||||
border-top-right-radius: 6px;
|
border-top-right-radius: 6px;
|
||||||
|
border-top: 1px solid var(--color1);
|
||||||
|
border-left: 1px solid var(--color1);
|
||||||
|
border-right: 1px solid var(--color1);
|
||||||
transition: background-color var(--fade);
|
transition: background-color var(--fade);
|
||||||
&.active,
|
&.active,
|
||||||
&:hover {
|
&:hover {
|
||||||
@@ -208,5 +211,18 @@ button {
|
|||||||
width: 30em;
|
width: 30em;
|
||||||
font-size: 90%;
|
font-size: 90%;
|
||||||
display: block;
|
display: block;
|
||||||
|
border: 1px solid var(--color1);
|
||||||
|
background-color: var(--color3);
|
||||||
|
margin: 2px;
|
||||||
|
border-radius: 4px;
|
||||||
|
transition: border-color var(--fade), background-color var(--fade);
|
||||||
|
&.error {
|
||||||
|
background-color: #efcbcf;
|
||||||
|
border-color: #e6b2b7;
|
||||||
|
}
|
||||||
|
&:focus,
|
||||||
|
&:hover {
|
||||||
|
border-color: var(--color4);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+24
-42
@@ -4,6 +4,7 @@ import m from "mithril";
|
|||||||
|
|
||||||
import config from "./config";
|
import config from "./config";
|
||||||
import filterComponent from "./filter-component";
|
import filterComponent from "./filter-component";
|
||||||
|
import * as filterParser from "../common/filter-parser";
|
||||||
|
|
||||||
function load(filter, limit) {
|
function load(filter, limit) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@@ -45,47 +46,14 @@ function count(filter, limit) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function preprocessFilter(filter) {
|
|
||||||
if (Array.isArray(filter)) {
|
|
||||||
filter = filter.map(f => {
|
|
||||||
f = f.trim();
|
|
||||||
if (f.startsWith("(")) return f;
|
|
||||||
|
|
||||||
let match = f.match(/([^=<>]+)([=<>]+)(.+)/);
|
|
||||||
|
|
||||||
let param = match[1].trim();
|
|
||||||
let op = match[2].trim();
|
|
||||||
let value = match[3].trim();
|
|
||||||
|
|
||||||
try {
|
|
||||||
value = JSON.parse(value);
|
|
||||||
} catch (err) {
|
|
||||||
// eslint-disable-line no-empty
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let cf of config.filter)
|
|
||||||
if (param === cf.label) param = cf.parameter;
|
|
||||||
|
|
||||||
if (param === "tag") {
|
|
||||||
let tag = value.replace(/[^a-zA-Z0-9]/g, "_");
|
|
||||||
if (op === "=") return `Tags.${tag} is not null`;
|
|
||||||
else if (op === "<>") return `Tags.${tag} is null`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return `${param} ${op} ${JSON.stringify(value)}`;
|
|
||||||
});
|
|
||||||
filter = "(" + filter.join(") AND (") + ")";
|
|
||||||
}
|
|
||||||
return filter;
|
|
||||||
}
|
|
||||||
|
|
||||||
function init(args) {
|
function init(args) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let filter = preprocessFilter(args.filter);
|
let filter;
|
||||||
|
if (args.filter) filter = filterParser.parse(args.filter);
|
||||||
|
|
||||||
Promise.all([count(filter), load(filter, config.pageSize)])
|
Promise.all([count(args.filter), load(args.filter, config.pageSize)])
|
||||||
.then(res => {
|
.then(res => {
|
||||||
resolve({ filter: args.filter, total: res[0], devices: res[1] });
|
resolve({ filter: filter, total: res[0], devices: res[1] });
|
||||||
})
|
})
|
||||||
.catch(reject);
|
.catch(reject);
|
||||||
});
|
});
|
||||||
@@ -129,20 +97,34 @@ function renderTable(devices, parameters, total, showMoreCallback) {
|
|||||||
const component = {
|
const component = {
|
||||||
view: vnode => {
|
view: vnode => {
|
||||||
document.title = "Devices - GenieACS";
|
document.title = "Devices - GenieACS";
|
||||||
|
|
||||||
function showMore() {
|
function showMore() {
|
||||||
const lastDevice = vnode.attrs.devices[vnode.attrs.devices.length - 1];
|
const lastDevice = vnode.attrs.devices[vnode.attrs.devices.length - 1];
|
||||||
let f = (vnode.attrs.filter || []).concat(
|
let f = filterParser.and(vnode.attrs.filter, [
|
||||||
`DeviceID.ID > "${lastDevice["DeviceID.ID"].value[0]}"`
|
">",
|
||||||
);
|
"DeviceID.ID",
|
||||||
load(preprocessFilter(f), config.pageSize).then(res => {
|
lastDevice["DeviceID.ID"].value[0]
|
||||||
|
]);
|
||||||
|
|
||||||
|
load(filterParser.stringify(f), config.pageSize).then(res => {
|
||||||
vnode.attrs.devices = vnode.attrs.devices.concat(res);
|
vnode.attrs.devices = vnode.attrs.devices.concat(res);
|
||||||
if (res.length < config.pageSize)
|
if (res.length < config.pageSize)
|
||||||
vnode.attrs.total = vnode.attrs.devices.length;
|
vnode.attrs.total = vnode.attrs.devices.length;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onFilterChanged(filter) {
|
||||||
|
let params = {};
|
||||||
|
if (filter) params.filter = filterParser.stringify(filter);
|
||||||
|
m.route.set("/devices", params);
|
||||||
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
m("h1", "Listing devices"),
|
m("h1", "Listing devices"),
|
||||||
m(filterComponent, { filterList: [].concat(vnode.attrs.filter) }),
|
m(filterComponent, {
|
||||||
|
filter: vnode.attrs.filter,
|
||||||
|
onChange: onFilterChanged
|
||||||
|
}),
|
||||||
renderTable(
|
renderTable(
|
||||||
vnode.attrs.devices,
|
vnode.attrs.devices,
|
||||||
config.index,
|
config.index,
|
||||||
|
|||||||
+38
-12
@@ -3,33 +3,59 @@
|
|||||||
import m from "mithril";
|
import m from "mithril";
|
||||||
|
|
||||||
import config from "./config";
|
import config from "./config";
|
||||||
|
import * as filterParser from "../common/filter-parser";
|
||||||
|
|
||||||
const component = {
|
const component = {
|
||||||
view: vnode => {
|
view: vnode => {
|
||||||
let a = m(
|
let a = m(
|
||||||
"datalist#filters",
|
"datalist#filters",
|
||||||
config.filter.map(f => m("option", { value: `${f.label} = ` }))
|
config.filter.map(f => m("option", { value: `${f.parameter} = ` }))
|
||||||
);
|
);
|
||||||
|
|
||||||
const filterList = vnode.attrs.filterList.filter(f => {
|
if (!vnode.state.filterList) {
|
||||||
return !!f;
|
vnode.state.filterList = [];
|
||||||
});
|
if (vnode.attrs.filter)
|
||||||
filterList.push("");
|
if (vnode.attrs.filter[0] === "AND")
|
||||||
|
for (let i = 1; i < vnode.attrs.filter.length; ++i)
|
||||||
|
vnode.state.filterList.push(
|
||||||
|
filterParser.stringify(vnode.attrs.filter[i])
|
||||||
|
);
|
||||||
|
else
|
||||||
|
vnode.state.filterList.push(
|
||||||
|
filterParser.stringify(vnode.attrs.filter)
|
||||||
|
);
|
||||||
|
vnode.state.filterList.push("");
|
||||||
|
}
|
||||||
|
|
||||||
|
function onChange() {
|
||||||
|
vnode.state.filterInvalid = 0;
|
||||||
|
vnode.state.filterList = vnode.state.filterList.filter(
|
||||||
|
f => f && f.trim()
|
||||||
|
);
|
||||||
|
let filter = vnode.state.filterList.map((f, idx) => {
|
||||||
|
try {
|
||||||
|
return filterParser.parse(f);
|
||||||
|
} catch (err) {
|
||||||
|
vnode.state.filterInvalid |= 1 << idx;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
vnode.state.filterList.push("");
|
||||||
|
if (!vnode.state.filterInvalid)
|
||||||
|
vnode.attrs.onChange(["AND"].concat(filter));
|
||||||
|
}
|
||||||
|
|
||||||
return m(
|
return m(
|
||||||
"div.filter",
|
"div.filter",
|
||||||
[m("b", "Filter"), a].concat(
|
[m("b", "Filter"), a].concat(
|
||||||
filterList.map((fltr, idx) => {
|
vnode.state.filterList.map((fltr, idx) => {
|
||||||
return m("input", {
|
return m("input", {
|
||||||
type: "string",
|
type: "string",
|
||||||
list: "filters",
|
list: "filters",
|
||||||
|
class: `${(vnode.state.filterInvalid >> idx) & 1 ? "error" : ""}`,
|
||||||
value: fltr,
|
value: fltr,
|
||||||
onchange: function(e) {
|
onchange: e => {
|
||||||
e.redraw = false;
|
vnode.state.filterList[idx] = e.target.value;
|
||||||
filterList[idx] = this.value;
|
onChange();
|
||||||
m.route.set("/devices", {
|
|
||||||
filter: filterList.filter(f => !!f)
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in new issue
Block a user