diff --git a/awx/network_ui/designs/animation_fsm.yml b/awx/network_ui/designs/animation_fsm.yml
new file mode 100644
index 0000000000..c99b99dd1c
--- /dev/null
+++ b/awx/network_ui/designs/animation_fsm.yml
@@ -0,0 +1,29 @@
+diagram_id: 58
+name: animation_fsm
+states:
+- id: 4
+ label: Cancelled
+ x: 590
+ y: 602
+- id: 3
+ label: Completed
+ x: 225
+ y: 604
+- id: 2
+ label: Running
+ x: 418
+ y: 362
+- id: 1
+ label: Start
+ x: 454
+ y: 158
+transitions:
+- from_state: Running
+ label: onAnimationCancelled
+ to_state: Cancelled
+- from_state: Running
+ label: onAnimationCompleted
+ to_state: Completed
+- from_state: Start
+ label: start
+ to_state: Running
diff --git a/awx/network_ui/designs/keybindings.png b/awx/network_ui/designs/keybindings.png
new file mode 100644
index 0000000000..e54b652211
Binary files /dev/null and b/awx/network_ui/designs/keybindings.png differ
diff --git a/awx/network_ui/designs/keybindings.yml b/awx/network_ui/designs/keybindings.yml
new file mode 100644
index 0000000000..11ce6fa212
--- /dev/null
+++ b/awx/network_ui/designs/keybindings.yml
@@ -0,0 +1,25 @@
+diagram_id: 60
+name: diagram
+states:
+- id: 3
+ label: Enabled
+ x: 842
+ y: 533
+- id: 2
+ label: Start
+ x: 839
+ y: 270
+- id: 6
+ label: Disabled
+ x: 1231
+ y: 532
+transitions:
+- from_state: Start
+ label: start
+ to_state: Enabled
+- from_state: Disabled
+ label: onBindDocument
+ to_state: Enabled
+- from_state: Enabled
+ label: onUnbindDocument
+ to_state: Disabled
diff --git a/awx/network_ui/static/network_ui/extract.js b/awx/network_ui/static/network_ui/extract.js
index 40c14c7462..79edb17f60 100755
--- a/awx/network_ui/static/network_ui/extract.js
+++ b/awx/network_ui/static/network_ui/extract.js
@@ -26,7 +26,7 @@ var transition = null;
var i = 0;
while(next_state !== undefined) {
state = implementation[next_state];
- transition_iter = Iterator(state.constructor.prototype)
+ transition_iter = Iterator(state.constructor.prototype);
next_transition = transition_iter.next();
while (next_transition !== undefined) {
transition = state.constructor.prototype[next_transition];
diff --git a/awx/network_ui/static/network_ui/extract_messages.js b/awx/network_ui/static/network_ui/extract_messages.js
index 914e5c4cb0..aee32413de 100755
--- a/awx/network_ui/static/network_ui/extract_messages.js
+++ b/awx/network_ui/static/network_ui/extract_messages.js
@@ -20,19 +20,19 @@ var next_message = message_iter.next();
var next_field = null;
var message = null;
var message_instance = null;
-var field = null;
var fields = null;
-var i = 0;
+// var field = null;
+// var i = 0;
while(next_message !== undefined) {
message = implementation[next_message];
try {
- message_instance = new message()
+ message_instance = new message();
} catch(err) {
next_message = message_iter.next();
continue;
}
fields = [];
- field_iter = Iterator(message_instance)
+ field_iter = Iterator(message_instance);
next_field = field_iter.next();
while (next_field !== undefined) {
fields.push(next_field);
diff --git a/awx/ui/client/features/_index.less b/awx/ui/client/features/_index.less
index 053f270ddd..e2339dc9e4 100644
--- a/awx/ui/client/features/_index.less
+++ b/awx/ui/client/features/_index.less
@@ -1,3 +1,2 @@
@import 'credentials/_index';
@import 'users/tokens/_index';
-@import 'networking/_index';
diff --git a/awx/ui/client/features/index.js b/awx/ui/client/features/index.js
index 5eb1cd96b2..01216e575f 100644
--- a/awx/ui/client/features/index.js
+++ b/awx/ui/client/features/index.js
@@ -6,7 +6,6 @@ import atFeaturesApplications from '~features/applications';
import atFeaturesCredentials from '~features/credentials';
import atFeaturesTemplates from '~features/templates';
import atFeaturesUsers from '~features/users';
-import atFeaturesNetworking from '~features/networking';
const MODULE_NAME = 'at.features';
@@ -17,8 +16,7 @@ angular.module(MODULE_NAME, [
atFeaturesApplications,
atFeaturesCredentials,
atFeaturesTemplates,
- atFeaturesUsers,
- atFeaturesNetworking
+ atFeaturesUsers
]);
export default MODULE_NAME;
diff --git a/awx/ui/client/features/networking/networking.controller.js b/awx/ui/client/features/networking/networking.controller.js
deleted file mode 100644
index f330d30ac1..0000000000
--- a/awx/ui/client/features/networking/networking.controller.js
+++ /dev/null
@@ -1,66 +0,0 @@
-function NetworkingController (models, $state, $scope, strings) {
- const vm = this || {};
-
- const {
- inventory
- } = models;
-
- vm.strings = strings;
- vm.panelTitle = `${strings.get('state.BREADCRUMB_LABEL')} | ${inventory.name}`;
- vm.hostDetail = {};
-
- vm.rightPanelIsExpanded = false;
- vm.leftPanelIsExpanded = true;
- vm.jumpToPanelExpanded = false;
- vm.keyPanelExpanded = false;
- vm.close = () => {
- $state.go('inventories');
- };
-
- vm.redirectButtonHandler = (string) => {
- $scope.$broadcast('toolbarButtonEvent', string);
- };
-
- vm.jumpTo = (string) => {
- vm.jumpToPanelExpanded = !vm.jumpToPanelExpanded;
- vm.keyPanelExpanded = false;
- if (string) {
- $scope.$broadcast('jumpTo', string);
- }
- };
-
- vm.key = () => {
- vm.keyPanelExpanded = !vm.keyPanelExpanded;
- vm.jumpToPanelExpanded = false;
- };
-
- $scope.$on('overall_toolbox_collapsed', () => {
- vm.leftPanelIsExpanded = !vm.leftPanelIsExpanded;
- });
-
- $scope.$on('closeDetailsPanel', () => {
- vm.rightPanelIsExpanded = false;
- vm.jumpToPanelExpanded = false;
- vm.keyPanelExpanded = false;
- });
-
- $scope.$on('showDetails', (e, data, expand) => {
- if (expand) {
- vm.rightPanelIsExpanded = true;
- }
- if (!_.has(data, 'host_id')) {
- $scope.item = data;
- } else {
- $scope.item = data;
- }
- });
-}
-
-NetworkingController.$inject = [
- 'resolvedModels',
- '$state',
- '$scope',
- 'NetworkingStrings'
-];
-
-export default NetworkingController;
diff --git a/awx/ui/client/src/network-ui/animation.fsm.js b/awx/ui/client/src/network-ui/animation.fsm.js
new file mode 100644
index 0000000000..19fe58c731
--- /dev/null
+++ b/awx/ui/client/src/network-ui/animation.fsm.js
@@ -0,0 +1,81 @@
+/* Copyright (c) 2018 Benjamin Thomasson */
+/* Copyright (c) 2018 Red Hat, Inc. */
+
+var inherits = require('inherits');
+var fsm = require('./fsm.js');
+
+
+function _Start () {
+ this.name = 'Start';
+}
+inherits(_Start, fsm._State);
+var Start = new _Start();
+exports.Start = Start;
+
+function _Completed () {
+ this.name = 'Completed';
+}
+inherits(_Completed, fsm._State);
+var Completed = new _Completed();
+exports.Completed = Completed;
+
+function _Cancelled () {
+ this.name = 'Cancelled';
+}
+inherits(_Cancelled, fsm._State);
+var Cancelled = new _Cancelled();
+exports.Cancelled = Cancelled;
+
+function _Running () {
+ this.name = 'Running';
+}
+inherits(_Running, fsm._State);
+var Running = new _Running();
+exports.Running = Running;
+
+
+_Start.prototype.start = function (controller) {
+
+ controller.changeState(Running);
+};
+_Start.prototype.start.transitions = ['Running'];
+
+_Running.prototype.start = function (controller) {
+
+ controller.scope.interval = setInterval(function () {
+ controller.scope.frame_number = controller.scope.frame_number_seq();
+ if (!controller.scope.active) {
+ return;
+ }
+ if (controller.scope.frame_number > controller.scope.steps) {
+ controller.scope.fsm.handle_message('AnimationCompleted');
+ return;
+ }
+ controller.scope.callback(controller.scope);
+ controller.scope.scope.$apply();
+ }, 17);
+};
+
+_Running.prototype.onAnimationCancelled = function (controller) {
+
+ controller.changeState(Cancelled);
+
+};
+_Running.prototype.onAnimationCancelled.transitions = ['Cancelled'];
+
+_Running.prototype.onAnimationCompleted = function (controller) {
+
+ controller.changeState(Completed);
+
+};
+_Running.prototype.onAnimationCompleted.transitions = ['Completed'];
+
+_Completed.prototype.start = function (controller) {
+ controller.scope.active = false;
+ clearInterval(controller.scope.interval);
+};
+
+_Cancelled.prototype.start = function (controller) {
+ controller.scope.active = false;
+ clearInterval(controller.scope.interval);
+};
diff --git a/awx/ui/client/src/network-ui/animations.js b/awx/ui/client/src/network-ui/animations.js
new file mode 100644
index 0000000000..b5caee6b3d
--- /dev/null
+++ b/awx/ui/client/src/network-ui/animations.js
@@ -0,0 +1,51 @@
+
+/*
+ * Uses y = cx^2 * cdx to calculate the height of the camera
+ * Uses scale = 1 / (height + 1) to calculate the scale of the virtual canvas
+ */
+
+function scale_animation (scope) {
+
+ var d = scope.steps;
+ var c = scope.data.c;
+ var x = scope.frame_number;
+ var initial_height = ((1 / scope.data.current_scale) - 1);
+ var a = -1 * initial_height / (c * d);
+ var height = 0;
+ if(scope.data.distance > 0) {
+ height = (x + a) * (x - d) * c + scope.data.end_height;
+ } else {
+ height = (scope.data.end_height - initial_height) * (scope.frame_number / scope.steps) + initial_height
+ }
+ //console.log({x: x,
+ // c: c,
+ // d: d,
+ // a: a,
+ // h: height,
+ // i: initial_height});
+ scope.data.scope.current_scale = 1 / (1 + height);
+ //console.log(scope.data.scope.current_scale);
+ //scope.data.scope.current_scale = 1.0;
+ scope.data.scope.first_channel.send("ScaleChanged", {});
+ scope.data.scope.first_channel.send("ScaleChanged", {});
+ scope.data.scope.updatePanAndScale();
+}
+exports.scale_animation = scale_animation;
+
+function pan_animation (scope) {
+ var incr_x = (scope.data.x2 - scope.data.x1) / scope.steps;
+ var incr_y = (scope.data.y2 - scope.data.y1) / scope.steps;
+ //console.log({incr_x: incr_x, incr_y: incr_y});
+ var v_x = incr_x * scope.frame_number + scope.data.x1;
+ var v_y = incr_y * scope.frame_number + scope.data.y1;
+ var p = scope.data.scope.to_pan(v_x, v_y);
+ //console.log({v_x: v_x, v_y: v_y});
+ //console.log({p_x: p.x, p_y: p.y});
+ //scope.data.scope.panX = scope.data.scope.graph.width/2 - scope.data.scope.current_scale * p.x / 1.0;
+ //scope.data.scope.panY = scope.data.scope.graph.height/2 - scope.data.scope.current_scale * p.y / 1.0;
+ scope.data.scope.panX = p.x + scope.data.scope.graph.width/2;
+ scope.data.scope.panY = p.y + scope.data.scope.graph.height/2;
+ scope.data.scope.first_channel.send("PanChanged", {});
+ scope.data.scope.updatePanAndScale();
+}
+exports.pan_animation = pan_animation;
diff --git a/awx/ui/client/src/network-ui/debug.partial.svg b/awx/ui/client/src/network-ui/debug.partial.svg
index 60ee70aa85..f9816f49a7 100644
--- a/awx/ui/client/src/network-ui/debug.partial.svg
+++ b/awx/ui/client/src/network-ui/debug.partial.svg
@@ -1,7 +1,8 @@
-
+
+
view_port.x: {{view_port.x}}
view_port.y: {{view_port.y}}
view_port.width: {{view_port.width}}
@@ -45,5 +46,16 @@
Inventory Toolbox State: {{inventory_toolbox_controller.state.name}}
Rack Toolbox State: {{rack_toolbox_controller.state.name}}
Site Toolbox State: {{site_toolbox_controller.state.name}}
-
-
+
+
+
+
+
diff --git a/awx/ui/client/src/network-ui/hotkeys.fsm.js b/awx/ui/client/src/network-ui/hotkeys.fsm.js
index 17556054c8..2c310380c6 100644
--- a/awx/ui/client/src/network-ui/hotkeys.fsm.js
+++ b/awx/ui/client/src/network-ui/hotkeys.fsm.js
@@ -77,8 +77,13 @@ _Enabled.prototype.onKeyDown = function(controller, msg_type, $event) {
scope.hide_interfaces = !scope.hide_interfaces;
return;
}
+ if($event.keyCode === 27){
+ // 27 is the escape key
+ scope.reset_fsm_state();
+ return;
+ }
- if ($event.key === 'r') {
+ if ($event.key === 'r' && !($event.ctrlKey || $event.metaKey)) {
scope.first_channel.send("NewDevice", new messages.NewDevice("router"));
return;
}
@@ -103,11 +108,7 @@ _Enabled.prototype.onKeyDown = function(controller, msg_type, $event) {
return;
}
else if ($event.key === '0') {
- scope.panX = 0;
- scope.panY = 0;
- scope.current_scale = 1.0;
- scope.updateScaledXY();
- scope.updatePanAndScale();
+ scope.jump_to_animation(0, 0, 1.0);
}
controller.delegate_channel.send(msg_type, $event);
diff --git a/awx/ui/client/src/network-ui/keybindings.fsm.js b/awx/ui/client/src/network-ui/keybindings.fsm.js
new file mode 100644
index 0000000000..5087b1c5b5
--- /dev/null
+++ b/awx/ui/client/src/network-ui/keybindings.fsm.js
@@ -0,0 +1,59 @@
+var inherits = require('inherits');
+var fsm = require('./fsm.js');
+
+function _State () {
+}
+inherits(_State, fsm._State);
+
+
+function _Disabled () {
+ this.name = 'Disabled';
+}
+inherits(_Disabled, _State);
+var Disabled = new _Disabled();
+exports.Disabled = Disabled;
+
+function _Start () {
+ this.name = 'Start';
+}
+inherits(_Start, _State);
+var Start = new _Start();
+exports.Start = Start;
+
+function _Enabled () {
+ this.name = 'Enabled';
+}
+inherits(_Enabled, _State);
+var Enabled = new _Enabled();
+exports.Enabled = Enabled;
+
+
+
+
+_Disabled.prototype.onBindDocument = function (controller) {
+
+ $(document).bind("keydown", controller.scope.onKeyDown);
+ controller.changeState(Enabled);
+
+};
+_Disabled.prototype.onBindDocument.transitions = ['Enabled'];
+
+
+
+_Start.prototype.start = function (controller) {
+
+ $(document).bind("keydown", controller.scope.onKeyDown);
+ controller.changeState(Enabled);
+
+};
+_Start.prototype.start.transitions = ['Enabled'];
+
+
+
+_Enabled.prototype.onUnbindDocument = function (controller) {
+
+ $(document).unbind("keydown", controller.scope.onKeyDown);
+ controller.changeState(Disabled);
+
+};
+_Enabled.prototype.onUnbindDocument.transitions = ['Disabled'];
diff --git a/awx/ui/client/src/network-ui/mode.fsm.js b/awx/ui/client/src/network-ui/mode.fsm.js
index bf657dd82d..85bfbab285 100644
--- a/awx/ui/client/src/network-ui/mode.fsm.js
+++ b/awx/ui/client/src/network-ui/mode.fsm.js
@@ -88,6 +88,8 @@ _Interface.prototype.onMouseWheel = function (controller, msg_type, $event) {
};
_Interface.prototype.onMouseWheel.transitions = ['Device'];
+_Interface.prototype.onScaleChanged = _Interface.prototype.onMouseWheel;
+
_Site.prototype.start = function (controller) {
controller.scope.current_mode = controller.state.name;
controller.scope.rack_toolbox_controller.handle_message('Enable', {});
@@ -115,6 +117,7 @@ _Site.prototype.onMouseWheel = function (controller, msg_type, $event) {
};
_Site.prototype.onMouseWheel.transitions = ['MultiSite', 'Rack'];
+_Site.prototype.onScaleChanged = _Site.prototype.onMouseWheel;
_Process.prototype.onMouseWheel = function (controller, msg_type, $event) {
@@ -126,6 +129,8 @@ _Process.prototype.onMouseWheel = function (controller, msg_type, $event) {
};
_Process.prototype.onMouseWheel.transitions = ['Device'];
+_Process.prototype.onScaleChanged = _Process.prototype.onMouseWheel;
+
_MultiSite.prototype.start = function (controller) {
controller.scope.current_mode = controller.state.name;
controller.scope.site_toolbox_controller.handle_message('Enable', {});
@@ -149,6 +154,8 @@ _MultiSite.prototype.onMouseWheel = function (controller, msg_type, $event) {
};
_MultiSite.prototype.onMouseWheel.transitions = ['Site'];
+_MultiSite.prototype.onScaleChanged = _MultiSite.prototype.onMouseWheel;
+
_Device.prototype.start = function (controller) {
controller.scope.current_mode = controller.state.name;
controller.scope.app_toolbox_controller.handle_message('Enable', {});
@@ -175,6 +182,7 @@ _Device.prototype.onMouseWheel = function (controller, msg_type, $event) {
};
_Device.prototype.onMouseWheel.transitions = ['Process', 'Interface', 'Rack'];
+_Device.prototype.onScaleChanged = _Device.prototype.onMouseWheel;
_Rack.prototype.start = function (controller) {
controller.scope.current_mode = controller.state.name;
@@ -203,3 +211,5 @@ _Rack.prototype.onMouseWheel = function (controller, msg_type, $event) {
controller.delegate_channel.send(msg_type, $event);
};
_Rack.prototype.onMouseWheel.transitions = ['Site', 'Device'];
+
+_Rack.prototype.onScaleChanged = _Rack.prototype.onMouseWheel;
diff --git a/awx/ui/client/src/network-ui/models.js b/awx/ui/client/src/network-ui/models.js
index be2fd5dd54..df25cc5880 100644
--- a/awx/ui/client/src/network-ui/models.js
+++ b/awx/ui/client/src/network-ui/models.js
@@ -1,8 +1,9 @@
-/* Copyright (c) 2017 Red Hat, Inc. */
+/* Copyright (c) 2017-2018 Red Hat, Inc. */
var fsm = require('./fsm.js');
var button = require('./button.js');
var util = require('./util.js');
var inherits = require('inherits');
+var animation_fsm = require('./animation.fsm.js');
function Device(id, name, x, y, type, host_id) {
this.id = id;
@@ -908,3 +909,18 @@ function TestResult(id, name, result, date, code_under_test) {
this.code_under_test = code_under_test;
}
exports.TestResult = TestResult;
+
+function Animation(id, steps, data, scope, tracer, callback) {
+
+ this.id = id;
+ this.steps = steps;
+ this.active = true;
+ this.frame_number_seq = util.natural_numbers(-1);
+ this.frame_number = 0;
+ this.data = data;
+ this.callback = callback;
+ this.scope = scope;
+ this.interval = null;
+ this.fsm = new fsm.FSMController(this, "animation_fsm", animation_fsm.Start, tracer);
+}
+exports.Animation = Animation;
diff --git a/awx/ui/client/src/network-ui/move.js b/awx/ui/client/src/network-ui/move.js
index d3070d3d9b..41c721289b 100644
--- a/awx/ui/client/src/network-ui/move.js
+++ b/awx/ui/client/src/network-ui/move.js
@@ -139,6 +139,7 @@ _Ready.prototype.onNewDevice = function (controller, msg_type, message) {
device.host_id));
scope.selected_devices.push(device);
device.selected = true;
+ scope.$emit('addSearchOption', device);
controller.changeState(Placing);
}
};
@@ -451,6 +452,7 @@ _EditLabel.prototype.onKeyDown = function (controller, msg_type, $event) {
} else if ($event.keyCode >= 186 && $event.keyCode <=222) { //Punctuation
item.name += $event.key;
} else if ($event.keyCode === 13) { //Enter
+ controller.scope.$emit('editSearchOption', item);
controller.changeState(Selected2);
}
if (item.constructor.name === "Device") {
diff --git a/awx/ui/client/features/networking/_index.less b/awx/ui/client/src/network-ui/network-nav/_index.less
similarity index 97%
rename from awx/ui/client/features/networking/_index.less
rename to awx/ui/client/src/network-ui/network-nav/_index.less
index a7a1dabf3c..a12cddfd9d 100644
--- a/awx/ui/client/features/networking/_index.less
+++ b/awx/ui/client/src/network-ui/network-nav/_index.less
@@ -190,7 +190,14 @@
}
.Networking-searchBarContainer{
- height: 30px
+ height: 30px;
+ flex: 1 0 auto;
+ display: flex;
+ margin-top:-5px;
+}
+
+.Networking-dropDown{
+ left:-2px!important;
}
.Networking-searchButton{
diff --git a/awx/ui/client/features/networking/index.js b/awx/ui/client/src/network-ui/network-nav/index.js
similarity index 82%
rename from awx/ui/client/features/networking/index.js
rename to awx/ui/client/src/network-ui/network-nav/index.js
index 71c20257e9..1a05acfefd 100644
--- a/awx/ui/client/features/networking/index.js
+++ b/awx/ui/client/src/network-ui/network-nav/index.js
@@ -1,9 +1,9 @@
-import NetworkingController from './networking.controller';
-import NetworkingStrings from './networking.strings';
+import NetworkingController from './network.nav.controller';
+import NetworkingStrings from './network.nav.strings';
const MODULE_NAME = 'at.features.networking';
-const networkingTemplate = require('~features/networking/networking.view.html');
+const networkNavTemplate = require('~network-ui/network-nav/network.nav.view.html');
function NetworkingResolve ($stateParams, resourceData) {
const resolve = {
@@ -31,7 +31,7 @@ function NetworkingRun ($stateExtender, strings) {
},
views: {
'networking@': {
- templateUrl: networkingTemplate,
+ templateUrl: networkNavTemplate,
controller: NetworkingController,
controllerAs: 'vm'
}
diff --git a/awx/ui/client/src/network-ui/network-nav/network.nav.controller.js b/awx/ui/client/src/network-ui/network-nav/network.nav.controller.js
new file mode 100644
index 0000000000..88bbc5824e
--- /dev/null
+++ b/awx/ui/client/src/network-ui/network-nav/network.nav.controller.js
@@ -0,0 +1,136 @@
+/* eslint-disable */
+function NetworkingController (models, $state, $scope, strings, CreateSelect2) {
+ const vm = this || {};
+
+ const {
+ inventory
+ } = models;
+
+ vm.strings = strings;
+ vm.panelTitle = `${strings.get('state.BREADCRUMB_LABEL')} | ${inventory.name}`;
+ vm.hostDetail = {};
+
+ vm.rightPanelIsExpanded = false;
+ vm.leftPanelIsExpanded = true;
+ vm.jumpToPanelExpanded = false;
+ vm.keyPanelExpanded = false;
+ $scope.devices = [];
+ // $scope.device = null;
+ vm.close = () => {
+ $state.go('inventories');
+ };
+
+ vm.redirectButtonHandler = (string) => {
+ $scope.$broadcast('toolbarButtonEvent', string);
+ };
+
+ vm.jumpTo = (thing) => {
+ vm.jumpToPanelExpanded = !vm.jumpToPanelExpanded;
+ vm.keyPanelExpanded = false;
+ if (thing && typeof thing === 'string') {
+ $scope.$broadcast('jumpTo', thing);
+ }
+ if (thing && typeof thing === 'object') {
+ $scope.$broadcast('search', thing);
+ }
+ };
+
+ vm.key = () => {
+ vm.keyPanelExpanded = !vm.keyPanelExpanded;
+ vm.jumpToPanelExpanded = false;
+ };
+
+ $scope.$on('overall_toolbox_collapsed', () => {
+ vm.leftPanelIsExpanded = !vm.leftPanelIsExpanded;
+ });
+
+ $scope.$on('closeDetailsPanel', () => {
+ vm.rightPanelIsExpanded = false;
+ vm.jumpToPanelExpanded = false;
+ vm.keyPanelExpanded = false;
+ });
+
+ $scope.$on('showDetails', (e, data, expand) => {
+ if (expand) {
+ vm.rightPanelIsExpanded = true;
+ }
+ if (!_.has(data, 'host_id')) {
+ $scope.item = data;
+ } else {
+ $scope.item = data;
+ }
+ });
+
+ $scope.$on('instatiateSelect', (e, devices) => {
+ for(var i = 0; i < devices.length; i++){
+ let device = devices[i];
+ $scope.devices.push({
+ value: device.id,
+ text: device.name,
+ label: device.name,
+ id: device.id
+ });
+ }
+
+ $("#networking-search").select2({
+ width:'100%',
+ containerCssClass: 'Form-dropDown',
+ placeholder: 'SEARCH'
+ });
+ });
+
+ $scope.$on('addSearchOption', (e, device) => {
+ $scope.devices.push({
+ value: device.id,
+ text: device.name,
+ label: device.name,
+ id: device.id
+ });
+ });
+
+ $scope.$on('editSearchOption', (e, device) => {
+ for(var i = 0; i < $scope.devices.length; i++){
+ if(device.id === $scope.devices[i].id){
+ $scope.devices[i].text = device.name;
+ $scope.devices[i].label = device.name;
+ }
+ }
+ });
+
+ $scope.$on('removeSearchOption', (e, device) => {
+ for (var i = 0; i < $scope.devices.length; i++) {
+ if ($scope.devices[i].id === device.id) {
+ $scope.devices.splice(i, 1);
+ }
+ }
+ });
+
+ $('#networking-search').on('select2:select', (e) => {
+ $scope.$broadcast('search', e.params.data);
+ });
+
+ $('#networking-search').on('select2:open', () => {
+ $('.select2-dropdown').addClass('Networking-dropDown');
+ $scope.$broadcast('unbind');
+ });
+
+ $('#networking-search').on('select2:close', () => {
+ setTimeout(function() {
+ $('.select2-container-active').removeClass('select2-container-active');
+ $(':focus').blur();
+ }, 1);
+ $scope.$broadcast('bind');
+ });
+
+}
+
+NetworkingController.$inject = [
+ 'resolvedModels',
+ '$state',
+ '$scope',
+ 'NetworkingStrings',
+ 'CreateSelect2'
+];
+
+export default NetworkingController;
+/* eslint-disable */
diff --git a/awx/ui/client/features/networking/networking.strings.js b/awx/ui/client/src/network-ui/network-nav/network.nav.strings.js
similarity index 100%
rename from awx/ui/client/features/networking/networking.strings.js
rename to awx/ui/client/src/network-ui/network-nav/network.nav.strings.js
diff --git a/awx/ui/client/features/networking/networking.view.html b/awx/ui/client/src/network-ui/network-nav/network.nav.view.html
similarity index 90%
rename from awx/ui/client/features/networking/networking.view.html
rename to awx/ui/client/src/network-ui/network-nav/network.nav.view.html
index 6d225101c4..4e90642869 100644
--- a/awx/ui/client/features/networking/networking.view.html
+++ b/awx/ui/client/src/network-ui/network-nav/network.nav.view.html
@@ -22,14 +22,13 @@
@@ -144,6 +143,17 @@
+
+
+
+
+
+
+
+
+
{{item.type}} DETAILS NOT AVAILABLE
diff --git a/awx/ui/client/src/network-ui/network.ui.app.js b/awx/ui/client/src/network-ui/network.ui.app.js
index b1caa34156..6590dee7ed 100644
--- a/awx/ui/client/src/network-ui/network.ui.app.js
+++ b/awx/ui/client/src/network-ui/network.ui.app.js
@@ -1,5 +1,7 @@
/* Copyright (c) 2017 Red Hat, Inc. */
+import atFeaturesNetworking from './network-nav/index';
+
//console.log = function () { };
var angular = require('angular');
var NetworkUIController = require('./network.ui.controller.js');
@@ -31,6 +33,7 @@ var awxNetworkUI = require('./network.ui.directive.js');
var networkUI = angular.module('networkUI', [
'monospaced.mousewheel',
+ atFeaturesNetworking
])
.controller('NetworkUIController', NetworkUIController.NetworkUIController)
.directive('awxNetCursor', cursor.cursor)
diff --git a/awx/ui/client/src/network-ui/network.ui.controller.js b/awx/ui/client/src/network-ui/network.ui.controller.js
index b27ce65587..206a8863f9 100644
--- a/awx/ui/client/src/network-ui/network.ui.controller.js
+++ b/awx/ui/client/src/network-ui/network.ui.controller.js
@@ -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 {
+ 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;
diff --git a/awx/ui/client/src/network-ui/network_ui.partial.svg b/awx/ui/client/src/network-ui/network_ui.partial.svg
index 5c1e03981e..b102480a10 100644
--- a/awx/ui/client/src/network-ui/network_ui.partial.svg
+++ b/awx/ui/client/src/network-ui/network_ui.partial.svg
@@ -85,7 +85,7 @@
-
+
diff --git a/awx/ui/client/src/network-ui/quadrants.partial.svg b/awx/ui/client/src/network-ui/quadrants.partial.svg
index e5160bf169..142b733d42 100644
--- a/awx/ui/client/src/network-ui/quadrants.partial.svg
+++ b/awx/ui/client/src/network-ui/quadrants.partial.svg
@@ -1,17 +1,27 @@
-
-
-
+
+
+
+
+
+
+
+
diff --git a/awx/ui/client/src/network-ui/style.less b/awx/ui/client/src/network-ui/style.less
index 9db36896ef..5b4a599df8 100644
--- a/awx/ui/client/src/network-ui/style.less
+++ b/awx/ui/client/src/network-ui/style.less
@@ -1,5 +1,5 @@
/* Copyright (c) 2017 Red Hat, Inc. */
-
+@import 'network-nav/_index';
@font-face {
font-family: 'Open Sans';
font-style: normal;
diff --git a/awx/ui/client/src/network-ui/view.js b/awx/ui/client/src/network-ui/view.js
index 24cfdd7bab..4c39e8754b 100644
--- a/awx/ui/client/src/network-ui/view.js
+++ b/awx/ui/client/src/network-ui/view.js
@@ -50,7 +50,7 @@ _Ready.prototype.onMouseDown = function (controller) {
controller.scope.pressedY = controller.scope.mouseY;
controller.scope.lastPanX = controller.scope.panX;
controller.scope.lastPanY = controller.scope.panY;
- controller.scope.$emit('closeDetailsPanel');
+ controller.scope.closeDetailsPanel();
controller.changeState(Pressed);
};