Merge pull request #7116 from mabashian/inventory-ux

Various inventory ux bug fixes
This commit is contained in:
Michael Abashian 2017-07-18 10:56:51 -04:00 committed by GitHub
commit 2c1fb371fe
22 changed files with 130 additions and 41 deletions

View File

@ -473,6 +473,10 @@ table, tbody {
color: @default-interface-txt;
}
.List-actionsInner {
display: flex;
}
@media (max-width: 991px) {
.List-searchWidget + .List-searchWidget {
margin-top: 20px;

View File

@ -62,7 +62,8 @@ export default ['i18n', function(i18n) {
//label: 'Delete',
mode: 'all',
ngClick: "disassociateHost(group)",
awToolTip: i18n._('Disassociate host'),
awToolTip: i18n._('Disassociate group'),
iconClass: 'fa fa-times',
dataPlacement: "top",
ngShow: "group.summary_fields.user_capabilities.delete"
}

View File

@ -10,5 +10,5 @@ import hostGroupsDefinition from './hosts-related-groups.list';
export default
angular.module('hostGroups', [])
.value('HostsRelatedGroupsList', hostGroupsDefinition)
.factory('HostsRelatedGroupsList', hostGroupsDefinition)
.controller('HostsRelatedGroupsController', controller);

View File

@ -165,6 +165,28 @@ angular.module('inventory', [
data: {
activityStream: true,
activityStreamTarget: 'inventory'
},
resolve: {
edit: {
InstanceGroupsData: ['$stateParams', 'Rest', 'GetBasePath', 'ProcessErrors',
function($stateParams, Rest, GetBasePath, ProcessErrors){
let path = `${GetBasePath('inventory')}${$stateParams.smartinventory_id}/instance_groups/`;
Rest.setUrl(path);
return Rest.get()
.then(({data}) => {
if (data.results.length > 0) {
return data.results;
}
})
.catch(({data, status}) => {
ProcessErrors(null, data, status, null, {
hdr: 'Error!',
msg: 'Failed to get instance groups. GET returned ' +
'status: ' + status
});
});
}]
}
}
});

View File

@ -98,7 +98,7 @@
//label: 'Delete',
mode: 'all',
ngClick: "deleteGroup(group)",
awToolTip: i18n._('Disassociate group'),
awToolTip: i18n._('Delete group'),
dataPlacement: "top",
ngShow: "group.summary_fields.user_capabilities.delete"
}

View File

@ -108,6 +108,7 @@
mode: 'all',
ngClick: "disassociateGroup(nested_group)",
awToolTip: i18n._('Disassociate group'),
iconClass: 'fa fa-times',
dataPlacement: "top",
ngShow: "nested_group.summary_fields.user_capabilities.delete"
}

View File

@ -83,7 +83,7 @@ export default ['i18n', function(i18n) {
"delete": {
//label: 'Delete',
ngClick: "disassociateHost(nested_host)",
icon: 'icon-trash',
iconClass: 'fa fa-times',
awToolTip: i18n._('Disassociate host'),
dataPlacement: 'top',
ngShow: 'nested_host.summary_fields.user_capabilities.delete'

View File

@ -78,11 +78,6 @@ function(i18n) {
dataTitle: i18n._('Host Variables'),
dataPlacement: 'right',
dataContainer: 'body'
},
inventory: {
type: 'hidden',
includeOnEdit: true,
includeOnAdd: true
}
},

View File

@ -96,6 +96,7 @@
mode: 'all',
ngClick: "disassociateGroup(nested_group)",
awToolTip: i18n._('Disassociate group'),
iconClass: 'fa fa-times',
dataPlacement: "top",
ngShow: "nested_group.summary_fields.user_capabilities.delete"
}

View File

@ -19,7 +19,7 @@ export default ['NotificationsList', 'i18n', function(NotificationsList, i18n){
include: "NotificationsList",
title: i18n._('Notifications'),
iterator: 'notification',
disabled: "source === undefined || source.value === ''",
ngIf: "!(inventory_source_obj.source === undefined || inventory_source_obj.source === '')",
generateList: true,
ngClick: "$state.go('inventories.edit.inventory_sources.edit.notifications')"
// search: {

View File

@ -13,7 +13,7 @@
function SmartInventoryAdd($scope, $location,
GenerateForm, smartInventoryForm, rbacUiControlService, Rest, Alert, ProcessErrors,
GetBasePath, ParseTypeChange, Wait, ToJSON,
$state, canAdd) {
$state, canAdd, InstanceGroupsService) {
$scope.canAdd = canAdd;
@ -64,9 +64,21 @@ function SmartInventoryAdd($scope, $location,
Rest.setUrl(defaultUrl);
Rest.post(data)
.success(function(data) {
var inventory_id = data.id;
Wait('stop');
$state.go('inventories.editSmartInventory', {smartinventory_id: inventory_id}, {reload: true});
const inventory_id = data.id,
instance_group_url = data.related.instance_groups;
InstanceGroupsService.addInstanceGroups(instance_group_url, $scope.instance_groups)
.then(() => {
Wait('stop');
$state.go('inventories.editSmartInventory', {smartinventory_id: inventory_id}, {reload: true});
})
.catch(({data, status}) => {
ProcessErrors($scope, data, status, form, {
hdr: 'Error!',
msg: 'Failed to post instance groups. POST returned ' +
'status: ' + status
});
});
})
.error(function(data, status) {
ProcessErrors($scope, data, status, form, {
@ -89,5 +101,5 @@ function SmartInventoryAdd($scope, $location,
export default ['$scope', '$location',
'GenerateForm', 'smartInventoryForm', 'rbacUiControlService', 'Rest', 'Alert',
'ProcessErrors', 'GetBasePath', 'ParseTypeChange',
'Wait', 'ToJSON', '$state', 'canAdd', SmartInventoryAdd
'Wait', 'ToJSON', '$state', 'canAdd', 'InstanceGroupsService', SmartInventoryAdd
];

View File

@ -7,13 +7,15 @@
function SmartInventoryEdit($scope, $location,
$stateParams, InventoryForm, Rest, ProcessErrors,
GetBasePath, ParseTypeChange, Wait, ToJSON,
ParseVariableString, $state, OrgAdminLookup, resourceData, $rootScope) {
ParseVariableString, $state, OrgAdminLookup, resourceData,
$rootScope, InstanceGroupsService, InstanceGroupsData) {
// Inject dynamic view
var defaultUrl = GetBasePath('inventory'),
form = InventoryForm,
inventory_id = $stateParams.smartinventory_id,
inventoryData = resourceData.data;
inventoryData = resourceData.data,
instance_group_url = inventoryData.related.instance_groups;
init();
function init() {
@ -25,6 +27,7 @@ function SmartInventoryEdit($scope, $location,
$scope.smartinventory_variables = inventoryData.variables === null || inventoryData.variables === '' ? '---' : ParseVariableString(inventoryData.variables);
$scope.organization_name = inventoryData.summary_fields.organization.name;
$scope.instance_groups = InstanceGroupsData;
$scope.$watch('inventory_obj.summary_fields.user_capabilities.edit', function(val) {
if (val === false) {
@ -75,8 +78,17 @@ function SmartInventoryEdit($scope, $location,
Rest.setUrl(defaultUrl + inventory_id + '/');
Rest.put(data)
.success(function() {
Wait('stop');
$state.go($state.current, {}, { reload: true });
InstanceGroupsService.editInstanceGroups(instance_group_url, $scope.instance_groups)
.then(() => {
Wait('stop');
$state.go($state.current, {}, { reload: true });
})
.catch(({data, status}) => {
ProcessErrors($scope, data, status, form, {
hdr: 'Error!',
msg: 'Failed to update instance groups. POST returned status: ' + status
});
});
})
.error(function(data, status) {
ProcessErrors($scope, data, status, form, {
@ -96,5 +108,6 @@ export default [ '$scope', '$location',
'$stateParams', 'InventoryForm', 'Rest',
'ProcessErrors', 'GetBasePath', 'ParseTypeChange', 'Wait',
'ToJSON', 'ParseVariableString',
'$state', 'OrgAdminLookup', 'resourceData', '$rootScope', SmartInventoryEdit
'$state', 'OrgAdminLookup', 'resourceData',
'$rootScope', 'InstanceGroupsService', 'InstanceGroupsData', SmartInventoryEdit
];

View File

@ -4,11 +4,12 @@
* All Rights Reserved
*************************************************/
import smartInventoryAdd from './add/main';
import smartInventoryEdit from './edit/main';
import smartInventoryForm from './smart-inventory.form';
import smartInventoryHostFilter from './smart-inventory-host-filter/smart-inventory-host-filter.directive';
import hostFilterModal from './smart-inventory-host-filter/host-filter-modal/host-filter-modal.directive';
import smartInventoryAdd from './add/main';
import smartInventoryEdit from './edit/main';
import smartInventoryForm from './smart-inventory.form';
import smartInventoryHostFilter from './smart-inventory-host-filter/smart-inventory-host-filter.directive';
import hostFilterModal from './smart-inventory-host-filter/host-filter-modal/host-filter-modal.directive';
import SmartInventoryStrings from './smart-inventory.strings';
export default
angular.module('smartInventory', [
@ -17,4 +18,5 @@ angular.module('smartInventory', [
])
.factory('smartInventoryForm', smartInventoryForm)
.directive('smartInventoryHostFilter', smartInventoryHostFilter)
.directive('hostFilterModal', hostFilterModal);
.directive('hostFilterModal', hostFilterModal)
.service('SmartInventoryStrings', SmartInventoryStrings);

View File

@ -4,10 +4,12 @@
* All Rights Reserved
*************************************************/
export default ['$scope', 'QuerySet',
function($scope, qs) {
export default ['$scope', 'QuerySet', 'SmartInventoryStrings',
function($scope, qs, SmartInventoryStrings) {
$scope.hostFilterTags = [];
$scope.filterTooltip = SmartInventoryStrings.get('filter.TOOLTIP');
$scope.$watch('hostFilter', function(){
$scope.hostFilterTags = [];

View File

@ -4,7 +4,7 @@
<i class="fa fa-search"></i>
</button>
</span>
<span class="form-control Form-textInput Form-textInput--variableHeight input-medium lookup" style="padding: 4px 6px;">
<span class="form-control Form-textInput Form-textInput--variableHeight input-medium lookup LabelList-lookupTags LabelList-lookupTags--disabled" aw-tool-tip="{{::filterTooltip}}" data-placement="top">
<span class="LabelList-tag" ng-repeat="tag in hostFilterTags">
<span class="LabelList-name">{{tag}}</span>
</span>

View File

@ -65,8 +65,20 @@ export default ['i18n', 'InventoryCompletedJobsList', function(i18n, InventoryCo
label: i18n._('Smart Host Filter'),
type: 'custom',
control: '<smart-inventory-host-filter host-filter="smart_hosts"></smart-inventory-host-filter>',
required: true,
class: 'Form-formGroup--fullWidth'
awPopOver: "<p>" + i18n._("Filter that will be applied to the hosts of this inventory.") + "</p>",
dataTitle: i18n._('Smart Host Filter'),
dataPlacement: 'right',
dataContainer: 'body',
required: true
},
instance_groups: {
label: i18n._('Instance Groups'),
type: 'custom',
awPopOver: "<p>" + i18n._("Select the Instance Groups for this Inventory to run on.") + "</p>",
dataTitle: i18n._('Instance Groups'),
dataPlacement: 'right',
dataContainer: 'body',
control: '<instance-groups-multiselect instance-groups="instance_groups"></instance-groups-multiselect>',
},
smartinventory_variables: {
label: i18n._('Variables'),

View File

@ -0,0 +1,14 @@
function SmartInventoryStrings (BaseString) {
BaseString.call(this, 'smartinventories');
let t = this.t;
let ns = this.smartinventories;
ns.filter = {
TOOLTIP: t('Please click the icon to edit the host filter.')
};
}
SmartInventoryStrings.$inject = ['BaseStringService'];
export default SmartInventoryStrings;

View File

@ -55,6 +55,7 @@ function InventoriesEdit($scope, $location,
});
$scope.inventory_obj = inventoryData;
$scope.inventory_name = inventoryData.name;
$rootScope.breadcrumb.inventory_name = inventoryData.name;
$scope.$watch('inventory_obj.summary_fields.user_capabilities.edit', function(val) {

View File

@ -1,10 +1,5 @@
@import "../../shared/branding/colors.default.less";
#InstanceGroups {
display: flex;
padding: 0 12px;
}
#instance-groups-panel {
table {
overflow: hidden;

View File

@ -4,7 +4,7 @@
<i class="fa fa-search"></i>
</button>
</span>
<span id="InstanceGroups" class="form-control Form-textInput Form-textInput--variableHeight input-medium lookup">
<span id="InstanceGroups" class="form-control Form-textInput Form-textInput--variableHeight input-medium lookup LabelList-lookupTags">
<div class="LabelList-tagContainer" ng-repeat="tag in instanceGroupsTags">
<div class="LabelList-deleteContainer"
ng-click="deleteTag(tag)">
@ -15,4 +15,4 @@
</div>
</div>
</span>
</div>
</div>

View File

@ -182,7 +182,7 @@ export default ['$compile', 'Attr', 'Icon',
html += (list.actionHolderClass) ? list.actionHolderClass : "List-actionHolder";
html += "\">";
html += "<div class=\"List-actions\">";
html += `<div ng-include="'${templateUrl('shared/list-generator/list-actions')}'">`;
html += `<div ng-include="'${templateUrl('shared/list-generator/list-actions')}'" class="List-actionsInner">`;
for (action in list.actions) {
list.actions[action] = _.defaults(list.actions[action], { dataPlacement: "top" });

View File

@ -17,7 +17,7 @@
.LabelList-tag, .JobSubmission-previewTag {
border-radius: 5px;
padding: 2px 10px;
margin: 4px 0px;
margin: 3px 0px;
font-size: 12px;
color: @default-interface-txt;
background-color: @default-list-header-bg;
@ -57,7 +57,7 @@
border-bottom-left-radius: 5px;
color: @default-bg;
padding: 0 5px;
margin: 4px 0px;
margin: 3px 0px;
align-items: center;
display: flex;
cursor: pointer;
@ -86,6 +86,20 @@
color: @default-bg;
}
.LabelList-lookupTags {
display: flex;
padding: 0 12px;
}
.LabelList-lookupTags--disabled {
cursor: not-allowed;
background-color: @default-list-header-bg;
.LabelList-tag {
color: @default-bg;
background-color: @default-icon;
}
}
.JobSubmission-previewTagContainer--vault{
flex: 1 0 auto;
}