mirror of
https://github.com/ZwareBear/awx.git
synced 2026-04-13 03:21:49 -05:00
Adds search field and jump-to a device UI.
Adds a search field in the network UI and a jump-to level menu. This allows users to quickly find a device on the canvas or jump to a certain mode/zoom-level. Adds animation to smooth out the transition from the current viewport to a viewport centered on the searched for device or zoom-level. * Adds animation FSM and changes the 0 hot key to use it * Adds jump to animation * Adds search bar type ahead * Adds jump animation to search and jump-to menus * Adds keybinding FSM * Updates the dropdown when devices are added/edit/removed * Highlights the searched for host
This commit is contained in:
@@ -19,6 +19,8 @@ var test_fsm = require('./test.fsm.js');
|
||||
var util = require('./util.js');
|
||||
var models = require('./models.js');
|
||||
var messages = require('./messages.js');
|
||||
var animations = require('./animations.js');
|
||||
var keybindings = require('./keybindings.fsm.js');
|
||||
var svg_crowbar = require('./svg-crowbar.js');
|
||||
var ReconnectingWebSocket = require('reconnectingwebsocket');
|
||||
|
||||
@@ -106,6 +108,7 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
|
||||
$scope.message_id_seq = util.natural_numbers(0);
|
||||
$scope.stream_id_seq = util.natural_numbers(0);
|
||||
$scope.test_result_id_seq = util.natural_numbers(0);
|
||||
$scope.animation_id_seq = util.natural_numbers(0);
|
||||
$scope.overall_toolbox_collapsed = false;
|
||||
$scope.time_pointer = -1;
|
||||
$scope.frame = 0;
|
||||
@@ -124,6 +127,7 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
|
||||
$scope.test_results = [];
|
||||
$scope.test_errors = [];
|
||||
$scope.streams = [];
|
||||
$scope.animations = [];
|
||||
$scope.view_port = {'x': 0,
|
||||
'y': 0,
|
||||
'width': 0,
|
||||
@@ -131,6 +135,10 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
|
||||
$scope.trace_id_seq = util.natural_numbers(0);
|
||||
$scope.trace_order_seq = util.natural_numbers(0);
|
||||
$scope.trace_id = $scope.trace_id_seq();
|
||||
$scope.jump = {from_x: 0,
|
||||
from_y: 0,
|
||||
to_x: 0,
|
||||
to_y: 0};
|
||||
|
||||
$scope.send_trace_message = function (message) {
|
||||
if (!$scope.recording) {
|
||||
@@ -150,9 +158,30 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
|
||||
}
|
||||
};
|
||||
|
||||
$scope.onKeyDown = function ($event) {
|
||||
if ($scope.recording) {
|
||||
$scope.send_control_message(new messages.KeyEvent($scope.client_id,
|
||||
$event.key,
|
||||
$event.keyCode,
|
||||
$event.type,
|
||||
$event.altKey,
|
||||
$event.shiftKey,
|
||||
$event.ctrlKey,
|
||||
$event.metaKey,
|
||||
$scope.trace_id));
|
||||
}
|
||||
$scope.last_event = $event;
|
||||
$scope.last_key = $event.key;
|
||||
$scope.last_key_code = $event.keyCode;
|
||||
$scope.first_channel.send('KeyDown', $event);
|
||||
$scope.$apply();
|
||||
$event.preventDefault();
|
||||
};
|
||||
|
||||
//Define the FSMs
|
||||
$scope.null_controller = new fsm.FSMController($scope, "null_fsm", null_fsm.Start, $scope);
|
||||
$scope.hotkeys_controller = new fsm.FSMController($scope, "hotkeys_fsm", hotkeys.Start, $scope);
|
||||
$scope.keybindings_controller = new fsm.FSMController($scope, "keybindings_fsm", keybindings.Start, $scope);
|
||||
$scope.view_controller = new fsm.FSMController($scope, "view_fsm", view.Start, $scope);
|
||||
$scope.device_detail_controller = new fsm.FSMController($scope, "device_detail_fsm", device_detail_fsm.Start, $scope);
|
||||
$scope.move_controller = new fsm.FSMController($scope, "move_fsm", move.Start, $scope);
|
||||
@@ -202,21 +231,28 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
|
||||
.then(function(response) {
|
||||
let hosts = response.data.results;
|
||||
for(var i = 0; i<hosts.length; i++){
|
||||
let host = hosts[i];
|
||||
console.log(host);
|
||||
host.data = jsyaml.safeLoad(host.variables);
|
||||
if (host.data.type == undefined) {
|
||||
host.data.type = 'unknown';
|
||||
try {
|
||||
let host = hosts[i];
|
||||
console.log(host);
|
||||
if (host.variables !== "") {
|
||||
host.data = jsyaml.safeLoad(host.variables);
|
||||
if (host.data.type === undefined) {
|
||||
host.data.type = 'unknown';
|
||||
}
|
||||
if (host.data.name === undefined) {
|
||||
host.data.name = host.name;
|
||||
}
|
||||
var device = new models.Device(0, host.data.name, 0, 0, host.data.type, host.id, host.variables);
|
||||
device.icon = true;
|
||||
$scope.inventory_toolbox.items.push(device);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
if (host.data.name == undefined) {
|
||||
host.data.name = host.name;
|
||||
}
|
||||
var device = new models.Device(0, host.data.name, 0, 0, host.data.type, host.id, host.variables);
|
||||
device.icon = true;
|
||||
$scope.inventory_toolbox.items.push(device);
|
||||
}
|
||||
})
|
||||
.catch(({data, status}) => {
|
||||
console.log([data, status]);
|
||||
ProcessErrors($scope, data, status, null, { hdr: 'Error!', msg: 'Failed to get host data: ' + status });
|
||||
});
|
||||
}
|
||||
@@ -269,9 +305,13 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
|
||||
$scope.mode_controller = new fsm.FSMController($scope, "mode_fsm", mode_fsm.Start, $scope);
|
||||
|
||||
//Wire up the FSMs
|
||||
$scope.view_controller.delegate_channel = new fsm.Channel($scope.view_controller,
|
||||
$scope.keybindings_controller.delegate_channel = new fsm.Channel($scope.keybindings_controller,
|
||||
$scope.hotkeys_controller,
|
||||
$scope);
|
||||
|
||||
$scope.view_controller.delegate_channel = new fsm.Channel($scope.view_controller,
|
||||
$scope.keybindings_controller,
|
||||
$scope);
|
||||
$scope.device_detail_controller.delegate_channel = new fsm.Channel($scope.device_detail_controller,
|
||||
$scope.view_controller,
|
||||
$scope);
|
||||
@@ -354,6 +394,24 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
|
||||
g.setAttribute('transform','translate(' + $scope.panX + ',' + $scope.panY + ') scale(' + $scope.current_scale + ')');
|
||||
};
|
||||
|
||||
$scope.to_virtual_coordinates = function (b_x, b_y) {
|
||||
var v_x = (b_x - $scope.panX) / $scope.current_scale;
|
||||
var v_y = (b_y - $scope.panY) / $scope.current_scale;
|
||||
return {x: v_x, y: v_y};
|
||||
};
|
||||
|
||||
$scope.to_browser_coordinates = function (v_x, v_y) {
|
||||
var b_x = (v_x * $scope.current_scale) + $scope.panX;
|
||||
var b_y = (v_y * $scope.current_scale) + $scope.panY;
|
||||
return {x: b_x, y: b_y};
|
||||
};
|
||||
|
||||
$scope.to_pan = function (v_x, v_y) {
|
||||
var p_x = v_x * $scope.current_scale * -1;
|
||||
var p_y = v_y * $scope.current_scale * -1;
|
||||
return {x: p_x, y: p_y};
|
||||
};
|
||||
|
||||
$scope.clear_selections = function () {
|
||||
|
||||
var i = 0;
|
||||
@@ -565,41 +623,22 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
|
||||
$event.preventDefault();
|
||||
};
|
||||
|
||||
$scope.onKeyDown = function ($event) {
|
||||
if ($scope.recording) {
|
||||
$scope.send_control_message(new messages.KeyEvent($scope.client_id,
|
||||
$event.key,
|
||||
$event.keyCode,
|
||||
$event.type,
|
||||
$event.altKey,
|
||||
$event.shiftKey,
|
||||
$event.ctrlKey,
|
||||
$event.metaKey,
|
||||
$scope.trace_id));
|
||||
}
|
||||
$scope.last_event = $event;
|
||||
$scope.last_key = $event.key;
|
||||
$scope.last_key_code = $event.keyCode;
|
||||
$scope.first_channel.send('KeyDown', $event);
|
||||
$scope.$apply();
|
||||
$event.preventDefault();
|
||||
};
|
||||
|
||||
$document.bind("keydown", $scope.onKeyDown);
|
||||
|
||||
// Conext Menu Button Handlers
|
||||
|
||||
$scope.removeContextMenu = function(){
|
||||
let context_menu = $scope.context_menus[0];
|
||||
context_menu.enabled = false;
|
||||
context_menu.x = -100000;
|
||||
context_menu.y = -100000;
|
||||
context_menu.buttons.forEach(function(button, index){
|
||||
context_menu.buttons.forEach(function(button){
|
||||
button.enabled = false;
|
||||
button.x = -100000;
|
||||
button.y = -100000;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
$scope.closeDetailsPanel = function () {
|
||||
$scope.$emit('closeDetailsPanel');
|
||||
};
|
||||
|
||||
$scope.onDetailsContextButton = function (panelBoolean) {
|
||||
if (!$scope.disconnected) {
|
||||
@@ -689,6 +728,7 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
|
||||
index = $scope.devices.indexOf(devices[i]);
|
||||
if (index !== -1) {
|
||||
$scope.devices.splice(index, 1);
|
||||
$scope.$emit('removeSearchOption', devices[i]);
|
||||
$scope.send_control_message(new messages.DeviceDestroy($scope.client_id,
|
||||
devices[i].id,
|
||||
devices[i].x,
|
||||
@@ -790,29 +830,85 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
|
||||
$scope[`on${functionName}Button`]();
|
||||
});
|
||||
|
||||
$scope.$on('jumpTo', function(e, zoomLevel){
|
||||
$scope.$on('unbind', function(){
|
||||
$scope.first_channel.send('UnbindDocument', {});
|
||||
});
|
||||
|
||||
$scope.$on('bind', function(){
|
||||
$scope.first_channel.send('BindDocument', {});
|
||||
});
|
||||
|
||||
$scope.jump_to_animation = function(jump_to_x, jump_to_y, jump_to_scale) {
|
||||
$scope.cancel_animations();
|
||||
var v_center = $scope.to_virtual_coordinates($scope.graph.width/2, $scope.graph.height/2);
|
||||
//console.log({v_center: v_center});
|
||||
$scope.jump.from_x = v_center.x;
|
||||
$scope.jump.from_y = v_center.y;
|
||||
$scope.jump.to_x = jump_to_x;
|
||||
$scope.jump.to_y = jump_to_y;
|
||||
var distance = util.distance(v_center.x, v_center.y, jump_to_x, jump_to_y);
|
||||
//console.log({distance: distance});
|
||||
var num_frames = 30 * Math.floor((1 + 4 * distance / (distance + 3000)));
|
||||
//console.log({num_frames: num_frames});
|
||||
var scale_animation = new models.Animation($scope.animation_id_seq(),
|
||||
num_frames,
|
||||
{
|
||||
c: -0.1,
|
||||
distance: distance,
|
||||
end_height: (1.0/jump_to_scale) - 1,
|
||||
current_scale: $scope.current_scale,
|
||||
scope: $scope
|
||||
},
|
||||
$scope,
|
||||
$scope,
|
||||
animations.scale_animation);
|
||||
$scope.animations.push(scale_animation);
|
||||
var pan_animation = new models.Animation($scope.animation_id_seq(),
|
||||
num_frames,
|
||||
{
|
||||
x2: jump_to_x,
|
||||
y2: jump_to_y,
|
||||
x1: v_center.x,
|
||||
y1: v_center.y,
|
||||
scope: $scope
|
||||
},
|
||||
$scope,
|
||||
$scope,
|
||||
animations.pan_animation);
|
||||
$scope.animations.push(pan_animation);
|
||||
};
|
||||
|
||||
$scope.$on('search', function(e, device){
|
||||
|
||||
var num_frames = 30;
|
||||
var searched;
|
||||
for(var i = 0; i < $scope.devices.length; i++){
|
||||
if(Number(device.id) === $scope.devices[i].id){
|
||||
searched = $scope.devices[i];
|
||||
}
|
||||
}
|
||||
searched.selected = true;
|
||||
$scope.selected_devices.push(searched);
|
||||
//console.log(searched);
|
||||
$scope.jump_to_animation(searched.x, searched.y, 1.0);
|
||||
});
|
||||
|
||||
$scope.$on('jumpTo', function(e, zoomLevel) {
|
||||
var v_center = $scope.to_virtual_coordinates($scope.graph.width/2, $scope.graph.height/2);
|
||||
switch (zoomLevel){
|
||||
case 'site':
|
||||
$scope.current_scale = 0.051;
|
||||
$scope.jump_to_animation(v_center.x, v_center.y, 0.051);
|
||||
break;
|
||||
case 'rack':
|
||||
$scope.current_scale = 0.11;
|
||||
$scope.jump_to_animation(v_center.x, v_center.y, 0.11);
|
||||
break;
|
||||
case 'inventory':
|
||||
$scope.current_scale = 0.51;
|
||||
$scope.jump_to_animation(v_center.x, v_center.y, 0.51);
|
||||
break;
|
||||
case 'process':
|
||||
$scope.current_scale = 1.1;
|
||||
$scope.jump_to_animation(v_center.x, v_center.y, 5.1);
|
||||
break;
|
||||
}
|
||||
// var new_panX = controller.scope.{{somethinghere}} - new_scale * ((controller.scope.mouseX - controller.scope.panX) / controller.scope.current_scale);
|
||||
// var new_panY = controller.scope.mouseY - new_scale * ((controller.scope.mouseY - controller.scope.panY) / controller.scope.current_scale);
|
||||
// // controller.scope.updateScaledXY();
|
||||
// // controller.scope.current_scale = new_scale;
|
||||
// controller.scope.panX = new_panX;
|
||||
// controller.scope.panY = new_panY;
|
||||
$scope.updateScaledXY();
|
||||
$scope.updatePanAndScale();
|
||||
});
|
||||
|
||||
$scope.onDeployButton = function (button) {
|
||||
@@ -1691,6 +1787,7 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
|
||||
}
|
||||
|
||||
$scope.updateInterfaceDots();
|
||||
$scope.$emit('instatiateSelect', $scope.devices);
|
||||
};
|
||||
|
||||
$scope.updateInterfaceDots = function() {
|
||||
@@ -1774,7 +1871,7 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
|
||||
|
||||
$scope.$on('$destroy', function () {
|
||||
console.log("Network UI stopping");
|
||||
$document.unbind('keydown', $scope.onKeyDown);
|
||||
$scope.first_channel.send('UnbindDocument', {});
|
||||
});
|
||||
|
||||
$scope.update_toolbox_heights = function(){
|
||||
@@ -1877,6 +1974,8 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
|
||||
$scope.null_controller.state.start($scope.null_controller);
|
||||
$scope.hotkeys_controller.state = hotkeys.Start;
|
||||
$scope.hotkeys_controller.state.start($scope.hotkeys_controller);
|
||||
$scope.keybindings_controller.state = keybindings.Start;
|
||||
$scope.keybindings_controller.state.start($scope.keybindings_controller);
|
||||
$scope.view_controller.state = view.Start;
|
||||
$scope.view_controller.state.start($scope.view_controller);
|
||||
$scope.device_detail_controller.state = device_detail_fsm.Start;
|
||||
@@ -1927,6 +2026,15 @@ var NetworkUIController = function($scope, $document, $location, $window, $http,
|
||||
$scope.rack_toolbox.items = [];
|
||||
$scope.site_toolbox.items = [];
|
||||
};
|
||||
|
||||
$scope.cancel_animations = function () {
|
||||
|
||||
var i = 0;
|
||||
for (i = 0; i < $scope.animations.length; i++) {
|
||||
this.animations[i].fsm.handle_message('AnimationCancelled');
|
||||
}
|
||||
$scope.animations = [];
|
||||
};
|
||||
};
|
||||
|
||||
exports.NetworkUIController = NetworkUIController;
|
||||
|
||||
Reference in New Issue
Block a user