diff --git a/awx/network_ui/designs/details_panel.png b/awx/network_ui/designs/details_panel.png new file mode 100644 index 0000000000..d060f3bd2f Binary files /dev/null and b/awx/network_ui/designs/details_panel.png differ diff --git a/awx/network_ui/designs/details_panel.yml b/awx/network_ui/designs/details_panel.yml new file mode 100644 index 0000000000..adbd2548a2 --- /dev/null +++ b/awx/network_ui/designs/details_panel.yml @@ -0,0 +1,25 @@ +diagram_id: 70 +name: diagram +states: +- id: 1 + label: Start + x: 590 + y: 233 +- id: 2 + label: Collapsed + x: 594 + y: 490 +- id: 3 + label: Expanded + x: 919 + y: 491 +transitions: +- from_state: Start + label: start + to_state: Collapsed +- from_state: Expanded + label: onDetailsPanelClose + to_state: Collapsed +- from_state: Collapsed + label: onDetailsPanel + to_state: Expanded diff --git a/awx/network_ui/designs/keybindings.png b/awx/network_ui/designs/keybindings.png index e54b652211..b6a0b89a19 100644 Binary files a/awx/network_ui/designs/keybindings.png 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 index 11ce6fa212..b3fb17e1a3 100644 --- a/awx/network_ui/designs/keybindings.yml +++ b/awx/network_ui/designs/keybindings.yml @@ -1,7 +1,7 @@ -diagram_id: 60 +diagram_id: 68 name: diagram states: -- id: 3 +- id: 1 label: Enabled x: 842 y: 533 @@ -9,10 +9,10 @@ states: label: Start x: 839 y: 270 -- id: 6 +- id: 3 label: Disabled - x: 1231 - y: 532 + x: 1412 + y: 522 transitions: - from_state: Start label: start @@ -23,3 +23,15 @@ transitions: - from_state: Enabled label: onUnbindDocument to_state: Disabled +- from_state: Disabled + label: onDetailsPanelClose + to_state: Enabled +- from_state: Enabled + label: onDetailsPanel + to_state: Disabled +- from_state: Enabled + label: onSearchDropdown + to_state: Disabled +- from_state: Disabled + label: onSearchDropdownClose + to_state: Enabled diff --git a/awx/network_ui/static/network_ui/designs/move.png b/awx/network_ui/static/network_ui/designs/move.png index 04eb438255..1f27444aaf 100644 Binary files a/awx/network_ui/static/network_ui/designs/move.png and b/awx/network_ui/static/network_ui/designs/move.png differ diff --git a/awx/network_ui/static/network_ui/designs/move.yml b/awx/network_ui/static/network_ui/designs/move.yml index 03d83d72bf..935bcbf521 100644 --- a/awx/network_ui/static/network_ui/designs/move.yml +++ b/awx/network_ui/static/network_ui/designs/move.yml @@ -1,94 +1,107 @@ -finite_state_machine_id: 13 -name: move_fsm +diagram_id: 64 +name: move states: -- id: 9 +- id: 1 label: Disable x: 743 y: 108 -- id: 1 +- id: 2 label: Start x: 533 y: 121 -- id: 2 +- id: 3 label: Ready x: 531 y: 320 -- id: 3 +- id: 4 label: Selected1 x: 226 y: 325 -- id: 4 - label: Selected2 - x: 230 - y: 582 -- id: 5 +- id: 6 label: Move x: -54 y: 587 -- id: 6 - label: EditLabel - x: 566 - y: 677 -- id: 7 - label: Selected3 - x: 175 - y: 886 - id: 8 label: Placing x: 92 y: 82 +- id: 9 + label: EditLabel + x: 594 + y: 677 +- id: 5 + label: Selected2 + x: 275 + y: 682 +- id: 10 + label: ContextMenu + x: 901 + y: 990 +- id: 7 + label: Selected3 + x: 190 + y: 954 transitions: -- from_state: Selected2 - label: onKeyDown - to_state: Ready -- from_state: Selected2 - label: onNewDevice - to_state: Ready -- from_state: EditLabel - label: onMouseDown - to_state: Ready -- from_state: Selected2 +- from_state: ContextMenu + label: onDetailsPanel + to_state: Selected2 +- from_state: ContextMenu label: onMouseDown to_state: Ready - from_state: Start label: start to_state: Ready -- from_state: Move +- from_state: Selected2 label: onMouseDown - to_state: Selected1 -- from_state: Placing + to_state: Ready +- from_state: EditLabel + label: onMouseDown + to_state: Ready +- from_state: Selected2 + label: onNewDevice + to_state: Ready +- from_state: Selected2 + label: onKeyDown + to_state: Ready +- from_state: Ready label: onMouseDown to_state: Selected1 - from_state: Move label: onMouseUp to_state: Selected1 -- from_state: Ready +- from_state: Placing label: onMouseDown to_state: Selected1 -- from_state: Ready - label: onPasteDevice +- from_state: Move + label: onMouseDown + to_state: Selected1 +- from_state: Selected1 + label: onMouseUp to_state: Selected2 - from_state: EditLabel label: onKeyDown to_state: Selected2 -- from_state: Selected1 - label: onMouseUp +- from_state: Ready + label: onPasteDevice to_state: Selected2 +- from_state: Selected1 + label: onMouseMove + to_state: Move +- from_state: Selected3 + label: onMouseMove + to_state: Move - from_state: Placing label: onMouseMove to_state: Move -- from_state: Selected3 - label: onMouseMove - to_state: Move -- from_state: Selected1 - label: onMouseMove - to_state: Move -- from_state: Selected3 - label: onMouseUp - to_state: EditLabel - from_state: Selected2 label: onMouseDown to_state: Selected3 - from_state: Ready label: onNewDevice to_state: Placing +- from_state: ContextMenu + label: onLabelEdit + to_state: EditLabel +- from_state: Selected3 + label: onMouseUp + to_state: ContextMenu diff --git a/awx/ui/client/src/network-ui/animations.js b/awx/ui/client/src/network-ui/animations.js index b5caee6b3d..4f2b3ec51f 100644 --- a/awx/ui/client/src/network-ui/animations.js +++ b/awx/ui/client/src/network-ui/animations.js @@ -29,6 +29,7 @@ function scale_animation (scope) { scope.data.scope.first_channel.send("ScaleChanged", {}); scope.data.scope.first_channel.send("ScaleChanged", {}); scope.data.scope.updatePanAndScale(); + scope.data.scope.$emit('awxNet-UpdateZoomWidget', scope.data.scope.current_scale, scope.data.updateZoomBoolean); } exports.scale_animation = scale_animation; diff --git a/awx/ui/client/src/network-ui/details.panel.fsm.js b/awx/ui/client/src/network-ui/details.panel.fsm.js new file mode 100644 index 0000000000..007057460a --- /dev/null +++ b/awx/ui/client/src/network-ui/details.panel.fsm.js @@ -0,0 +1,63 @@ +var inherits = require('inherits'); +var fsm = require('./fsm.js'); + +function _State () { +} +inherits(_State, fsm._State); + + +function _Start () { + this.name = 'Start'; +} +inherits(_Start, _State); +var Start = new _Start(); +exports.Start = Start; + +function _Collapsed () { + this.name = 'Collapsed'; +} +inherits(_Collapsed, _State); +var Collapsed = new _Collapsed(); +exports.Collapsed = Collapsed; + +function _Expanded () { + this.name = 'Expanded'; +} +inherits(_Expanded, _State); +var Expanded = new _Expanded(); +exports.Expanded = Expanded; + + + + +_Start.prototype.start = function (controller, msg_type, $event) { + + controller.scope.$parent.vm.rightPanelIsExpanded = false; + controller.changeState(Collapsed); + controller.handle_message(msg_type, $event); + +}; +_Start.prototype.start.transitions = ['Collapsed']; + + + +_Collapsed.prototype.onDetailsPanel = function (controller, msg_type, $event) { + + controller.scope.$parent.vm.rightPanelIsExpanded = true; + controller.changeState(Expanded); + controller.handle_message(msg_type, $event); + +}; +_Collapsed.prototype.onDetailsPanel.transitions = ['Expanded']; + + + +_Expanded.prototype.onDetailsPanelClose = function (controller, msg_type, $event) { + + controller.scope.$parent.vm.rightPanelIsExpanded = false; + controller.scope.$parent.vm.jumpToPanelExpanded = false; + controller.scope.$parent.vm.keyPanelExpanded = false; + controller.changeState(Collapsed); + controller.handle_message(msg_type, $event); +}; +_Expanded.prototype.onDetailsPanelClose.transitions = ['Collapsed']; diff --git a/awx/ui/client/src/network-ui/host.partial.svg b/awx/ui/client/src/network-ui/host.partial.svg index 6faefc2504..212e71b3d3 100644 --- a/awx/ui/client/src/network-ui/host.partial.svg +++ b/awx/ui/client/src/network-ui/host.partial.svg @@ -1,89 +1,91 @@ - - - - - - + + + + + + + - - - - - + + + + + - - - - - + + + + + - - - - + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + + + {{item.name}} + + {{item.name}}{{item.edit_label?'_':''}} - - {{item.name}} - - {{item.name}}{{item.edit_label?'_':''}} - diff --git a/awx/ui/client/src/network-ui/keybindings.fsm.js b/awx/ui/client/src/network-ui/keybindings.fsm.js index 5087b1c5b5..3e9fcd8ee4 100644 --- a/awx/ui/client/src/network-ui/keybindings.fsm.js +++ b/awx/ui/client/src/network-ui/keybindings.fsm.js @@ -57,3 +57,37 @@ _Enabled.prototype.onUnbindDocument = function (controller) { }; _Enabled.prototype.onUnbindDocument.transitions = ['Disabled']; + +_Disabled.prototype.onDetailsPanelClose = function (controller) { + + $(document).bind("keydown", controller.scope.onKeyDown); + controller.changeState(Enabled); + +}; +_Disabled.prototype.onDetailsPanelClose.transitions = ['Enabled']; + +_Disabled.prototype.onSearchDropdownClose = function (controller) { + + $(document).bind("keydown", controller.scope.onKeyDown); + controller.changeState(Enabled); + +}; +_Disabled.prototype.onSearchDropdownClose.transitions = ['Enabled']; + + + +_Enabled.prototype.onDetailsPanel = function (controller) { + + $(document).unbind("keydown", controller.scope.onKeyDown); + controller.changeState(Disabled); + +}; +_Enabled.prototype.onDetailsPanel.transitions = ['Disabled']; + +_Enabled.prototype.onSearchDropdown = function (controller) { + + $(document).unbind("keydown", controller.scope.onKeyDown); + controller.changeState(Disabled); + +}; +_Enabled.prototype.onSearchDropdown.transitions = ['Disabled']; diff --git a/awx/ui/client/src/network-ui/models.js b/awx/ui/client/src/network-ui/models.js index df25cc5880..b1dc9e4bfc 100644 --- a/awx/ui/client/src/network-ui/models.js +++ b/awx/ui/client/src/network-ui/models.js @@ -28,6 +28,7 @@ function Device(id, name, x, y, type, host_id) { this.interfaces = []; this.process_id_seq = util.natural_numbers(0); this.processes = []; + this.in_group = false; } exports.Device = Device; @@ -640,6 +641,7 @@ Group.prototype.update_membership = function (devices, groups) { devices[i].y > y1 && devices[i].x < x2 && devices[i].y < y2) { + devices[i].in_group = true; this.devices.push(devices[i]); device_ids.push(devices[i].id); } @@ -918,6 +920,7 @@ function Animation(id, steps, data, scope, tracer, callback) { this.frame_number_seq = util.natural_numbers(-1); this.frame_number = 0; this.data = data; + this.data.updateZoomBoolean = data.updateZoomBoolean !== undefined ? data.updateZoomBoolean : true; this.callback = callback; this.scope = scope; this.interval = null; diff --git a/awx/ui/client/src/network-ui/move.js b/awx/ui/client/src/network-ui/move.js index 41c721289b..b8b485af1c 100644 --- a/awx/ui/client/src/network-ui/move.js +++ b/awx/ui/client/src/network-ui/move.js @@ -208,13 +208,10 @@ _Ready.prototype.onMouseDown = function (controller, msg_type, $event) { if (last_selected.last_selected_device !== null) { controller.changeState(Selected1); - controller.scope.onDetailsContextButton(); } else if (last_selected.last_selected_link !== null) { controller.changeState(Selected1); - controller.scope.onDetailsContextButton(); } else if (last_selected.last_selected_interface !== null) { controller.changeState(Selected1); - controller.scope.onDetailsContextButton(); } else { controller.delegate_channel.send(msg_type, $event); } @@ -289,7 +286,7 @@ _Selected2.prototype.onMouseDown = function (controller, msg_type, $event) { return; } } - + controller.scope.first_channel.send('BindDocument', {}); controller.changeState(Ready); controller.handle_message(msg_type, $event); }; @@ -315,6 +312,9 @@ _Selected1.prototype.onMouseMove.transitions = ['Move']; _Selected1.prototype.onMouseUp = function (controller) { + if(controller.scope.$parent.vm.rightPanelIsExpanded){ + controller.scope.onDetailsContextButton(); + } controller.changeState(Selected2); }; @@ -511,3 +511,10 @@ _ContextMenu.prototype.onMouseDown = function (controller) { }; _ContextMenu.prototype.onMouseDown.transitions = ['Ready']; + +_ContextMenu.prototype.onDetailsPanel = function (controller, msg_type, $event) { + + controller.changeState(Selected2); + controller.handle_message(msg_type, $event); +}; +_ContextMenu.prototype.onDetailsPanel.transitions = ['Selected2']; diff --git a/awx/ui/client/src/network-ui/network-details/details.block.less b/awx/ui/client/src/network-ui/network-details/details.block.less new file mode 100644 index 0000000000..802e67fd3e --- /dev/null +++ b/awx/ui/client/src/network-ui/network-details/details.block.less @@ -0,0 +1,29 @@ +.Networking-panelHeader { + display: flex; + height: 30px; + width:100%; +} + +.Networking-panelHeaderText { + color: @default-interface-txt; + flex: 1 0 auto; + font-size: 14px; + font-weight: bold; + margin-right: 10px; + text-transform: uppercase; +} + +.Networking-noItems{ + margin-top: 0px; +} + +.Networking-form{ + font-weight: normal; +} + +.Networking-saveConfirmation{ + font-weight: normal; + color: @default-succ; + text-align: right; + margin-top:15px; +} diff --git a/awx/ui/client/src/network-ui/network-details/details.controller.js b/awx/ui/client/src/network-ui/network-details/details.controller.js new file mode 100644 index 0000000000..c00f407096 --- /dev/null +++ b/awx/ui/client/src/network-ui/network-details/details.controller.js @@ -0,0 +1,92 @@ +/************************************************* + * Copyright (c) 2016 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + + export default + ['$scope', '$state', '$stateParams', 'GenerateForm', 'ParseTypeChange', 'HostsService', '$rootScope', + function($scope, $state, $stateParams, GenerateForm, ParseTypeChange, HostsService, $rootScope){ + + $scope.parseType = 'yaml'; + $scope.formCancel = function(){ + $scope.$parent.$$childTail.closeDetailsPanel(); + }; + + $scope.formSave = function(){ + var host = { + id: $scope.item.id, + variables: $scope.variables === '---' || $scope.variables === '{}' ? null : $scope.variables, + name: $scope.item.name, + description: $scope.item.description, + enabled: $scope.item.enabled + }; + HostsService.put(host).then(function(response){ + $scope.saveConfirmed = true; + if(_.has(response, "data")){ + $scope.$parent.$broadcast('hostUpdateSaved', response.data); + } + setTimeout(function(){ + $scope.saveConfirmed = false; + }, 3000); + }); + + }; + + $scope.$parent.$on('showDetails', (e, data, canAdd) => { + if (!_.has(data, 'host_id')) { + $scope.item = data; + $scope.canAdd = canAdd; + } else { + $scope.item = data; + } + }); + + $scope.$watch('item', function(){ + init(); + }); + + var init = function(){ + if($scope.item && $scope.item.host_id){ + $scope.variables = getVars($scope.item.variables); + ParseTypeChange({ + scope: $scope, + field_id: 'network_host_variables', + variable: 'variables', + }); + } + + }; + + // Adding this function b/c sometimes extra vars are returned to the + // UI as a string (ex: "foo: bar"), and other times as a + // json-object-string (ex: "{"foo": "bar"}"). CodeMirror wouldn't know + // how to prettify the latter. The latter occurs when host vars were + // system generated and not user-input (such as adding a cloud host); + function getVars(str){ + + // Quick function to test if the host vars are a json-object-string, + // by testing if they can be converted to a JSON object w/o error. + function IsJsonString(str) { + try { + JSON.parse(str); + } catch (e) { + return false; + } + return true; + } + + if(str === ''){ + return '---'; + } + else if(IsJsonString(str)){ + str = JSON.parse(str); + return jsyaml.safeDump(str); + } + else if(!IsJsonString(str)){ + return str; + } + } + + // init(); + }]; diff --git a/awx/ui/client/src/network-ui/network-details/details.directive.js b/awx/ui/client/src/network-ui/network-details/details.directive.js new file mode 100644 index 0000000000..d05f364390 --- /dev/null +++ b/awx/ui/client/src/network-ui/network-details/details.directive.js @@ -0,0 +1,22 @@ +/************************************************* + * Copyright (c) 2018 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +import detailsController from './details.controller'; + +const templateUrl = require('~network-ui/network-details/details.partial.html'); + +export default [ + function() { + return { + scope:{ + item: "=", + canAdd: '@' + }, + templateUrl, + controller: detailsController, + restrict: 'E', + }; +}]; diff --git a/awx/ui/client/src/network-ui/network-details/details.partial.html b/awx/ui/client/src/network-ui/network-details/details.partial.html new file mode 100644 index 0000000000..09622950d0 --- /dev/null +++ b/awx/ui/client/src/network-ui/network-details/details.partial.html @@ -0,0 +1,66 @@ +
+
+ DETAILS | {{item.name}} +
+
+ +
+ {{item.type}} DETAILS NOT AVAILABLE +
+ +
+
+
+ +
+ +
Please enter a value.
+
+
+
+
+ +
+ +
+
+
+
+ + +
+
+
+ + + +
+
+ Save Complete +
+
diff --git a/awx/ui/client/src/network-ui/network-details/main.js b/awx/ui/client/src/network-ui/network-details/main.js new file mode 100644 index 0000000000..ffa06f41e4 --- /dev/null +++ b/awx/ui/client/src/network-ui/network-details/main.js @@ -0,0 +1,11 @@ +/************************************************* + * Copyright (c) 2018 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +import awxNetDetailsPanel from './details.directive'; + +export default + angular.module('networkDetailsDirective', []) + .directive('awxNetDetailsPanel', awxNetDetailsPanel); diff --git a/awx/ui/client/src/network-ui/network-nav/index.js b/awx/ui/client/src/network-ui/network-nav/main.js similarity index 100% rename from awx/ui/client/src/network-ui/network-nav/index.js rename to awx/ui/client/src/network-ui/network-nav/main.js diff --git a/awx/ui/client/src/network-ui/network-nav/_index.less b/awx/ui/client/src/network-ui/network-nav/network.nav.block.less similarity index 85% rename from awx/ui/client/src/network-ui/network-nav/_index.less rename to awx/ui/client/src/network-ui/network-nav/network.nav.block.less index a12cddfd9d..eb89a3366b 100644 --- a/awx/ui/client/src/network-ui/network-nav/_index.less +++ b/awx/ui/client/src/network-ui/network-nav/network.nav.block.less @@ -87,38 +87,6 @@ right:0px; } - -.Networking-panelHeader { - display: flex; - height: 30px; - width:100%; -} - -.Networking-panelHeaderText { - color: @default-interface-txt; - flex: 1 0 auto; - font-size: 14px; - font-weight: bold; - margin-right: 10px; - text-transform: uppercase; -} - -.Networking-resultRowLabel{ - width: initial; -} - -.Networking-resultRow--variables { - flex-direction: column; - - #cm-variables-container { - width: 100%; - } -} - -.Networking-noItems{ - margin-top: 0px; -} - .Networking-toolbar{ min-height: 40px; width:100%; @@ -139,22 +107,18 @@ .Networking-breadCrumbText{ color:@default-link; + text-transform: uppercase; + font-size: 14px; } -.Networking-toolbarLeftSide--expanded{ - width: calc(~"100% - 201px"); - // margin-left:201px; - left:201px; +.Networking-breadCrumbSlash{ + padding: 0px 10px 0px 10px; + color: #707070; } -.Networking-toolbarBothPanels--expanded{ - width: calc(~"100% - 601px"); - // margin-right:400px; - left:201px; -} - -.Networking-toolbarRightSide--expanded{ - width: calc(~"100% - 445px"); +.Networking-breadCrumbText--last{ + color: #707070; + text-transform: none; } .Networking-toolbarButton{ 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 index 88bbc5824e..d3b5072938 100644 --- 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 @@ -15,7 +15,6 @@ function NetworkingController (models, $state, $scope, strings, CreateSelect2) { vm.jumpToPanelExpanded = false; vm.keyPanelExpanded = false; $scope.devices = []; - // $scope.device = null; vm.close = () => { $state.go('inventories'); }; @@ -44,23 +43,6 @@ function NetworkingController (models, $state, $scope, strings, CreateSelect2) { 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]; @@ -68,7 +50,8 @@ function NetworkingController (models, $state, $scope, strings, CreateSelect2) { value: device.id, text: device.name, label: device.name, - id: device.id + id: device.id, + type: device.type }); } @@ -106,12 +89,12 @@ function NetworkingController (models, $state, $scope, strings, CreateSelect2) { }); $('#networking-search').on('select2:select', (e) => { - $scope.$broadcast('search', e.params.data); + $scope.$broadcast('search', $scope.device); }); $('#networking-search').on('select2:open', () => { $('.select2-dropdown').addClass('Networking-dropDown'); - $scope.$broadcast('unbind'); + $scope.$broadcast('SearchDropdown'); }); $('#networking-search').on('select2:close', () => { @@ -119,7 +102,7 @@ function NetworkingController (models, $state, $scope, strings, CreateSelect2) { $('.select2-container-active').removeClass('select2-container-active'); $(':focus').blur(); }, 1); - $scope.$broadcast('bind'); + $scope.$broadcast('SearchDropdownClose'); }); } diff --git a/awx/ui/client/src/network-ui/network-nav/network.nav.view.html b/awx/ui/client/src/network-ui/network-nav/network.nav.view.html index 4e90642869..e9e1a1bb34 100644 --- a/awx/ui/client/src/network-ui/network-nav/network.nav.view.html +++ b/awx/ui/client/src/network-ui/network-nav/network.nav.view.html @@ -23,12 +23,12 @@
- + - - -
-
+
Foo
/
+
Bar
/
+
Bread
/
+
crumb
-
- -
-
- DETAILS | {{item.name}} -
-
- - - -
- -
- {{item.name}} -
-
- - - -
- - - - -
- - -
- {{item.type}} DETAILS NOT AVAILABLE -
- - -
- - -
- -
- - + +
- - - +
+ +