web app updates for deleting a node and disabling node context options
This commit is contained in:
parent
8c31b75c39
commit
f004d20b79
5 changed files with 104 additions and 35 deletions
|
@ -250,6 +250,23 @@ def get_node(session_id, node_id):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/sessions/<int:session_id>/nodes/<node_id>/terminal")
|
||||||
|
def node_terminal(session_id, node_id):
|
||||||
|
session = coreemu.sessions.get(session_id)
|
||||||
|
if not session:
|
||||||
|
return jsonify(error="session does not exist"), 404
|
||||||
|
|
||||||
|
if node_id.isdigit():
|
||||||
|
node_id = int(node_id)
|
||||||
|
node = session.objects.get(node_id)
|
||||||
|
if not node:
|
||||||
|
return jsonify(error="node does not exist"), 404
|
||||||
|
|
||||||
|
node.client.term("bash")
|
||||||
|
|
||||||
|
return jsonify()
|
||||||
|
|
||||||
|
|
||||||
@app.route("/sessions/<int:session_id>/nodes/<node_id>", methods=["DELETE"])
|
@app.route("/sessions/<int:session_id>/nodes/<node_id>", methods=["DELETE"])
|
||||||
@synchronized
|
@synchronized
|
||||||
def delete_node(session_id, node_id):
|
def delete_node(session_id, node_id):
|
||||||
|
|
|
@ -177,10 +177,9 @@ class CoreNetwork {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
this.network = new vis.Network(this.container, this.networkData, this.networkOptions);
|
this.network = new vis.Network(this.container, this.networkData, this.networkOptions);
|
||||||
this.network.on('doubleClick', this.addNode.bind(this));
|
this.network.on('doubleClick', this.doubleClick.bind(this));
|
||||||
this.network.on('dragEnd', this.dragEnd.bind(this));
|
this.network.on('dragEnd', this.dragEnd.bind(this));
|
||||||
this.edges.on('add', this.addEdge.bind(this));
|
this.edges.on('add', this.addEdge.bind(this));
|
||||||
this.nodesEnabled = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async initialSession() {
|
async initialSession() {
|
||||||
|
@ -197,6 +196,29 @@ class CoreNetwork {
|
||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deleteNode(nodeId) {
|
||||||
|
// remove node from graph
|
||||||
|
this.nodes.remove(nodeId);
|
||||||
|
|
||||||
|
// remove node links
|
||||||
|
const edges = this.edges.get();
|
||||||
|
for (let edge of edges) {
|
||||||
|
const link = edge.link;
|
||||||
|
|
||||||
|
if (edge.from === nodeId) {
|
||||||
|
this.edges.remove(edge);
|
||||||
|
const otherNode = this.getCoreNode(edge.to);
|
||||||
|
delete otherNode.interfaces[link.interfaceTwo.id];
|
||||||
|
delete this.links[edge.linkId]
|
||||||
|
} else if (edge.to === nodeId) {
|
||||||
|
this.edges.remove(edge);
|
||||||
|
const otherNode = this.getCoreNode(edge.from);
|
||||||
|
delete otherNode.interfaces[link.interfaceOne.id];
|
||||||
|
delete this.links[edge.linkId]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getCoreNode(nodeId) {
|
getCoreNode(nodeId) {
|
||||||
return this.nodes.get(nodeId).coreNode;
|
return this.nodes.get(nodeId).coreNode;
|
||||||
}
|
}
|
||||||
|
@ -223,11 +245,6 @@ class CoreNetwork {
|
||||||
this.links = {};
|
this.links = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
enableNodeCreation(enabled) {
|
|
||||||
console.log('node created enabled: ', enabled);
|
|
||||||
this.nodesEnabled = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
getCoreNodes() {
|
getCoreNodes() {
|
||||||
const coreNodes = [];
|
const coreNodes = [];
|
||||||
for (let node of this.nodes.get()) {
|
for (let node of this.nodes.get()) {
|
||||||
|
@ -359,9 +376,19 @@ class CoreNetwork {
|
||||||
return await coreRest.setSessionState(SessionStates.instantiation);
|
return await coreRest.setSessionState(SessionStates.instantiation);
|
||||||
}
|
}
|
||||||
|
|
||||||
addNode(properties) {
|
async doubleClick(properties) {
|
||||||
if (!this.nodesEnabled) {
|
const isRunning = await this.coreRest.isRunning();
|
||||||
console.log('node creation disabled');
|
|
||||||
|
// check for terminal interaction
|
||||||
|
if (isRunning && properties.nodes.length === 1) {
|
||||||
|
const nodeId = properties.nodes[0];
|
||||||
|
await this.coreRest.nodeTerminal(nodeId);
|
||||||
|
console.log('launched node terminal: ', nodeId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isRunning) {
|
||||||
|
console.log('node creation disabled, while running');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,6 +77,10 @@ class CoreRest {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async nodeTerminal(nodeId) {
|
||||||
|
return await $.getJSON(`/sessions/${this.currentSession}/nodes/${nodeId}/terminal`);
|
||||||
|
}
|
||||||
|
|
||||||
async createLink(link) {
|
async createLink(link) {
|
||||||
return await postJson(`/sessions/${this.currentSession}/links`, link);
|
return await postJson(`/sessions/${this.currentSession}/links`, link);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,8 @@ class ServicesModal {
|
||||||
this.$servicesList.html('');
|
this.$servicesList.html('');
|
||||||
this.serviceOptions.clear();
|
this.serviceOptions.clear();
|
||||||
|
|
||||||
|
this.$servicesModal.find('.modal-title').text(`Services: ${this.node.name}`);
|
||||||
|
|
||||||
for (let group in this.serviceGroups) {
|
for (let group in this.serviceGroups) {
|
||||||
const $option = $('<option>', {value: group, text: group});
|
const $option = $('<option>', {value: group, text: group});
|
||||||
this.$serviceGroup.append($option);
|
this.$serviceGroup.append($option);
|
||||||
|
@ -149,24 +151,38 @@ class SessionsModal {
|
||||||
}
|
}
|
||||||
|
|
||||||
class NodeContext {
|
class NodeContext {
|
||||||
constructor(coreNetwork, nodeEditModal, servicesModal) {
|
constructor(coreNetwork, coreRest, nodeEditModal, servicesModal) {
|
||||||
this.coreNetwork = coreNetwork;
|
this.coreNetwork = coreNetwork;
|
||||||
|
this.coreRest = coreRest;
|
||||||
this.nodeEditModal = nodeEditModal;
|
this.nodeEditModal = nodeEditModal;
|
||||||
this.servicesModal = servicesModal;
|
this.servicesModal = servicesModal;
|
||||||
this.$nodeContext = $('#node-context');
|
this.$nodeContext = $('#node-context');
|
||||||
|
this.$deleteButton = this.$nodeContext.find('button[data-option="delete"]');
|
||||||
this.onClick();
|
this.onClick();
|
||||||
}
|
}
|
||||||
|
|
||||||
show(nodeId, x, y) {
|
show(nodeId, x, y) {
|
||||||
const node = this.coreNetwork.nodes.get(nodeId);
|
const node = this.coreNetwork.nodes.get(nodeId);
|
||||||
console.log('context node: ', node);
|
console.log('context node: ', node);
|
||||||
this.$nodeContext.data('node', nodeId);
|
this.coreRest.isRunning()
|
||||||
this.$nodeContext.css({
|
.then(isRunning => {
|
||||||
position: 'absolute',
|
if (isRunning) {
|
||||||
left: x,
|
this.$deleteButton.attr('disabled', 'disabled');
|
||||||
top: y
|
} else {
|
||||||
});
|
this.$deleteButton.removeAttr('disabled');
|
||||||
this.$nodeContext.removeClass('d-none');
|
}
|
||||||
|
|
||||||
|
this.$nodeContext.data('node', nodeId);
|
||||||
|
this.$nodeContext.css({
|
||||||
|
position: 'absolute',
|
||||||
|
left: x,
|
||||||
|
top: y
|
||||||
|
});
|
||||||
|
this.$nodeContext.removeClass('d-none');
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
console.log('error checking is session is running: ', err);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
hide() {
|
hide() {
|
||||||
|
@ -182,13 +198,19 @@ class NodeContext {
|
||||||
const $target = $(event.target);
|
const $target = $(event.target);
|
||||||
const option = $target.data('option');
|
const option = $target.data('option');
|
||||||
console.log('node context: ', nodeId, option);
|
console.log('node context: ', nodeId, option);
|
||||||
if (option === 'edit') {
|
switch (option) {
|
||||||
self.nodeEditModal.show(nodeId);
|
case 'edit':
|
||||||
} else if (option === 'services') {
|
self.nodeEditModal.show(nodeId);
|
||||||
self.servicesModal.show(nodeId)
|
break;
|
||||||
.catch(function (err) {
|
case 'services':
|
||||||
console.log('error showing services modal: ', err);
|
self.servicesModal.show(nodeId)
|
||||||
});
|
.catch(function (err) {
|
||||||
|
console.log('error showing services modal: ', err);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 'delete':
|
||||||
|
self.coreNetwork.deleteNode(nodeId);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,14 +114,15 @@
|
||||||
{% include 'linkedit_modal.html' %}
|
{% include 'linkedit_modal.html' %}
|
||||||
{% include 'services_modal.html' %}
|
{% include 'services_modal.html' %}
|
||||||
|
|
||||||
<ul id="node-context" class="list-group context d-none">
|
<div id="node-context" class="list-group context d-none">
|
||||||
<a class="list-group-item list-group-item-action" href="#" data-option="edit">Edit Node</a>
|
<button type="button" class="list-group-item list-group-item-action" href="#" data-option="edit">Edit Node</button>
|
||||||
<a class="list-group-item list-group-item-action" href="#" data-option="services">Services</a>
|
<button type="button" class="list-group-item list-group-item-action" href="#" data-option="services">Services</button>
|
||||||
</ul>
|
<button type="button" class="list-group-item list-group-item-action" href="#" data-option="delete">Delete</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<ul id="edge-context" class="list-group context d-none">
|
<div id="edge-context" class="list-group context d-none">
|
||||||
<a class="list-group-item list-group-item-action" href="#" data-option="edit">Edit Link</a>
|
<button type="button" class="list-group-item list-group-item-action" href="#" data-option="edit">Edit Link</button>
|
||||||
</ul>
|
</div>
|
||||||
|
|
||||||
<script src="static/jquery-3.3.1.min.js"></script>
|
<script src="static/jquery-3.3.1.min.js"></script>
|
||||||
<script src="static/popper.min.js"></script>
|
<script src="static/popper.min.js"></script>
|
||||||
|
@ -162,7 +163,7 @@
|
||||||
const servicesModal = new ServicesModal(coreRest, coreNetwork);
|
const servicesModal = new ServicesModal(coreRest, coreNetwork);
|
||||||
const sessionsModal = new SessionsModal(coreRest, coreNetwork, joinSession);
|
const sessionsModal = new SessionsModal(coreRest, coreNetwork, joinSession);
|
||||||
const nodeEditModal = new NodeEditModal(coreNetwork);
|
const nodeEditModal = new NodeEditModal(coreNetwork);
|
||||||
const nodeContext = new NodeContext(coreNetwork, nodeEditModal, servicesModal);
|
const nodeContext = new NodeContext(coreNetwork, coreRest, nodeEditModal, servicesModal);
|
||||||
const edgeEditModal = new EdgeEditModal(coreNetwork, coreRest);
|
const edgeEditModal = new EdgeEditModal(coreNetwork, coreRest);
|
||||||
const edgeContext = new EdgeContext(coreNetwork, edgeEditModal);
|
const edgeContext = new EdgeContext(coreNetwork, edgeEditModal);
|
||||||
const infoPanel = new InfoPanel(coreNetwork);
|
const infoPanel = new InfoPanel(coreNetwork);
|
||||||
|
@ -183,13 +184,11 @@
|
||||||
$runButton.text('Start');
|
$runButton.text('Start');
|
||||||
$runButton.addClass('btn-success');
|
$runButton.addClass('btn-success');
|
||||||
$linkButton.removeAttr('disabled');
|
$linkButton.removeAttr('disabled');
|
||||||
coreNetwork.enableNodeCreation(true);
|
|
||||||
} else {
|
} else {
|
||||||
$runButton.text('Stop');
|
$runButton.text('Stop');
|
||||||
$runButton.addClass('btn-danger');
|
$runButton.addClass('btn-danger');
|
||||||
$linkButton.removeClass('active');
|
$linkButton.removeClass('active');
|
||||||
$linkButton.attr('disabled', 'disabled');
|
$linkButton.attr('disabled', 'disabled');
|
||||||
coreNetwork.enableNodeCreation(false);
|
|
||||||
coreNetwork.linkMode(false);
|
coreNetwork.linkMode(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue