', {class: 'input-group'});
const $ip6Label = $('
', {class: 'input-group-prepend'}).append(
$('', {class: 'input-group-text', text: 'IP6'})
);
const $ip6 = $('', {
class: 'form-control',
type: 'text',
name: `interface-${interfaceId}-ip6`,
value: nodeInterface.ip6
});
const $ip6Mask = $('', {
class: 'form-control',
type: 'text',
name: `interface-${interfaceId}-ip6mask`,
value: nodeInterface.ip6mask
});
$inputGroup.append([$ip6Label, $ip6, $ip6Mask]);
this.$formCustom.append($inputGroup);
}
}
async show(nodeId) {
const node = this.coreNetwork.getCoreNode(nodeId);
this.$modal.data('node', nodeId);
this.$modal.find('.modal-title').text(`Edit Node: ${node.name}`);
this.$modal.find('#node-name').val(node.name);
this.$formCustom.html('');
// add interface edit
this.addInterfaceOptions(node);
// add emane edit
if (node.type === CoreNodeHelper.emaneNode) {
this.addEmaneOptions(node);
}
this.$modal.modal('show');
}
onClick() {
const $form = this.$modal.find('form');
const formData = formToJson($form);
console.log('node edit data: ', formData);
const nodeId = this.$modal.data('node');
const node = this.coreNetwork.nodes.get(nodeId);
if (formData.name) {
node.label = formData.name;
node.coreNode.name = formData.name;
this.coreNetwork.nodes.update(node);
}
// deal with interface data
const interfaceKeys = Object.keys(formData)
.filter(key => key.startsWith('interface'));
for (let interfaceKey of interfaceKeys) {
const value = formData[interfaceKey];
const interfaceValues = interfaceKey.split('-');
const interfaceId = interfaceValues[1];
const field = interfaceValues[2];
node.coreNode.interfaces[interfaceId][field] = value;
}
if (formData.emane !== undefined) {
node.coreNode.emane = formData.emane;
}
this.$modal.modal('hide');
}
}
class EdgeContext {
constructor(coreNetwork, edgeEditModal) {
this.coreNetwork = coreNetwork;
this.edgeEditModal = edgeEditModal;
this.$context = $('#edge-context');
this.$context.click(this.onClick.bind(this));
}
show(edgeId, x, y) {
const edge = this.coreNetwork.edges.get(edgeId);
console.log('context edge: ', edge);
this.$context.data('edge', edgeId);
this.$context.css({
position: 'absolute',
left: x,
top: y
});
this.$context.removeClass('d-none');
}
hide() {
this.$context.addClass('d-none');
}
onClick(event) {
this.$context.addClass('d-none');
console.log('edge context click: ', event);
const edgeId = this.$context.data('edge');
const $target = $(event.target);
const option = $target.data('option');
console.log('edge context: ', edgeId, option);
if (option === 'edit') {
this.edgeEditModal.show(edgeId);
}
}
}
class EdgeEditModal {
constructor(coreNetwork, coreRest) {
this.coreNetwork = coreNetwork;
this.coreRest = coreRest;
this.$modal = $('#linkedit-modal');
this.$editButton = $('#linkedit-button');
this.$editButton.click(this.onClick.bind(this));
}
show(edgeId) {
// populate form with current link data
const edge = this.coreNetwork.edges.get(edgeId);
const link = edge.link;
this.$modal.data('link', edgeId);
this.$modal.find('#link-bandwidth').val(link.bandwidth);
this.$modal.find('#link-delay').val(link.delay);
this.$modal.find('#link-per').val(link.loss);
this.$modal.find('#link-dup').val(link.duplicate);
this.$modal.find('#link-jitter').val(link.jitter);
// set modal name and show
this.$modal.find('.modal-title').text('Edit Edge');
this.$modal.modal('show');
}
async onClick(event) {
const $form = this.$modal.find('form');
const formData = {};
$form.serializeArray().map(function (x) {
let value = x.value;
if (value === '') {
value = null;
} else if (!isNaN(value)) {
value = parseInt(value);
}
formData[x.name] = value;
});
console.log('link edit data: ', formData);
const edgeId = this.$modal.data('link');
const edge = this.coreNetwork.edges.get(edgeId);
const link = edge.link;
link.bandwidth = formData.bandwidth;
link.delay = formData.delay;
link.duplicate = formData.duplicate;
link.loss = formData.loss;
link.jitter = formData.jitter;
if (await coreRest.isRunning()) {
const linkEdit = link.json();
linkEdit.interface_one = linkEdit.interface_one.id;
linkEdit.interface_two = linkEdit.interface_two.id;
await this.coreRest.editLink(linkEdit);
console.log('link edit success');
}
this.$modal.modal('hide');
}
}
class InfoPanel {
constructor(coreNetwork) {
this.coreNetwork = coreNetwork;
this.$infoCard = $('#info-card');
this.$infoCardTable = $('#info-card-table');
this.$infoCardHeader = $('#info-card-header');
this.coreNetwork.nodes.on('remove', this.onNodeDelete.bind(this));
this.coreNetwork.edges.on('remove', this.onEdgeDelete.bind(this));
}
onNodeDelete(_, properties) {
if (properties.items.length !== 1) {
return;
}
const nodeId = properties.items[0];
if (nodeId === this.$infoCard.data('node')) {
this.hide();
}
}
onEdgeDelete(_, properties) {
if (properties.items.length !== 1) {
return;
}
const edgeId = properties.items[0];
if (edgeId === this.$infoCard.data('edge')) {
this.hide();
}
}
addInfoTable(name, value) {
const $nameCell = $('
', {text: name});
const $valueCell = $(' | ', {text: value});
const $row = $(' | ').append([$nameCell, $valueCell]);
this.$infoCardTable.find('tbody').append($row);
}
show() {
this.$infoCard.removeClass('visible invisible');
this.$infoCard.addClass('visible');
}
hide() {
this.$infoCard.removeClass('visible invisible');
this.$infoCard.addClass('invisible');
}
addInterfaceInfo(nodeInterface) {
this.addInfoTable('Interface', `eth${nodeInterface.id}`);
if (nodeInterface.ip4) {
this.addInfoTable('IP4', `${nodeInterface.ip4}/${nodeInterface.ip4mask}`);
}
if (nodeInterface.ip6) {
this.addInfoTable('IP6', `${nodeInterface.ip6}/${nodeInterface.ip6mask}`);
}
}
showNode(nodeId) {
const node = coreNetwork.getCoreNode(nodeId);
this.$infoCard.data('node', nodeId);
this.$infoCardHeader.text(node.name);
this.$infoCardTable.find('tbody tr').remove();
if (node.model) {
this.addInfoTable('Model', node.model);
}
if (node.emane) {
this.addInfoTable('EMANE', node.emane);
}
this.addInfoTable('X', node.x);
this.addInfoTable('Y', node.y);
for (let interfaceId in node.interfaces) {
const nodeInterface = node.interfaces[interfaceId];
console.log('node interface: ', nodeInterface);
this.addInterfaceInfo(nodeInterface);
}
this.show();
}
showEdge(edgeId) {
const edge = coreNetwork.edges.get(edgeId);
const link = edge.link;
const nodeOne = coreNetwork.getCoreNode(link.nodeOne);
const nodeTwo = coreNetwork.getCoreNode(link.nodeTwo);
console.log('clicked edge: ', link);
this.$infoCard.data('edge', edgeId);
this.$infoCard.addClass('visible');
this.$infoCardHeader.text('Edge');
this.$infoCardTable.find('tbody tr').remove();
const interfaceOne = link.interfaceOne;
if (interfaceOne) {
this.addInfoTable(nodeOne.name, null);
this.addInterfaceInfo(interfaceOne);
}
const interfaceTwo = link.interfaceTwo;
if (interfaceTwo) {
this.addInfoTable(nodeTwo.name, null);
this.addInterfaceInfo(interfaceTwo);
}
this.addInfoTable('Bandwidth', edge.link.bandwidth);
this.addInfoTable('Delay', edge.link.delay);
this.addInfoTable('Duplicate', edge.link.duplicate);
this.addInfoTable('Loss', edge.link.loss);
this.addInfoTable('Jitter', edge.link.jitter);
this.show();
}
}