From 1b7e9167ec5b67b09357e4efeae3c62f8d117651 Mon Sep 17 00:00:00 2001 From: Chris Houseknecht Date: Wed, 9 Apr 2014 12:04:34 -0400 Subject: [PATCH] Cleanup of 'loading' and 'no records matching your search'. Removed 'group' from group host status messages. Fixed conflict between group edit and host edit dialogs that caused variable editor to sometimes not display on host edit. --- awx/ui/static/js/helpers/Groups.js | 159 +++++++++++++++++---- awx/ui/static/js/helpers/Hosts.js | 31 ++-- awx/ui/static/js/helpers/refresh.js | 6 +- awx/ui/static/less/ansible-ui.less | 6 +- awx/ui/static/lib/ansible/InventoryTree.js | 5 +- awx/ui/static/lib/ansible/Modal.js | 6 + awx/ui/static/partials/inventory-edit.html | 53 +++++++ 7 files changed, 219 insertions(+), 47 deletions(-) diff --git a/awx/ui/static/js/helpers/Groups.js b/awx/ui/static/js/helpers/Groups.js index 20a1034dac..57c23472d5 100644 --- a/awx/ui/static/js/helpers/Groups.js +++ b/awx/ui/static/js/helpers/Groups.js @@ -789,6 +789,11 @@ function($compile, SchedulerInit, Rest, Wait, SetSchedulesInnerDialogSize, Sched if (sources_scope.codeMirror) { sources_scope.codeMirror.destroy(); } + $('#properties-tab').empty(); + $('#sources-tab').empty(); + $('#schedules-list').empty(); + $('#schedules-form').empty(); + $('#schedules-detail').empty(); $('#group-modal-dialog').hide(); $('#group-modal-dialog').dialog('destroy'); modal_scope.cancelModal(); @@ -1265,45 +1270,149 @@ function($compile, SchedulerInit, Rest, Wait, SetSchedulesInnerDialogSize, Sched .factory('GroupsDelete', ['$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'GroupForm', 'GenerateForm', - 'Prompt', 'ProcessErrors', 'GetBasePath', 'Wait', 'BuildTree', 'Find', + 'Prompt', 'ProcessErrors', 'GetBasePath', 'Wait', 'BuildTree', 'Find', 'CreateDialog', function ($rootScope, $location, $log, $routeParams, Rest, Alert, GroupForm, GenerateForm, Prompt, ProcessErrors, - GetBasePath, Wait, BuildTree, Find) { + GetBasePath, Wait, BuildTree, Find, CreateDialog) { return function (params) { // Delete the selected group node. Disassociates it from its parent. var scope = params.scope, tree_id = params.tree_id, - inventory_id = params.inventory_id, node = Find({ list: scope.groups, key: 'id', val: tree_id }), - url = GetBasePath('inventory') + inventory_id + '/groups/', - action_to_take; + hosts = [], + groups = [], + childCount = 0, + buttonSet; - action_to_take = function () { - $('#prompt-modal').on('hidden.bs.modal', function () { - Wait('start'); + // action_to_take = function () { + // $('#prompt-modal').on('hidden.bs.modal', function () { + // Wait('start'); + // }); + // $('#prompt-modal').modal('hide'); + // Rest.setUrl(url); + // Rest.post({ id: node.group_id, disassociate: 1 }) + // .success(function () { + // $('#prompt-modal').modal('hide'); + // scope.$emit('GroupDeleteCompleted'); // Signal a group refresh to start + // }) + // .error(function (data, status) { + // Wait('stop'); + // ProcessErrors(scope, data, status, null, { + // hdr: 'Error!', + // msg: 'Call to ' + url + ' failed. POST returned status: ' + status + // }); + // }); + // }; + + scope.deleteOption = "preserve-all"; + + buttonSet = [{ + label: "Cancel", + onClick: function() { + scope.cancel(); + }, + icon: "fa-times", + "class": "btn btn-default", + "id": "group-delete-cancel-button" + },{ + label: "Continue", + onClick: function() { + scope.performDelete(); + }, + icon: "fa-check", + "class": "btn btn-primary", + "id": "group-delete-ok-button" + }]; + + if (scope.removeDeleteDialogReady) { + scope.removeDeleteDialogReady(); + } + scope.removeDeleteDialogReady = scope.$on('DeleteDialogReady', function() { + Wait('stop'); + $('#group-delete-dialog').dialog('open'); + }); + + if (scope.removeShowDeleteDialog) { + scope.removeShowDeleteDialog(); + } + scope.removeShowDeleteDialog = scope.$on('ShowDeleteDialog', function() { + scope.group_name = node.name; + scope.groupsCount = groups.length; + scope.hostsCount = hosts.length; + CreateDialog({ + id: 'group-delete-dialog', + scope: scope, + buttons: buttonSet, + width: 650, + height: 350, + minWidth: 500, + title: 'Delete Group', + callback: 'DeleteDialogReady' }); - $('#prompt-modal').modal('hide'); - Rest.setUrl(url); - Rest.post({ id: node.group_id, disassociate: 1 }) - .success(function () { - $('#prompt-modal').modal('hide'); - scope.$emit('GroupDeleteCompleted'); // Signal a group refresh to start + }); + + if (scope.removeChildrenReady) { + scope.removeChildrenReady(); + } + scope.removeChildrenReady = scope.$on('ChildrenReady', function() { + childCount++; + if (childCount === 2) { + scope.$emit('ShowDeleteDialog'); + } + }); + + Wait('start'); + + if (node.related.children) { + Rest.setUrl(node.related.children); + Rest.get() + .success(function(data) { + if (data.count) { + data.results.forEach(function(group) { + groups.push(group); + }); + } + scope.$emit('ChildrenReady'); }) - .error(function (data, status) { - Wait('stop'); - ProcessErrors(scope, data, status, null, { - hdr: 'Error!', - msg: 'Call to ' + url + ' failed. POST returned status: ' + status + .error(function(data, status) { + ProcessErrors(scope, data, status, null, { hdr: 'Error!', + msg: 'Failed to retrieve related groups. GET returned: ' + status }); }); + } + else { + scope.$emit('ChildrenReady'); + } + + if (node.related.all_hosts) { + Rest.setUrl(node.related.all_hosts); + Rest.get() + .success( function(data) { + if (data.count) { + data.results.forEach(function(host) { + hosts.push(host); + }); + } + scope.$emit('ChildrenReady'); + }) + .error( function(data, status) { + ProcessErrors(scope, data, status, null, { hdr: 'Error!', + msg: 'Failed to retrieve related hosts. GET returned: ' + status + }); + }); + } + else { + scope.$emit('ChildrenReady'); + } + + scope.cancel = function() { + $('#group-delete-dialog').dialog('close'); + }; + + scope.performDelete = function() { + $('#group-delete-dialog').dialog('close'); }; - Prompt({ - hdr: 'Delete Group', - body: '
Are you sure you want to delete group ' + node.name + '?
', - action: action_to_take, - 'class': 'btn-danger' - }); }; } ]) diff --git a/awx/ui/static/js/helpers/Hosts.js b/awx/ui/static/js/helpers/Hosts.js index 7fdb7127f6..3c33eaa566 100644 --- a/awx/ui/static/js/helpers/Hosts.js +++ b/awx/ui/static/js/helpers/Hosts.js @@ -498,28 +498,35 @@ function($rootScope, $location, $log, $routeParams, Rest, Alert, HostForm, Gener formId: 'host_form' }); }, + beforeDestroy: function() { + if (scope.codeMirror) { + scope.codeMirror.destroy(); + } + $('#host-modal-dialog').empty(); + }, onOpen: function() { $('#host_name').focus(); - setTimeout(function() { - TextareaResize({ - scope: scope, - textareaId: 'host_variables', - modalId: 'host-modal-dialog', - formId: 'host_form' - }); - }, 300); - } + }, + callback: 'HostEditDialogReady' }); scope.parseType = 'yaml'; - + if (scope.hostVariablesLoadedRemove) { scope.hostVariablesLoadedRemove(); } scope.hostVariablesLoadedRemove = scope.$on('hostVariablesLoaded', function() { - var callback = function() { Wait('stop'); }; $('#host-modal-dialog').dialog('open'); - ParseTypeChange({ scope: scope, field_id: 'host_variables', onReady: callback }); + setTimeout(function() { + TextareaResize({ + scope: scope, + textareaId: 'host_variables', + modalId: 'host-modal-dialog', + formId: 'host_form', + parse: true + }); + }, 300); + //ParseTypeChange({ scope: scope, field_id: 'host_variables', onReady: callback }); }); if (scope.hostLoadedRemove) { diff --git a/awx/ui/static/js/helpers/refresh.js b/awx/ui/static/js/helpers/refresh.js index 54339c5076..203e4bfe84 100644 --- a/awx/ui/static/js/helpers/refresh.js +++ b/awx/ui/static/js/helpers/refresh.js @@ -25,7 +25,8 @@ angular.module('RefreshHelper', ['RestServices', 'Utilities', 'PaginationHelpers set = params.set, iterator = params.iterator, url = params.url; - + + scope[iterator + 'Loading'] = true; scope.current_url = url; Rest.setUrl(url); Rest.get() @@ -38,13 +39,12 @@ angular.module('RefreshHelper', ['RestServices', 'Utilities', 'PaginationHelpers previous: data.previous, iterator: iterator }); - scope[iterator + 'Loading'] = false; for (i = 1; i <= 3; i++) { modifier = (i === 1) ? '' : i; scope[iterator + 'HoldInput' + modifier] = false; } scope[set] = data.results; - //window.scrollTo(0, 0); + scope[iterator + 'Loading'] = false; Wait('stop'); scope.$emit('PostRefresh'); }) diff --git a/awx/ui/static/less/ansible-ui.less b/awx/ui/static/less/ansible-ui.less index fb17e9d192..5c8313bf8a 100644 --- a/awx/ui/static/less/ansible-ui.less +++ b/awx/ui/static/less/ansible-ui.less @@ -942,9 +942,9 @@ input[type="checkbox"].checkbox-no-label { /* Table info rows */ .loading-info { - color: @grey-txt; - font-weight: bold; - padding: 15px 0; + color: @grey-txt; + font-weight: normal; + padding: 15px 0; } /* Jobs pages */ diff --git a/awx/ui/static/lib/ansible/InventoryTree.js b/awx/ui/static/lib/ansible/InventoryTree.js index ac9a8173e8..7da0fa6675 100644 --- a/awx/ui/static/lib/ansible/InventoryTree.js +++ b/awx/ui/static/lib/ansible/InventoryTree.js @@ -116,10 +116,7 @@ angular.module('InventoryTree', ['Utilities', 'RestServices', 'GroupsHelper', 'P event_level: level, children: children, ngicon: (sorted[i].children.length > 0) ? 'fa fa-minus-square-o node-toggle' : 'fa fa-square-o node-no-toggle', - related: { - children: (sorted[i].children.length > 0) ? sorted[i].related.children : '', - inventory_source: sorted[i].related.inventory_source - }, + related: sorted[i].related, status: sorted[i].summary_fields.inventory_source.status, status_class: stat['class'], status_tooltip: stat.tooltip, diff --git a/awx/ui/static/lib/ansible/Modal.js b/awx/ui/static/lib/ansible/Modal.js index 66f680e445..80eed2950e 100644 --- a/awx/ui/static/lib/ansible/Modal.js +++ b/awx/ui/static/lib/ansible/Modal.js @@ -26,6 +26,7 @@ angular.module('ModalDialog', ['Utilities', 'ParseHelper']) * onResizeStop: - Function to call when user stops resizing the dialog, optional * onClose: - Function to call after window closes, optional * onOpen: - Function to call after window opens, optional + * beforeDestroy: - Function to call during onClose and prior to destroying the window * callback: - String to pass to scope.$emit() after dialog is created, optional * }) * @@ -46,6 +47,7 @@ angular.module('ModalDialog', ['Utilities', 'ParseHelper']) onClose = params.onClose, onOpen = params.onOpen, callback = params.callback, + beforeDestroy = params.beforeDestroy, closeOnEscape = (params.closeOnEscape === undefined) ? false : params.closeOnEscape, buttons, id = params.id, @@ -132,6 +134,9 @@ angular.module('ModalDialog', ['Utilities', 'ParseHelper']) // remove lingering popover
elements $(this).remove(); }); + if (beforeDestroy) { + beforeDestroy(); + } $('#' + id).dialog('destroy'); $('#' + id).hide(); if (onClose) { @@ -161,6 +166,7 @@ angular.module('ModalDialog', ['Utilities', 'ParseHelper']) * textareaId: - id attribute value of the textarea * modalId: - id attribute of the
element used to create the modal * formId: - id attribute of the textarea's parent form + * parse: - if true, call ParseTypeChange and replace textarea with codemirror editor * }) * * Use to resize a textarea field contained on a modal. Has only been tested where the diff --git a/awx/ui/static/partials/inventory-edit.html b/awx/ui/static/partials/inventory-edit.html index 1fa1b2205c..3737b77693 100644 --- a/awx/ui/static/partials/inventory-edit.html +++ b/awx/ui/static/partials/inventory-edit.html @@ -49,6 +49,59 @@
+ + +
+
\ No newline at end of file