Bulk push file from device list page
This commit is contained in:
1 parent
82124d471e
commit
f14e6ceb97
5 files changed
+110
-66
No files matched your search
@@ -70,7 +70,7 @@ const component: ClosureComponent = (): Component => {
|
|||||||
onclick: () => {
|
onclick: () => {
|
||||||
taskQueue.stageDownload({
|
taskQueue.stageDownload({
|
||||||
name: "download",
|
name: "download",
|
||||||
device: device["DeviceID.ID"].value[0],
|
devices: [device["DeviceID.ID"].value[0]],
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ const component: ClosureComponent = (): Component => {
|
|||||||
onclick: () => {
|
onclick: () => {
|
||||||
taskQueue.stageSpv({
|
taskQueue.stageSpv({
|
||||||
name: "setParameterValues",
|
name: "setParameterValues",
|
||||||
device: device["DeviceID.ID"].value[0],
|
devices: [device["DeviceID.ID"].value[0]],
|
||||||
parameterValues: [
|
parameterValues: [
|
||||||
[
|
[
|
||||||
parameter,
|
parameter,
|
||||||
|
|||||||
@@ -122,6 +122,23 @@ function renderActions(selected: Set<string>): Children {
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
buttons.push(
|
||||||
|
m(
|
||||||
|
"button.critical",
|
||||||
|
{
|
||||||
|
title: "Push a firmware or a config file",
|
||||||
|
disabled: !selected.size,
|
||||||
|
onclick: () => {
|
||||||
|
taskQueue.stageDownload({
|
||||||
|
name: "download",
|
||||||
|
devices: [...selected],
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"Push file"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
buttons.push(
|
buttons.push(
|
||||||
m(
|
m(
|
||||||
"button.primary",
|
"button.primary",
|
||||||
|
|||||||
+82
-57
@@ -24,10 +24,21 @@ import m, {
|
|||||||
Component,
|
Component,
|
||||||
VnodeDOM,
|
VnodeDOM,
|
||||||
} from "mithril";
|
} from "mithril";
|
||||||
import * as taskQueue from "./task-queue";
|
|
||||||
import * as store from "./store";
|
import * as store from "./store";
|
||||||
import * as notifications from "./notifications";
|
import * as notifications from "./notifications";
|
||||||
import { getIcon } from "./icons";
|
import { getIcon } from "./icons";
|
||||||
|
import {
|
||||||
|
clear,
|
||||||
|
commit,
|
||||||
|
deleteTask,
|
||||||
|
getQueue,
|
||||||
|
getStaging,
|
||||||
|
QueueTask,
|
||||||
|
queueTask,
|
||||||
|
StageTask,
|
||||||
|
} from "./task-queue";
|
||||||
|
|
||||||
|
const invalid: WeakSet<StageTask> = new WeakSet();
|
||||||
|
|
||||||
function mparam(param): Children {
|
function mparam(param): Children {
|
||||||
return m("span.parameter", { title: param }, `${param}`);
|
return m("span.parameter", { title: param }, `${param}`);
|
||||||
@@ -37,7 +48,7 @@ function mval(val): Children {
|
|||||||
return m("span.value", { title: val }, `${val}`);
|
return m("span.value", { title: val }, `${val}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderStagingSpv(task, queueFunc, cancelFunc): Children {
|
function renderStagingSpv(task: StageTask, queueFunc, cancelFunc): Children {
|
||||||
function keydown(e): void {
|
function keydown(e): void {
|
||||||
if (e.keyCode === 13) queueFunc();
|
if (e.keyCode === 13) queueFunc();
|
||||||
else if (e.keyCode === 27) cancelFunc();
|
else if (e.keyCode === 27) cancelFunc();
|
||||||
@@ -90,13 +101,24 @@ function renderStagingSpv(task, queueFunc, cancelFunc): Children {
|
|||||||
return [m("span", "Editing ", mparam(task.parameterValues[0][0])), input];
|
return [m("span", "Editing ", mparam(task.parameterValues[0][0])), input];
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderStagingDownload(task): Children {
|
function renderStagingDownload(task: StageTask): Children {
|
||||||
task.invalid = !task.fileName || !task.fileType;
|
if (!task.fileName || !task.fileType) invalid.add(task);
|
||||||
|
else invalid.delete(task);
|
||||||
const files = store.fetch("files", true);
|
const files = store.fetch("files", true);
|
||||||
const idParts = task.device.split("-");
|
let oui = "";
|
||||||
const oui = decodeURIComponent(idParts[0]);
|
let productClass = "";
|
||||||
const productClass =
|
for (const d of task.devices) {
|
||||||
idParts.length === 3 ? decodeURIComponent(idParts[1]) : "";
|
const parts = d.split("-");
|
||||||
|
if (oui === "") oui = parts[0];
|
||||||
|
else if (oui !== parts[0]) oui = null;
|
||||||
|
if (parts.length === 3) {
|
||||||
|
if (productClass === "") productClass = parts[1];
|
||||||
|
else if (productClass !== parts[1]) productClass = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oui) oui = decodeURIComponent(oui);
|
||||||
|
if (productClass) productClass = decodeURIComponent(productClass);
|
||||||
|
|
||||||
const typesList = [
|
const typesList = [
|
||||||
"",
|
"",
|
||||||
@@ -162,13 +184,17 @@ function renderStagingDownload(task): Children {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderStaging(staging): Child[] {
|
function renderStaging(staging: Set<StageTask>): Child[] {
|
||||||
const elements: Child[] = [];
|
const elements: Child[] = [];
|
||||||
|
|
||||||
for (const s of staging) {
|
for (const s of staging) {
|
||||||
const queueFunc = (): void => {
|
const queueFunc = (): void => {
|
||||||
staging.delete(s);
|
staging.delete(s);
|
||||||
taskQueue.queueTask(s);
|
for (const d of s.devices) {
|
||||||
|
const t = Object.assign({ device: d }, s);
|
||||||
|
delete t.devices;
|
||||||
|
queueTask(t);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
const cancelFunc = (): void => {
|
const cancelFunc = (): void => {
|
||||||
staging.delete(s);
|
staging.delete(s);
|
||||||
@@ -181,7 +207,7 @@ function renderStaging(staging): Child[] {
|
|||||||
|
|
||||||
const queue = m(
|
const queue = m(
|
||||||
"button.primary",
|
"button.primary",
|
||||||
{ title: "Queue task", onclick: queueFunc, disabled: s.invalid },
|
{ title: "Queue task", onclick: queueFunc, disabled: invalid.has(s) },
|
||||||
"Queue"
|
"Queue"
|
||||||
);
|
);
|
||||||
const cancel = m(
|
const cancel = m(
|
||||||
@@ -195,7 +221,7 @@ function renderStaging(staging): Child[] {
|
|||||||
return elements;
|
return elements;
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderQueue(queue): Child[] {
|
function renderQueue(queue: Set<QueueTask>): Child[] {
|
||||||
const details: Child[] = [];
|
const details: Child[] = [];
|
||||||
const devices: { [deviceId: string]: any[] } = {};
|
const devices: { [deviceId: string]: any[] } = {};
|
||||||
for (const t of queue) {
|
for (const t of queue) {
|
||||||
@@ -215,7 +241,7 @@ function renderQueue(queue): Child[] {
|
|||||||
{
|
{
|
||||||
title: "Retry this task",
|
title: "Retry this task",
|
||||||
onclick: () => {
|
onclick: () => {
|
||||||
taskQueue.queueTask(t);
|
queueTask(t);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
getIcon("retry")
|
getIcon("retry")
|
||||||
@@ -229,7 +255,7 @@ function renderQueue(queue): Child[] {
|
|||||||
{
|
{
|
||||||
title: "Remove this task",
|
title: "Remove this task",
|
||||||
onclick: () => {
|
onclick: () => {
|
||||||
taskQueue.deleteTask(t);
|
deleteTask(t);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
getIcon("remove")
|
getIcon("remove")
|
||||||
@@ -347,8 +373,8 @@ function renderNotifications(notifs): Child[] {
|
|||||||
const component: ClosureComponent = (): Component => {
|
const component: ClosureComponent = (): Component => {
|
||||||
return {
|
return {
|
||||||
view: (vnode) => {
|
view: (vnode) => {
|
||||||
const queue = taskQueue.getQueue();
|
const queue = getQueue();
|
||||||
const staging = taskQueue.getStaging();
|
const staging = getStaging();
|
||||||
const notifs = notifications.getNotifications();
|
const notifs = notifications.getNotifications();
|
||||||
|
|
||||||
let drawerElement, statusElement;
|
let drawerElement, statusElement;
|
||||||
@@ -394,51 +420,50 @@ const component: ClosureComponent = (): Component => {
|
|||||||
title: "Commit queued tasks",
|
title: "Commit queued tasks",
|
||||||
disabled: !statusCount.queued,
|
disabled: !statusCount.queued,
|
||||||
onclick: () => {
|
onclick: () => {
|
||||||
const tasks = Array.from(taskQueue.getQueue()).filter(
|
const tasks = Array.from(getQueue()).filter(
|
||||||
(t) => t["status"] === "queued"
|
(t) => t["status"] === "queued"
|
||||||
);
|
);
|
||||||
taskQueue
|
commit(
|
||||||
.commit(
|
tasks,
|
||||||
tasks,
|
(deviceId, err, connectionRequestStatus, tasks2) => {
|
||||||
(deviceId, err, connectionRequestStatus, tasks2) => {
|
if (err) {
|
||||||
if (err) {
|
|
||||||
notifications.push(
|
|
||||||
"error",
|
|
||||||
`${deviceId}: ${err.message}`
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (connectionRequestStatus !== "OK") {
|
|
||||||
notifications.push(
|
|
||||||
"error",
|
|
||||||
`${deviceId}: ${connectionRequestStatus}`
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const t of tasks2) {
|
|
||||||
if (t.status === "stale") {
|
|
||||||
notifications.push(
|
|
||||||
"error",
|
|
||||||
`${deviceId}: No contact from device`
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
} else if (t.status === "fault") {
|
|
||||||
notifications.push(
|
|
||||||
"error",
|
|
||||||
`${deviceId}: Task(s) faulted`
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
notifications.push(
|
notifications.push(
|
||||||
"success",
|
"error",
|
||||||
`${deviceId}: Task(s) committed`
|
`${deviceId}: ${err.message}`
|
||||||
);
|
);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
if (connectionRequestStatus !== "OK") {
|
||||||
|
notifications.push(
|
||||||
|
"error",
|
||||||
|
`${deviceId}: ${connectionRequestStatus}`
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const t of tasks2) {
|
||||||
|
if (t.status === "stale") {
|
||||||
|
notifications.push(
|
||||||
|
"error",
|
||||||
|
`${deviceId}: No contact from device`
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
} else if (t.status === "fault") {
|
||||||
|
notifications.push(
|
||||||
|
"error",
|
||||||
|
`${deviceId}: Task(s) faulted`
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
notifications.push(
|
||||||
|
"success",
|
||||||
|
`${deviceId}: Task(s) committed`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
store.fulfill(0, Date.now());
|
store.fulfill(0, Date.now());
|
||||||
})
|
})
|
||||||
@@ -453,7 +478,7 @@ const component: ClosureComponent = (): Component => {
|
|||||||
"button",
|
"button",
|
||||||
{
|
{
|
||||||
title: "Clear tasks",
|
title: "Clear tasks",
|
||||||
onclick: taskQueue.clear,
|
onclick: clear,
|
||||||
disabled: !queueElements.length,
|
disabled: !queueElements.length,
|
||||||
},
|
},
|
||||||
"Clear"
|
"Clear"
|
||||||
|
|||||||
+9
-7
@@ -22,20 +22,22 @@ import { Task } from "../lib/types";
|
|||||||
|
|
||||||
export interface QueueTask extends Task {
|
export interface QueueTask extends Task {
|
||||||
status?: string;
|
status?: string;
|
||||||
device?: string;
|
device: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StageTask extends Task {
|
||||||
|
devices: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const queue: Set<QueueTask> = new Set();
|
const queue: Set<QueueTask> = new Set();
|
||||||
const staging: Set<QueueTask> = new Set();
|
const staging: Set<StageTask> = new Set();
|
||||||
|
|
||||||
export function queueTask(task: QueueTask): void {
|
export function queueTask(task: QueueTask): void {
|
||||||
staging.delete(task);
|
|
||||||
task.status = "queued";
|
task.status = "queued";
|
||||||
queue.add(task);
|
queue.add(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function deleteTask(task: QueueTask): void {
|
export function deleteTask(task: QueueTask): void {
|
||||||
staging.delete(task);
|
|
||||||
queue.delete(task);
|
queue.delete(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,7 +49,7 @@ export function clear(): void {
|
|||||||
queue.clear();
|
queue.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getStaging(): Set<QueueTask> {
|
export function getStaging(): Set<StageTask> {
|
||||||
return staging;
|
return staging;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,11 +57,11 @@ export function clearStaging(): void {
|
|||||||
staging.clear();
|
staging.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
export function stageSpv(task: QueueTask): void {
|
export function stageSpv(task: StageTask): void {
|
||||||
staging.add(task);
|
staging.add(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function stageDownload(task: QueueTask): void {
|
export function stageDownload(task: StageTask): void {
|
||||||
staging.add(task);
|
staging.add(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user