finish converting AJAX to Websocket
This commit is contained in:
parent
58f1bd2979
commit
fc2aa37f93
99
events.py
99
events.py
|
@ -1,75 +1,94 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
"""Websocket events."""
|
"""Websocket events."""
|
||||||
|
import re
|
||||||
import types
|
import types
|
||||||
|
|
||||||
import models
|
import models
|
||||||
from models import network
|
from models import network
|
||||||
|
|
||||||
|
|
||||||
async def toggle_outlet(ws, data):
|
async def toggle_outlet(ws, data):
|
||||||
"""Toggles the state of a RelayDevice."""
|
"""Toggles the state of a RelayDevice."""
|
||||||
device_id = data.get('device_id')
|
device_id = data.get('device_id')
|
||||||
sub_device_id = data.get('sub_device_id')
|
sub_device_id = data.get('sub_device_id')
|
||||||
|
|
||||||
|
data = {}
|
||||||
|
data['device_id'] = device_id
|
||||||
|
data['sub_device_id'] = sub_device_id
|
||||||
|
|
||||||
device = network.find(device_id)
|
device = network.find(device_id)
|
||||||
if not device:
|
if not device:
|
||||||
await ws.send_json({'ok': False, 'message': "device_id not found"})
|
data['ok'] = False
|
||||||
|
data['error'] = "device_id not found"
|
||||||
|
await ws.send_json(data)
|
||||||
return
|
return
|
||||||
state = device.toggle(sub_device_id)
|
state = device.toggle(sub_device_id)
|
||||||
if state is None:
|
if state is None:
|
||||||
await ws.send_json({'ok': False, 'message': "sub_device_id not found"})
|
data['ok'] = False
|
||||||
|
data['error'] = "sub_device_id not found"
|
||||||
|
await ws.send_json(data)
|
||||||
return
|
return
|
||||||
models.save_network(network)
|
models.save_network(network)
|
||||||
|
|
||||||
data = {}
|
|
||||||
data['ok'] = True
|
data['ok'] = True
|
||||||
data['device_id'] = device_id
|
|
||||||
data['sub_device_id'] = sub_device_id
|
|
||||||
data['state'] = state
|
data['state'] = state
|
||||||
res = {'event': 'toggle_outlet', 'data': data}
|
res = {'event': 'toggle_outlet', 'data': data}
|
||||||
await ws.send_json(res)
|
await ws.send_json(res)
|
||||||
|
|
||||||
|
|
||||||
async def edit(ws, data):
|
async def edit_field(ws, data):
|
||||||
"""Edits the text of a particular field."""
|
"""Edits the text of a particular field."""
|
||||||
device_id = data.get('device_id')
|
device_id = data.get('device_id')
|
||||||
sub_device_id = data.get('sub_device_id')
|
sub_device_id = data.get('sub_device_id')
|
||||||
field = data.get('field')
|
field = data.get('field')
|
||||||
value = data.get('value')
|
value = data.get('value')
|
||||||
|
|
||||||
|
data = {}
|
||||||
|
data['device_id'] = device_id
|
||||||
|
if sub_device_id:
|
||||||
|
data['sub_device_id'] = sub_device_id
|
||||||
|
data['field'] = field
|
||||||
|
data['value'] = value
|
||||||
|
|
||||||
device = network.find(device_id)
|
device = network.find(device_id)
|
||||||
if not device:
|
if not device:
|
||||||
await ws.send_json({'ok': False, 'message': "device_id not found"})
|
data['ok'] = False
|
||||||
|
data['error'] = "device_id not found"
|
||||||
|
await ws.send_json(data)
|
||||||
return
|
return
|
||||||
|
|
||||||
if device.locked:
|
if device.locked:
|
||||||
await ws.send_json({'ok': False, 'message': "device is locked for editing"})
|
data['ok'] = False
|
||||||
|
data['error'] = "device is locked for editing"
|
||||||
|
await ws.send_json(data)
|
||||||
return
|
return
|
||||||
|
|
||||||
if sub_device_id:
|
if sub_device_id:
|
||||||
sub_device = device.find(sub_device_id)
|
sub_device = device.find(sub_device_id)
|
||||||
if not sub_device:
|
if not sub_device:
|
||||||
await ws.send_json({'ok': False, 'message': "sub_device_id not found"})
|
data['ok'] = False
|
||||||
|
data['error'] = "sub_device_id not found"
|
||||||
|
await ws.send_json(data)
|
||||||
return
|
return
|
||||||
|
|
||||||
if hasattr(sub_device, field):
|
if hasattr(sub_device, field):
|
||||||
setattr(sub_device, field, value)
|
setattr(sub_device, field, value)
|
||||||
else:
|
else:
|
||||||
await ws.send_json({'ok': False, 'message': "sub_device field not found"})
|
data['ok'] = False
|
||||||
|
data['error'] = "sub_device field not found"
|
||||||
|
await ws.send_json(data)
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
if hasattr(device, field):
|
if hasattr(device, field):
|
||||||
setattr(device, field, value)
|
setattr(device, field, value)
|
||||||
else:
|
else:
|
||||||
await ws.send_json({'ok': False, 'message': "device field not found"})
|
data['ok'] = False
|
||||||
|
data['error'] = "device field not found"
|
||||||
|
await ws.send_json(data)
|
||||||
return
|
return
|
||||||
|
|
||||||
res = {
|
|
||||||
'ok': True,
|
|
||||||
'field': field,
|
|
||||||
'value': value
|
|
||||||
}
|
|
||||||
models.save_network(network)
|
models.save_network(network)
|
||||||
|
|
||||||
|
data['ok'] = True
|
||||||
|
res = {'event': 'edit_field', 'data': data}
|
||||||
await ws.send_json(res)
|
await ws.send_json(res)
|
||||||
|
|
||||||
|
|
||||||
|
@ -80,10 +99,15 @@ async def new_device(ws, data):
|
||||||
"""
|
"""
|
||||||
device_type = data.get('device_type')
|
device_type = data.get('device_type')
|
||||||
|
|
||||||
|
data = {}
|
||||||
|
data['device_type'] = device_type
|
||||||
|
|
||||||
if device_type == 'RelayDevice':
|
if device_type == 'RelayDevice':
|
||||||
device = models.RelayDevice()
|
device = models.RelayDevice()
|
||||||
else:
|
else:
|
||||||
await ws.send_json({'ok': False, 'message': "unknown device type"})
|
data['ok'] = False
|
||||||
|
data['error'] = "unknown device type"
|
||||||
|
await ws.send_json(data)
|
||||||
return
|
return
|
||||||
|
|
||||||
devices = [dev for dev in network if dev.type == device_type]
|
devices = [dev for dev in network if dev.type == device_type]
|
||||||
|
@ -99,42 +123,57 @@ async def new_device(ws, data):
|
||||||
device.id = device_type + num
|
device.id = device_type + num
|
||||||
network.append(device)
|
network.append(device)
|
||||||
models.save_network(network)
|
models.save_network(network)
|
||||||
res = {'ok': True, 'device_id': device.id}
|
|
||||||
|
data['ok'] = True
|
||||||
|
data['device_id'] = device.id
|
||||||
|
res = {'event': 'new_device', 'data': data}
|
||||||
await ws.send_json(res)
|
await ws.send_json(res)
|
||||||
|
|
||||||
|
|
||||||
async def lock_device(ws, data):
|
async def lock_device(ws, data):
|
||||||
"""Locks or unlocks a device to prevent or allow editing it's fields."""
|
"""Locks or unlocks a device to prevent or allow editing it's fields."""
|
||||||
device_id = data.get('device_id')
|
device_id = data.get('device_id')
|
||||||
locked = data.get('locked') == 'true'
|
locked = bool(data.get('locked'))
|
||||||
|
|
||||||
|
data = {}
|
||||||
|
data['device_id'] = device_id
|
||||||
|
data['locked'] = locked
|
||||||
|
|
||||||
device = network.find(device_id)
|
device = network.find(device_id)
|
||||||
if not device:
|
if not device:
|
||||||
await ws.send_json({'ok': False, 'message': "device_id not found"})
|
data['ok'] = False
|
||||||
|
data['error'] = "device_id not found"
|
||||||
|
await ws.send_json(data)
|
||||||
return
|
return
|
||||||
|
|
||||||
if locked:
|
device.locked = locked
|
||||||
device.locked = True
|
|
||||||
else:
|
|
||||||
device.locked = False
|
|
||||||
models.save_network(network)
|
models.save_network(network)
|
||||||
|
|
||||||
await ws.send_json({'ok': True, 'device_id': device.id, 'locked': device.locked})
|
data['ok'] = True
|
||||||
|
res = {'event': 'lock_device', 'data': data}
|
||||||
|
await ws.send_json(res)
|
||||||
|
|
||||||
|
|
||||||
async def delete(ws, data):
|
async def delete_device(ws, data):
|
||||||
"""Deletes a device."""
|
"""Deletes a device."""
|
||||||
device_id = data.get('device_id')
|
device_id = data.get('device_id')
|
||||||
|
|
||||||
|
data = {}
|
||||||
|
data['device_id'] = device_id
|
||||||
|
|
||||||
device = network.find(device_id)
|
device = network.find(device_id)
|
||||||
if not device:
|
if not device:
|
||||||
await ws.send_json({'ok': False, 'message': "device_id not found"})
|
data['ok'] = False
|
||||||
|
data['error'] = "device_id not found"
|
||||||
|
await ws.send_json(data)
|
||||||
return
|
return
|
||||||
|
|
||||||
network.remove(device)
|
network.remove(device)
|
||||||
models.save_network(network)
|
models.save_network(network)
|
||||||
|
|
||||||
await ws.send_json({'ok': True})
|
data['ok'] = True
|
||||||
|
res = {'event': 'delete_device', 'data': data}
|
||||||
|
await ws.send_json(res)
|
||||||
|
|
||||||
|
|
||||||
events = {}
|
events = {}
|
||||||
|
|
246
static/juice.js
246
static/juice.js
|
@ -24,12 +24,13 @@ function load() {
|
||||||
|
|
||||||
/* Websocket setup */
|
/* Websocket setup */
|
||||||
function init_websocket() {
|
function init_websocket() {
|
||||||
let socket = new Websocket('wss://' + window.location.hostname + ws_uri);
|
let socket = new WebSocket('wss://' + window.location.hostname + ws_uri);
|
||||||
socket._send = socket.send;
|
socket._send = socket.send;
|
||||||
socket.send = function(event_title, data) {
|
socket.send = function(event_title, data) {
|
||||||
data = JSON.stringify({event: event_title, data: data});
|
data = JSON.stringify({event: event_title, data: data});
|
||||||
if (socket.readyState == 0) {
|
if (socket.readyState == 0) {
|
||||||
console.log("Socket is still opening!");
|
console.log("Socket is still opening!");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
socket._send(data);
|
socket._send(data);
|
||||||
}
|
}
|
||||||
|
@ -38,6 +39,10 @@ function init_websocket() {
|
||||||
socket.onerror = onerror;
|
socket.onerror = onerror;
|
||||||
socket.events = {};
|
socket.events = {};
|
||||||
socket.events['toggle_outlet'] = toggle_outlet_recv;
|
socket.events['toggle_outlet'] = toggle_outlet_recv;
|
||||||
|
socket.events['edit_field'] = edit_field_recv;
|
||||||
|
socket.events['new_device'] = new_device_recv;
|
||||||
|
socket.events['lock_device'] = lock_device_recv;
|
||||||
|
socket.events['delete_device'] = delete_device_recv;
|
||||||
return socket;
|
return socket;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +50,13 @@ function onmessage (e) {
|
||||||
let data = JSON.parse(e.data);
|
let data = JSON.parse(e.data);
|
||||||
let event = data.event;
|
let event = data.event;
|
||||||
data = data.data;
|
data = data.data;
|
||||||
if (socket.events[event] === undefined) { return; }
|
if (!data.ok) {
|
||||||
|
throw new Error("Socket error: event = " + event +", error = " + data.error);
|
||||||
|
}
|
||||||
|
if (socket.events[event] === undefined) {
|
||||||
|
console.log("Unknown socket event: " + event);
|
||||||
|
return;
|
||||||
|
}
|
||||||
socket.events[event](data);
|
socket.events[event](data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,12 +74,8 @@ function onerror(e) {
|
||||||
|
|
||||||
/* Websocket receive */
|
/* Websocket receive */
|
||||||
function toggle_outlet_recv(data) {
|
function toggle_outlet_recv(data) {
|
||||||
if (!data.ok) {
|
|
||||||
throw new Error('Socket Event Error: toggle_outlet, message = ' + data.message);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let device = document.querySelector('#' + data.device_id);
|
let device = document.querySelector('#' + data.device_id);
|
||||||
let sub_device = document.querySelector('.' + data.sub_device_id);
|
let sub_device = device.querySelector('.' + data.sub_device_id);
|
||||||
let svg = sub_device.querySelector('.outlet_image').getSVGDocument().firstChild;
|
let svg = sub_device.querySelector('.outlet_image').getSVGDocument().firstChild;
|
||||||
if (data.state === true) {
|
if (data.state === true) {
|
||||||
svg.classList.remove('off');
|
svg.classList.remove('off');
|
||||||
|
@ -79,58 +86,15 @@ function toggle_outlet_recv(data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Websocket send */
|
function edit_field_recv(data) {
|
||||||
function toggle_outlet(svg) {
|
let device = document.querySelector('#' + data.device_id);
|
||||||
let sub_dev = get_object_from_svg(svg).parentElement;
|
if (data.sub_device_id) {
|
||||||
let data = {
|
device = device.querySelector('.' + data.sub_device_id);
|
||||||
device_id: sub_dev.parentElement.parentElement.id,
|
|
||||||
sub_device_id: sub_dev.querySelector('.id').innerText,
|
|
||||||
};
|
|
||||||
socket.send('toggle_outlet', data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* AJAX */
|
|
||||||
function edit_field(field) {
|
|
||||||
let value = field.firstElementChild.innerText;
|
|
||||||
let input = document.createElement('input');
|
|
||||||
input.value = value;
|
|
||||||
field.firstElementChild.replaceWith(input);
|
|
||||||
|
|
||||||
let save = document.createElement('span');
|
|
||||||
save.innerHTML = '';
|
|
||||||
save.className = 'save font-awesome';
|
|
||||||
save.setAttribute('onclick', 'save_field(this.parentElement)');
|
|
||||||
field.children[1].replaceWith(save);
|
|
||||||
}
|
|
||||||
|
|
||||||
function save_field(field) {
|
|
||||||
let value = field.firstElementChild.value;
|
|
||||||
let device_id = field.parentElement.id;
|
|
||||||
let sub_dev_id;
|
|
||||||
if (field.parentElement.className.includes('sub_device')) {
|
|
||||||
sub_dev_id = field.parentElement.children[0].textContent;
|
|
||||||
device_id = field.parentElement.parentElement.parentElement.id;
|
|
||||||
} else {
|
|
||||||
sub_dev_id = '';
|
|
||||||
}
|
}
|
||||||
let params = {
|
let field = device.querySelector('.' + data.field);
|
||||||
device_id: device_id,
|
|
||||||
sub_dev_id: sub_dev_id,
|
|
||||||
field: field.classList[0],
|
|
||||||
value: value
|
|
||||||
};
|
|
||||||
let query = Object.keys(params)
|
|
||||||
.map(k => encodeURIComponent(k) + '=' + encodeURIComponent(params[k]))
|
|
||||||
.join('&');
|
|
||||||
|
|
||||||
fetch(window.location.href + 'edit?' + query)
|
|
||||||
.then(function(response) {
|
|
||||||
return response.json();
|
|
||||||
})
|
|
||||||
.then(function(json) {
|
|
||||||
if (!json.ok) { throw new Error('HTTP error, status = ' + json.status + ', message = ' + json.message); }
|
|
||||||
let span = document.createElement('span');
|
let span = document.createElement('span');
|
||||||
span.innerText = json['value'];
|
span.innerText = data['value'];
|
||||||
span.className = 'field_value';
|
span.className = 'field_value';
|
||||||
field.firstElementChild.replaceWith(span);
|
field.firstElementChild.replaceWith(span);
|
||||||
|
|
||||||
|
@ -139,49 +103,26 @@ function save_field(field) {
|
||||||
edit.className = 'edit font-awesome';
|
edit.className = 'edit font-awesome';
|
||||||
edit.setAttribute('onclick', 'edit_field(this.parentElement)');
|
edit.setAttribute('onclick', 'edit_field(this.parentElement)');
|
||||||
field.children[1].replaceWith(edit);
|
field.children[1].replaceWith(edit);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function new_device() {
|
function new_device_recv(data) {
|
||||||
let params = {
|
if (data.device_type == 'RelayDevice') {
|
||||||
device_type: 'RelayDevice',
|
var template = document.querySelector('#RelayDevice_template');
|
||||||
};
|
} else {
|
||||||
let query = Object.keys(params)
|
return;
|
||||||
.map(k => encodeURIComponent(k) + '=' + encodeURIComponent(params[k]))
|
}
|
||||||
.join('&');
|
|
||||||
|
|
||||||
fetch(window.location.href + 'new_device?' + query)
|
|
||||||
.then(function(response) {
|
|
||||||
return response.json();
|
|
||||||
})
|
|
||||||
.then(function(json) {
|
|
||||||
let template = document.querySelector('#RelayDevice_template');
|
|
||||||
let node = document.importNode(template.content, true);
|
let node = document.importNode(template.content, true);
|
||||||
node.querySelector('.id').querySelector('.field_value').textContent = json.device_id;
|
node.querySelector('.id').querySelector('.field_value').textContent = data.device_id;
|
||||||
document.querySelector('#devices').appendChild(node);
|
document.querySelector('#devices').appendChild(node);
|
||||||
let children = document.querySelector('#devices').children;
|
let children = document.querySelector('#devices').children;
|
||||||
children[children.length - 1].id = json.device_id;
|
children[children.length - 1].id = data.device_id;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function lock_device(device) {
|
function lock_device_recv(data) {
|
||||||
if (device.querySelector('.save')) { return; }
|
let device = document.querySelector('#' + data.device_id);
|
||||||
let params = {
|
|
||||||
device_id: device.id,
|
|
||||||
locked: true,
|
|
||||||
};
|
|
||||||
let query = Object.keys(params)
|
|
||||||
.map(k => encodeURIComponent(k) + '=' + encodeURIComponent(params[k]))
|
|
||||||
.join('&');
|
|
||||||
|
|
||||||
fetch(window.location.href + 'lock_device?' + query)
|
|
||||||
.then(function(response) {
|
|
||||||
return response.json();
|
|
||||||
})
|
|
||||||
.then(function(json) {
|
|
||||||
if (!json.locked) { return; }
|
|
||||||
|
|
||||||
let fields = device.querySelectorAll('.editable');
|
let fields = device.querySelectorAll('.editable');
|
||||||
|
|
||||||
|
if (data.locked) {
|
||||||
fields.forEach(function(field) {
|
fields.forEach(function(field) {
|
||||||
field.querySelector('.edit').remove();
|
field.querySelector('.edit').remove();
|
||||||
});
|
});
|
||||||
|
@ -192,26 +133,7 @@ function lock_device(device) {
|
||||||
unlock.className = 'unlock font-awesome';
|
unlock.className = 'unlock font-awesome';
|
||||||
unlock.setAttribute('onclick', 'unlock_device(this.parentElement.parentElement)');
|
unlock.setAttribute('onclick', 'unlock_device(this.parentElement.parentElement)');
|
||||||
device.querySelector('.id').appendChild(unlock);
|
device.querySelector('.id').appendChild(unlock);
|
||||||
});
|
} else {
|
||||||
}
|
|
||||||
|
|
||||||
function unlock_device(device) {
|
|
||||||
let params = {
|
|
||||||
device_id: device.id,
|
|
||||||
locked: false,
|
|
||||||
};
|
|
||||||
let query = Object.keys(params)
|
|
||||||
.map(k => encodeURIComponent(k) + '=' + encodeURIComponent(params[k]))
|
|
||||||
.join('&');
|
|
||||||
|
|
||||||
fetch(window.location.href + 'lock_device?' + query)
|
|
||||||
.then(function(response) {
|
|
||||||
return response.json();
|
|
||||||
})
|
|
||||||
.then(function(json) {
|
|
||||||
if (json.locked) { return; }
|
|
||||||
|
|
||||||
let fields = device.querySelectorAll('.editable');
|
|
||||||
fields.forEach(function(field) {
|
fields.forEach(function(field) {
|
||||||
let edit = document.createElement('span');
|
let edit = document.createElement('span');
|
||||||
edit.innerHTML = '';
|
edit.innerHTML = '';
|
||||||
|
@ -232,45 +154,87 @@ function unlock_device(device) {
|
||||||
lock.className = 'lock font-awesome';
|
lock.className = 'lock font-awesome';
|
||||||
lock.setAttribute('onclick', 'lock_device(this.parentElement.parentElement)');
|
lock.setAttribute('onclick', 'lock_device(this.parentElement.parentElement)');
|
||||||
device.querySelector('.id').appendChild(lock);
|
device.querySelector('.id').appendChild(lock);
|
||||||
});
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function delete_device_recv(data) {
|
||||||
|
let device = document.querySelector('#' + data.device_id);
|
||||||
|
device.remove()
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Websocket send */
|
||||||
|
function toggle_outlet(svg) {
|
||||||
|
let sub_dev = get_object_from_svg(svg).parentElement;
|
||||||
|
let data = {
|
||||||
|
device_id: sub_dev.parentElement.parentElement.id,
|
||||||
|
sub_device_id: sub_dev.querySelector('.id').innerText,
|
||||||
|
};
|
||||||
|
socket.send('toggle_outlet', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
function save_field(field) {
|
||||||
|
let value = field.firstElementChild.value;
|
||||||
|
let device_id = field.parentElement.id;
|
||||||
|
let sub_dev_id;
|
||||||
|
if (field.parentElement.className.includes('sub_device')) {
|
||||||
|
sub_device_id = field.parentElement.children[0].textContent;
|
||||||
|
device_id = field.parentElement.parentElement.parentElement.id;
|
||||||
|
} else {
|
||||||
|
sub_device_id = '';
|
||||||
|
}
|
||||||
|
let data = {
|
||||||
|
device_id: device_id,
|
||||||
|
sub_dev_id: sub_dev_id,
|
||||||
|
field: field.classList[0],
|
||||||
|
value: value
|
||||||
|
};
|
||||||
|
socket.send('edit_field', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
function new_device() {
|
||||||
|
let data = {
|
||||||
|
device_type: 'RelayDevice',
|
||||||
|
};
|
||||||
|
socket.send('new_device', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
function lock_device(device) {
|
||||||
|
if (device.querySelector('.save')) { return; }
|
||||||
|
let data = {
|
||||||
|
device_id: device.id,
|
||||||
|
locked: true,
|
||||||
|
};
|
||||||
|
socket.send('lock_device', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
function unlock_device(device) {
|
||||||
|
let data = {
|
||||||
|
device_id: device.id,
|
||||||
|
locked: false,
|
||||||
|
};
|
||||||
|
socket.send('lock_device', data);
|
||||||
}
|
}
|
||||||
|
|
||||||
function delete_device(device) {
|
function delete_device(device) {
|
||||||
if (!window.confirm("Are you sure you want to delete this device?")) { return; }
|
if (!window.confirm("Are you sure you want to delete this device?")) { return; }
|
||||||
let params = {
|
let data = {
|
||||||
device_id: device.id,
|
device_id: device.id,
|
||||||
};
|
};
|
||||||
let query = Object.keys(params)
|
socket.send('delete_device', data);
|
||||||
.map(k => encodeURIComponent(k) + '=' + encodeURIComponent(params[k]))
|
|
||||||
.join('&');
|
|
||||||
|
|
||||||
fetch(window.location.href + 'delete?' + query)
|
|
||||||
.then(function(response) {
|
|
||||||
return response.json();
|
|
||||||
})
|
|
||||||
.then(function(json) {
|
|
||||||
if (!json) { return; }
|
|
||||||
device.remove()
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function delete_token(token_id) {
|
/* DOM */
|
||||||
if (!window.confirm("Are you sure you want to delete this token?")) { return; }
|
function edit_field(field) {
|
||||||
let params = {
|
let value = field.firstElementChild.innerText;
|
||||||
token_id: token_id,
|
let input = document.createElement('input');
|
||||||
};
|
input.value = value;
|
||||||
let query = Object.keys(params)
|
field.firstElementChild.replaceWith(input);
|
||||||
.map(k => encodeURIComponent(k) + '=' + encodeURIComponent(params[k]))
|
|
||||||
.join('&');
|
|
||||||
|
|
||||||
fetch(url_prefix + '/delete_token?' + query)
|
let save = document.createElement('span');
|
||||||
.then(function(response) {
|
save.innerHTML = '';
|
||||||
return response.json();
|
save.className = 'save font-awesome';
|
||||||
})
|
save.setAttribute('onclick', 'save_field(this.parentElement)');
|
||||||
.then(function(json) {
|
field.children[1].replaceWith(save);
|
||||||
if (!json.ok) { return; }
|
|
||||||
document.querySelector('#token_' + token_id).remove();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Misc */
|
/* Misc */
|
||||||
|
|
Loading…
Reference in New Issue
Block a user