Rebuilt the network view in Svelte
This commit is contained in:
368
src/js/app.js
368
src/js/app.js
@@ -1,36 +1,11 @@
|
||||
/******************************************************************************\
|
||||
"use strict";
|
||||
|
||||
This file is part of the Buildbotics firmware.
|
||||
const api = require("./api");
|
||||
const cookie = require("./cookie")("bbctrl-");
|
||||
const Sock = require("./sock");
|
||||
const omit = require("lodash.omit");
|
||||
|
||||
Copyright (c) 2015 - 2018, Buildbotics LLC
|
||||
All rights reserved.
|
||||
|
||||
This file ("the software") is free software: you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License,
|
||||
version 2 as published by the Free Software Foundation. You should
|
||||
have received a copy of the GNU General Public License, version 2
|
||||
along with the software. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
The software is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the software. If not, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
For information regarding this software email:
|
||||
"Joseph Coffland" <joseph@buildbotics.com>
|
||||
|
||||
\******************************************************************************/
|
||||
|
||||
'use strict'
|
||||
|
||||
const api = require('./api');
|
||||
const cookie = require('./cookie')('bbctrl-');
|
||||
const Sock = require('./sock');
|
||||
const omit = require('lodash.omit');
|
||||
SvelteComponents.initNetworkInfo();
|
||||
|
||||
function is_newer_version(current, latest) {
|
||||
const pattern = /(\d+)\.(\d+)\.(\d+)(.*)/;
|
||||
@@ -47,7 +22,8 @@ function is_newer_version(current, latest) {
|
||||
const patch = latestParts[3] - currentParts[3];
|
||||
|
||||
// If current is a pre-release, and latest is a release
|
||||
const betaToRelease = latestParts[4].length === 0 && currentParts[4].length > 0;
|
||||
const betaToRelease =
|
||||
latestParts[4].length === 0 && currentParts[4].length > 0;
|
||||
|
||||
switch (true) {
|
||||
case major > 0:
|
||||
@@ -61,15 +37,17 @@ function is_newer_version(current, latest) {
|
||||
}
|
||||
}
|
||||
|
||||
function is_object(o) { return o !== null && typeof o == 'object' }
|
||||
function is_array(o) { return Array.isArray(o) }
|
||||
|
||||
function update_array(dst, src) {
|
||||
while (dst.length) dst.pop()
|
||||
for (var i = 0; i < src.length; i++)
|
||||
Vue.set(dst, i, src[i]);
|
||||
function is_object(o) {
|
||||
return o !== null && typeof o == "object";
|
||||
}
|
||||
function is_array(o) {
|
||||
return Array.isArray(o);
|
||||
}
|
||||
|
||||
function update_array(dst, src) {
|
||||
while (dst.length) dst.pop();
|
||||
for (var i = 0; i < src.length; i++) Vue.set(dst, i, src[i]);
|
||||
}
|
||||
|
||||
function update_object(dst, src, remove) {
|
||||
var props, index, key, value;
|
||||
@@ -79,8 +57,7 @@ function update_object(dst, src, remove) {
|
||||
|
||||
for (index in props) {
|
||||
key = props[index];
|
||||
if (!src.hasOwnProperty(key))
|
||||
Vue.delete(dst, key);
|
||||
if (!src.hasOwnProperty(key)) Vue.delete(dst, key);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,111 +68,100 @@ function update_object(dst, src, remove) {
|
||||
|
||||
if (is_array(value) && dst.hasOwnProperty(key) && is_array(dst[key]))
|
||||
update_array(dst[key], value);
|
||||
|
||||
else if (is_object(value) && dst.hasOwnProperty(key) && is_object(dst[key]))
|
||||
update_object(dst[key], value, remove);
|
||||
|
||||
else Vue.set(dst, key, value);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new Vue({
|
||||
el: 'body',
|
||||
|
||||
el: "body",
|
||||
|
||||
data: function () {
|
||||
return {
|
||||
status: 'connecting',
|
||||
currentView: 'loading',
|
||||
status: "connecting",
|
||||
currentView: "loading",
|
||||
index: -1,
|
||||
modified: false,
|
||||
template: require('../resources/config-template.json'),
|
||||
template: require("../resources/config-template.json"),
|
||||
config: {
|
||||
settings: { units: 'METRIC' },
|
||||
settings: { units: "METRIC" },
|
||||
motors: [{}, {}, {}, {}],
|
||||
version: '<loading>',
|
||||
full_version: '<loading>'
|
||||
version: "<loading>",
|
||||
full_version: "<loading>",
|
||||
},
|
||||
state: {
|
||||
messages: [],
|
||||
probing_active: false,
|
||||
wait_for_probing_complete: false,
|
||||
show_probe_complete_modal: false,
|
||||
show_probe_failed_modal: false
|
||||
show_probe_failed_modal: false,
|
||||
},
|
||||
video_size: cookie.get('video-size', 'small'),
|
||||
crosshair: cookie.get('crosshair', 'false') != 'false',
|
||||
video_size: cookie.get("video-size", "small"),
|
||||
crosshair: cookie.get("crosshair", "false") != "false",
|
||||
errorTimeout: 30,
|
||||
errorTimeoutStart: 0,
|
||||
errorShow: false,
|
||||
errorMessage: '',
|
||||
errorMessage: "",
|
||||
confirmUpgrade: false,
|
||||
confirmUpload: false,
|
||||
firmwareUpgrading: false,
|
||||
checkedUpgrade: false,
|
||||
firmwareName: '',
|
||||
latestVersion: '',
|
||||
ipAddress: '0.0.0.0',
|
||||
wifiSSID: '',
|
||||
firmwareName: "",
|
||||
latestVersion: "",
|
||||
confirmShutdown: false,
|
||||
diskSpace: ''
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
components: {
|
||||
'estop': { template: '#estop-template' },
|
||||
'loading-view': { template: '<h1>Loading...</h1>' },
|
||||
'control-view': require('./control-view'),
|
||||
'settings-view': require('./settings-view'),
|
||||
'motor-view': require('./motor-view'),
|
||||
'tool-view': require('./tool-view'),
|
||||
'io-view': require('./io-view'),
|
||||
'admin-general-view': require('./admin-general-view'),
|
||||
'admin-network-view': require('./admin-network-view'),
|
||||
'help-view': { template: '#help-view-template' },
|
||||
'cheat-sheet-view': {
|
||||
template: '#cheat-sheet-view-template',
|
||||
data: function () { return { showUnimplemented: false } }
|
||||
}
|
||||
estop: { template: "#estop-template" },
|
||||
"loading-view": { template: "<h1>Loading...</h1>" },
|
||||
"control-view": require("./control-view"),
|
||||
"settings-view": require("./settings-view"),
|
||||
"motor-view": require("./motor-view"),
|
||||
"tool-view": require("./tool-view"),
|
||||
"io-view": require("./io-view"),
|
||||
"admin-general-view": require("./admin-general-view"),
|
||||
"admin-network-view": require("./admin-network-view"),
|
||||
"help-view": { template: "#help-view-template" },
|
||||
"cheat-sheet-view": {
|
||||
template: "#cheat-sheet-view-template",
|
||||
data: function () {
|
||||
return { showUnimplemented: false };
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
events: {
|
||||
'config-changed': function () {
|
||||
"config-changed": function () {
|
||||
this.modified = true;
|
||||
},
|
||||
|
||||
'hostname-changed': function (hostname) {
|
||||
this.hostname = hostname
|
||||
},
|
||||
|
||||
send: function (msg) {
|
||||
if (this.status == 'connected') {
|
||||
console.debug('>', msg);
|
||||
if (this.status == "connected") {
|
||||
console.debug(">", msg);
|
||||
this.sock.send(msg);
|
||||
}
|
||||
},
|
||||
|
||||
connected: function () {
|
||||
this.update()
|
||||
this.update();
|
||||
},
|
||||
|
||||
update: function () {
|
||||
this.update()
|
||||
this.update();
|
||||
},
|
||||
|
||||
check: function () {
|
||||
this.latestVersion = '';
|
||||
check: async function () {
|
||||
try {
|
||||
const response = await fetch("https://raw.githubusercontent.com/OneFinityCNC/onefinity-release/master/latest.txt", {
|
||||
cache: "no-cache"
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
url: 'https://raw.githubusercontent.com/OneFinityCNC/onefinity-release/master/latest.txt',
|
||||
data: { hid: this.state.hid },
|
||||
cache: false
|
||||
|
||||
}).done(function (data) {
|
||||
this.latestVersion = data;
|
||||
this.$broadcast('latest_version', data);
|
||||
}.bind(this))
|
||||
this.latestVersion = (await response.text()).trim();
|
||||
} catch (err) {
|
||||
this.latestVersion = "";
|
||||
}
|
||||
},
|
||||
|
||||
upgrade: function () {
|
||||
@@ -221,7 +187,7 @@ module.exports = new Vue({
|
||||
// Popup error dialog
|
||||
this.errorShow = true;
|
||||
this.errorMessage = msg.msg;
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
@@ -236,17 +202,17 @@ module.exports = new Vue({
|
||||
}
|
||||
|
||||
return msgs;
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
ready: function () {
|
||||
$(window).on('hashchange', this.parse_hash);
|
||||
$(window).on("hashchange", this.parse_hash);
|
||||
this.connect();
|
||||
},
|
||||
|
||||
methods: {
|
||||
metric: function () {
|
||||
return this.config.settings.units != 'IMPERIAL'
|
||||
return this.config.settings.units != "IMPERIAL";
|
||||
},
|
||||
|
||||
block_error_dialog: function () {
|
||||
@@ -255,30 +221,30 @@ module.exports = new Vue({
|
||||
},
|
||||
|
||||
toggle_video: function (e) {
|
||||
if (this.video_size == 'small') this.video_size = 'large';
|
||||
else if (this.video_size == 'large') this.video_size = 'small';
|
||||
cookie.set('video-size', this.video_size);
|
||||
if (this.video_size == "small") this.video_size = "large";
|
||||
else if (this.video_size == "large") this.video_size = "small";
|
||||
cookie.set("video-size", this.video_size);
|
||||
},
|
||||
|
||||
toggle_crosshair: function (e) {
|
||||
e.preventDefault();
|
||||
this.crosshair = !this.crosshair;
|
||||
cookie.set('crosshair', this.crosshair);
|
||||
cookie.set("crosshair", this.crosshair);
|
||||
},
|
||||
|
||||
estop: function () {
|
||||
if (this.state.xx == 'ESTOPPED') api.put('clear');
|
||||
else api.put('estop');
|
||||
if (this.state.xx == "ESTOPPED") api.put("clear");
|
||||
else api.put("estop");
|
||||
},
|
||||
|
||||
upgrade_confirmed: async function () {
|
||||
this.confirmUpgrade = false;
|
||||
|
||||
try {
|
||||
await api.put('upgrade');
|
||||
await api.put("upgrade");
|
||||
this.firmwareUpgrading = true;
|
||||
} catch (err) {
|
||||
api.alert('Error during upgrade.');
|
||||
api.alert("Error during upgrade.");
|
||||
console.error("Error during upgrade", err);
|
||||
}
|
||||
},
|
||||
@@ -287,22 +253,27 @@ module.exports = new Vue({
|
||||
this.confirmUpload = false;
|
||||
|
||||
const form = new FormData();
|
||||
form.append('firmware', this.firmware);
|
||||
form.append("firmware", this.firmware);
|
||||
|
||||
$.ajax({
|
||||
url: '/api/firmware/update',
|
||||
type: 'PUT',
|
||||
url: "/api/firmware/update",
|
||||
type: "PUT",
|
||||
data: form,
|
||||
cache: false,
|
||||
contentType: false,
|
||||
processData: false
|
||||
|
||||
}).success(function () {
|
||||
this.firmwareUpgrading = true;
|
||||
}.bind(this)).error(function (err) {
|
||||
api.alert('Firmware update failed');
|
||||
console.error('Firmware update failed', err);
|
||||
}.bind(this))
|
||||
processData: false,
|
||||
})
|
||||
.success(
|
||||
function () {
|
||||
this.firmwareUpgrading = true;
|
||||
}.bind(this)
|
||||
)
|
||||
.error(
|
||||
function (err) {
|
||||
api.alert("Firmware update failed");
|
||||
console.error("Firmware update failed", err);
|
||||
}.bind(this)
|
||||
);
|
||||
},
|
||||
|
||||
show_upgrade: function () {
|
||||
@@ -310,97 +281,58 @@ module.exports = new Vue({
|
||||
return is_newer_version(this.config.version, this.latestVersion);
|
||||
},
|
||||
|
||||
update: function () {
|
||||
api.get('config/load').done(function (config) {
|
||||
update_object(this.config, config, true);
|
||||
this.parse_hash();
|
||||
update: async function () {
|
||||
const config = await api.get("config/load");
|
||||
|
||||
if (!this.checkedUpgrade) {
|
||||
this.checkedUpgrade = true;
|
||||
update_object(this.config, config, true);
|
||||
this.parse_hash();
|
||||
|
||||
var check = this.config.admin['auto-check-upgrade'];
|
||||
if (typeof check == 'undefined' || check)
|
||||
this.$emit('check');
|
||||
}
|
||||
if (!this.checkedUpgrade) {
|
||||
this.checkedUpgrade = true;
|
||||
|
||||
this.check_ip_address();
|
||||
this.check_ssid();
|
||||
}.bind(this))
|
||||
},
|
||||
var check = this.config.admin["auto-check-upgrade"];
|
||||
if (typeof check == "undefined" || check) this.$emit("check");
|
||||
}
|
||||
|
||||
check_ip_address: function () {
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
url: 'hostinfo.txt',
|
||||
data: { hid: this.state.hid },
|
||||
cache: false
|
||||
|
||||
}).done(function (data) {
|
||||
console.debug('>', data);
|
||||
this.ipAddress = 'IP:' + data;
|
||||
this.$broadcast('ipAddress', data);
|
||||
}.bind(this))
|
||||
},
|
||||
|
||||
check_ssid: function () {
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
url: 'ssidinfo.txt',
|
||||
data: { hid: this.state.hid },
|
||||
cache: false
|
||||
|
||||
}).done(function (data) {
|
||||
console.debug('>', data);
|
||||
this.wifiSSID = 'SSID:' + data;
|
||||
this.$broadcast('wifiSSID', data);
|
||||
}.bind(this))
|
||||
},
|
||||
|
||||
get_ip_address: function () {
|
||||
console.debug('get_ip>', this.ipAddress);
|
||||
return this.ipAddress;
|
||||
},
|
||||
|
||||
get_ssid: function () {
|
||||
console.debug('get_ssid>', this.wifiSSID);
|
||||
return this.wifiSSID;
|
||||
},
|
||||
|
||||
shutdown: function () {
|
||||
this.confirmShutdown = false;
|
||||
api.put('shutdown');
|
||||
|
||||
api.put("shutdown");
|
||||
},
|
||||
|
||||
reboot: function () {
|
||||
this.confirmShutdown = false;
|
||||
api.put('reboot');
|
||||
api.put("reboot");
|
||||
},
|
||||
|
||||
connect: function () {
|
||||
this.sock = new Sock(`//${location.host}/sockjs`);
|
||||
|
||||
this.sock.onmessage = (e) => {
|
||||
if (typeof e.data != 'object') {
|
||||
if (typeof e.data != "object") {
|
||||
return;
|
||||
}
|
||||
|
||||
if ('log' in e.data) {
|
||||
if ("log" in e.data) {
|
||||
if (e.data.log.msg === "Switch not found") {
|
||||
this.$broadcast('probing_failed');
|
||||
this.$broadcast("probing_failed");
|
||||
} else {
|
||||
this.$broadcast('log', e.data.log);
|
||||
this.$broadcast("log", e.data.log);
|
||||
}
|
||||
|
||||
delete e.data.log;
|
||||
}
|
||||
|
||||
// Check for session ID change on controller
|
||||
if ('sid' in e.data) {
|
||||
if (typeof this.sid == 'undefined') {
|
||||
if ("sid" in e.data) {
|
||||
if (typeof this.sid == "undefined") {
|
||||
this.sid = e.data.sid;
|
||||
} else if (this.sid != e.data.sid) {
|
||||
if (typeof this.hostname !== 'undefined' && location.hostname !== 'localhost') {
|
||||
if (
|
||||
typeof this.hostname !== "undefined" &&
|
||||
location.hostname !== "localhost"
|
||||
) {
|
||||
location.hostname = this.hostname;
|
||||
}
|
||||
|
||||
@@ -412,15 +344,15 @@ module.exports = new Vue({
|
||||
const debugStateChanges = false;
|
||||
if (debugStateChanges) {
|
||||
const data = omit(e.data, [
|
||||
'vdd',
|
||||
'vin',
|
||||
'vout',
|
||||
'motor',
|
||||
'temp',
|
||||
'heartbeat',
|
||||
'load1',
|
||||
'load2',
|
||||
'rpi_temp'
|
||||
"vdd",
|
||||
"vin",
|
||||
"vout",
|
||||
"motor",
|
||||
"temp",
|
||||
"heartbeat",
|
||||
"load1",
|
||||
"load2",
|
||||
"rpi_temp",
|
||||
]);
|
||||
if (Object.keys(data).length > 0) {
|
||||
console.log(JSON.stringify(data, null, 4));
|
||||
@@ -433,24 +365,24 @@ module.exports = new Vue({
|
||||
Vue.set(this.state, "saw_probe_connected", true);
|
||||
}
|
||||
|
||||
if (this.state.cycle === 'idle') {
|
||||
if (this.state.cycle === "idle") {
|
||||
if (this.state.wait_for_probing_complete) {
|
||||
Vue.set(this.state, "wait_for_probing_complete", false);
|
||||
this.$broadcast("probing_complete");
|
||||
}
|
||||
}
|
||||
|
||||
this.$broadcast('update');
|
||||
this.$broadcast("update");
|
||||
};
|
||||
|
||||
this.sock.onopen = () => {
|
||||
this.status = 'connected';
|
||||
this.status = "connected";
|
||||
this.$emit(this.status);
|
||||
this.$broadcast(this.status);
|
||||
};
|
||||
|
||||
this.sock.onclose = () => {
|
||||
this.status = 'disconnected';
|
||||
this.status = "disconnected";
|
||||
this.$emit(this.status);
|
||||
this.$broadcast(this.status);
|
||||
};
|
||||
@@ -460,11 +392,11 @@ module.exports = new Vue({
|
||||
var hash = location.hash.substr(1);
|
||||
|
||||
if (!hash.trim().length) {
|
||||
location.hash = 'control';
|
||||
location.hash = "control";
|
||||
return;
|
||||
}
|
||||
|
||||
var parts = hash.split(':');
|
||||
var parts = hash.split(":");
|
||||
|
||||
if (parts.length == 2) this.index = parts[1];
|
||||
|
||||
@@ -472,35 +404,43 @@ module.exports = new Vue({
|
||||
},
|
||||
|
||||
save: function () {
|
||||
const selected_tool = this.config.tool['selected-tool'];
|
||||
const saveModbus = selected_tool !== "pwm" &&
|
||||
const selected_tool = this.config.tool["selected-tool"];
|
||||
const saveModbus =
|
||||
selected_tool !== "pwm" &&
|
||||
selected_tool !== "laser" &&
|
||||
selected_tool !== "router";
|
||||
const settings = {
|
||||
['tool']: { ...this.config.tool },
|
||||
['pwm-spindle']: { ...this.config['pwm-spindle'] },
|
||||
['modbus-spindle']: saveModbus ? { ...this.config['modbus-spindle'] } : undefined
|
||||
}
|
||||
delete settings.tool['tool-type'];
|
||||
["tool"]: { ...this.config.tool },
|
||||
["pwm-spindle"]: { ...this.config["pwm-spindle"] },
|
||||
["modbus-spindle"]: saveModbus
|
||||
? { ...this.config["modbus-spindle"] }
|
||||
: undefined,
|
||||
};
|
||||
delete settings.tool["tool-type"];
|
||||
|
||||
this.config['selected-tool-settings'][selected_tool] = settings;
|
||||
this.config["selected-tool-settings"][selected_tool] = settings;
|
||||
|
||||
api.put('config/save', this.config).done(function (data) {
|
||||
this.modified = false;
|
||||
}.bind(this)).fail(function (error) {
|
||||
api.alert('Save failed', error);
|
||||
});
|
||||
api
|
||||
.put("config/save", this.config)
|
||||
.done(
|
||||
function (data) {
|
||||
this.modified = false;
|
||||
}.bind(this)
|
||||
)
|
||||
.fail(function (error) {
|
||||
api.alert("Save failed", error);
|
||||
});
|
||||
},
|
||||
|
||||
close_messages: function (action) {
|
||||
if (action == 'stop') api.put('stop');
|
||||
if (action == 'continue') api.put('unpause');
|
||||
if (action == "stop") api.put("stop");
|
||||
if (action == "continue") api.put("unpause");
|
||||
|
||||
// Acknowledge messages
|
||||
if (this.state.messages.length) {
|
||||
var id = this.state.messages.slice(-1)[0].id
|
||||
api.put('message/' + id + '/ack');
|
||||
var id = this.state.messages.slice(-1)[0].id;
|
||||
api.put("message/" + id + "/ack");
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user