mirror of
https://github.com/ansible/awx.git
synced 2026-01-13 11:00:03 -03:30
Merge pull request #6836 from mabashian/6656-multiselect-preview
Added multi-select preview to group/host associate and instance groups modals
This commit is contained in:
commit
8c834daf46
@ -13,7 +13,7 @@ export default {
|
||||
controller: function($scope, $q, GroupsService, $state){
|
||||
$scope.associateGroups = function(selectedItems){
|
||||
var deferred = $q.defer();
|
||||
return $q.all( _.map(selectedItems, (id) => GroupsService.associateHost({id: parseInt($state.params.host_id)}, id)) )
|
||||
return $q.all( _.map(selectedItems, (selectedItem) => GroupsService.associateHost({id: parseInt($state.params.host_id)}, selectedItem.id)) )
|
||||
.then( () =>{
|
||||
deferred.resolve();
|
||||
}, (error) => {
|
||||
|
||||
@ -13,7 +13,7 @@ export default {
|
||||
controller: function($scope, $q, GroupsService, $state){
|
||||
$scope.associateGroups = function(selectedItems){
|
||||
var deferred = $q.defer();
|
||||
return $q.all( _.map(selectedItems, (id) => GroupsService.associateGroup({id: id}, $state.params.group_id)) )
|
||||
return $q.all( _.map(selectedItems, (selectedItem) => GroupsService.associateGroup({id: selectedItem.id}, $state.params.group_id)) )
|
||||
.then( () =>{
|
||||
deferred.resolve();
|
||||
}, (error) => {
|
||||
|
||||
@ -13,7 +13,7 @@ export default {
|
||||
controller: function($scope, $q, GroupsService, $state){
|
||||
$scope.associateHosts = function(selectedItems){
|
||||
var deferred = $q.defer();
|
||||
return $q.all( _.map(selectedItems, (id) => GroupsService.associateHost({id: id}, $state.params.group_id)) )
|
||||
return $q.all( _.map(selectedItems, (selectedItem) => GroupsService.associateHost({id: selectedItem.id}, $state.params.group_id)) )
|
||||
.then( () =>{
|
||||
deferred.resolve();
|
||||
}, (error) => {
|
||||
|
||||
@ -13,7 +13,7 @@ export default {
|
||||
controller: function($scope, $q, GroupsService, $state){
|
||||
$scope.associateGroups = function(selectedItems){
|
||||
var deferred = $q.defer();
|
||||
return $q.all( _.map(selectedItems, (id) => GroupsService.associateHost({id: parseInt($state.params.host_id)}, id)) )
|
||||
return $q.all( _.map(selectedItems, (selectedItem) => GroupsService.associateHost({id: parseInt($state.params.host_id)}, selectedItem.id)) )
|
||||
.then( () =>{
|
||||
deferred.resolve();
|
||||
}, (error) => {
|
||||
|
||||
@ -35,6 +35,10 @@
|
||||
list.multiSelect = true;
|
||||
list.fields.name.ngClick = 'linkoutGroup(associate_group.id)';
|
||||
list.trackBy = 'associate_group.id';
|
||||
list.multiSelectPreview = {
|
||||
selectedRows: 'selectedItems',
|
||||
availableRows: 'associate_groups'
|
||||
};
|
||||
delete list.actions;
|
||||
delete list.fieldActions;
|
||||
delete list.fields.failed_hosts;
|
||||
@ -58,9 +62,11 @@
|
||||
$scope.$watchCollection('associate_groups', function () {
|
||||
if($scope.selectedItems) {
|
||||
$scope.associate_groups.forEach(function(row, i) {
|
||||
if (_.includes($scope.selectedItems, row.id)) {
|
||||
$scope.associate_groups[i].isSelected = true;
|
||||
}
|
||||
$scope.selectedItems.forEach(function(selectedItem) {
|
||||
if(selectedItem.id === row.id) {
|
||||
$scope.associate_groups[i].isSelected = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -72,14 +78,14 @@
|
||||
let item = value.value;
|
||||
|
||||
if (value.isSelected) {
|
||||
$scope.selectedItems.push(item.id);
|
||||
$scope.selectedItems.push(item);
|
||||
}
|
||||
else {
|
||||
// _.remove() Returns the new array of removed elements.
|
||||
// This will pull all the values out of the array that don't
|
||||
// match the deselected item effectively removing it
|
||||
$scope.selectedItems = _.remove($scope.selectedItems, function(selectedItem) {
|
||||
return selectedItem !== item.id;
|
||||
return selectedItem.id !== item.id;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header Form-header">
|
||||
<div class="Form-title Form-title--uppercase">SELECT GROUP</div>
|
||||
<div class="Form-title Form-title--uppercase">SELECT GROUPS</div>
|
||||
<div class="Form-header--fields"></div>
|
||||
<div class="Form-exitHolder">
|
||||
<button type="button" class="Form-exit" ng-click="closeModal()">
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header Form-header">
|
||||
<div class="Form-title Form-title--uppercase">SELECT HOST</div>
|
||||
<div class="Form-title Form-title--uppercase">SELECT HOSTS</div>
|
||||
<div class="Form-header--fields"></div>
|
||||
<div class="Form-exitHolder">
|
||||
<button type="button" class="Form-exit" ng-click="closeModal()">
|
||||
|
||||
@ -46,7 +46,10 @@ export default ['templateUrl', function(templateUrl) {
|
||||
instanceGroupList.listTitle = false;
|
||||
instanceGroupList.well = false;
|
||||
instanceGroupList.multiSelect = true;
|
||||
instanceGroupList.multiSelectExtended = true;
|
||||
instanceGroupList.multiSelectPreview = {
|
||||
selectedRows: 'igTags',
|
||||
availableRows: 'instance_groups'
|
||||
};
|
||||
delete instanceGroupList.fields.percent_capacity_remaining;
|
||||
delete instanceGroupList.fields.jobs_running;
|
||||
|
||||
@ -104,4 +107,4 @@ export default ['templateUrl', function(templateUrl) {
|
||||
};
|
||||
}]
|
||||
};
|
||||
}];
|
||||
}];
|
||||
|
||||
@ -163,6 +163,10 @@ export default ['$compile', 'Attr', 'Icon',
|
||||
html += "</div>\n";
|
||||
}
|
||||
|
||||
if (list.multiSelectPreview) {
|
||||
html += "<multi-select-preview selected-rows='" + list.multiSelectPreview.selectedRows + "' available-rows='" + list.multiSelectPreview.availableRows + "'></multi-select-preview>";
|
||||
}
|
||||
|
||||
if (options.instructions) {
|
||||
html += "<div class=\"instructions alert alert-info\">" + options.instructions + "</div>\n";
|
||||
} else if (list.instructions) {
|
||||
|
||||
@ -32,6 +32,7 @@ import directives from './directives';
|
||||
import features from './features/main';
|
||||
import orgAdminLookup from './org-admin-lookup/main';
|
||||
import limitPanels from './limit-panels/main';
|
||||
import multiSelectPreview from './multi-select-preview/main';
|
||||
import 'angular-duration-format';
|
||||
|
||||
export default
|
||||
@ -61,6 +62,7 @@ angular.module('shared', [listGenerator.name,
|
||||
features.name,
|
||||
orgAdminLookup.name,
|
||||
limitPanels.name,
|
||||
multiSelectPreview.name,
|
||||
require('angular-cookies'),
|
||||
'angular-duration-format'
|
||||
])
|
||||
|
||||
11
awx/ui/client/src/shared/multi-select-preview/main.js
Normal file
11
awx/ui/client/src/shared/multi-select-preview/main.js
Normal file
@ -0,0 +1,11 @@
|
||||
/*************************************************
|
||||
* Copyright (c) 2017 Ansible, Inc.
|
||||
*
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
import multiSelectPreview from './multi-select-preview.directive';
|
||||
|
||||
export default
|
||||
angular.module('multiSelectPreview', [])
|
||||
.directive('multiSelectPreview', multiSelectPreview);
|
||||
@ -0,0 +1,99 @@
|
||||
@import '../branding/colors.default.less';
|
||||
|
||||
.MultiSelectPreview {
|
||||
display: flex;
|
||||
flex: 1 0 auto;
|
||||
margin-bottom: 15px;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
.MultiSelectPreview-selectedItems {
|
||||
display: flex;
|
||||
flex: 0 0 100%;
|
||||
background-color: @default-no-items-bord;
|
||||
border: 1px solid @default-border;
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.MultiSelectPreview-selectedItemsLabel, .MultiSelectPreview-label {
|
||||
color: @default-interface-txt;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.MultiSelectPreview-selectedItemsLabel {
|
||||
flex: 0 0 80px;
|
||||
line-height: 29px;
|
||||
}
|
||||
|
||||
.MultiSelectPreview-previewTags--outer {
|
||||
flex: 1 0 auto;
|
||||
max-width: ~"calc(100% - 140px)";
|
||||
}
|
||||
|
||||
.MultiSelectPreview-previewTags--inner {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.MultiSelectPreview-previewTagContainer {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.MultiSelectPreview-previewTagRevert {
|
||||
flex: 0 0 60px;
|
||||
line-height: 29px;
|
||||
}
|
||||
|
||||
.MultiSelectPreview-revertLink {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.MultiSelectPreview-previewTagContainerDelete {
|
||||
background-color: @default-link;
|
||||
border-top-left-radius: 5px;
|
||||
border-bottom-left-radius: 5px;
|
||||
color: @default-bg;
|
||||
padding: 0 5px;
|
||||
margin: 4px 0px;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.MultiSelectPreview-previewTagContainerDelete:hover {
|
||||
border-color: @default-err;
|
||||
background-color: @default-err;
|
||||
}
|
||||
|
||||
.MultiSelectPreview-previewTagContainerDelete:hover > .MultiSelectPreview-previewTagContainerTagDelete {
|
||||
color: @default-bg;
|
||||
}
|
||||
|
||||
.MultiSelectPreview-previewTag {
|
||||
border-radius: 5px;
|
||||
padding: 2px 10px;
|
||||
margin: 4px 0px;
|
||||
font-size: 12px;
|
||||
color: @default-interface-txt;
|
||||
background-color: @default-list-header-bg;
|
||||
margin-right: 5px;
|
||||
max-width: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.MultiSelectPreview-previewTagLabel {
|
||||
color: @default-list-header-bg;
|
||||
}
|
||||
|
||||
.MultiSelectPreview-previewTag--deletable {
|
||||
color: @default-bg;
|
||||
background-color: @default-link;
|
||||
margin-right: 0px;
|
||||
border-top-left-radius: 0px;
|
||||
border-bottom-left-radius: 0px;
|
||||
border-right: 0;
|
||||
max-width: ~"calc(100% - 23px)";
|
||||
margin-right: 5px;
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
/*************************************************
|
||||
* Copyright (c) 2017 Ansible, Inc.
|
||||
*
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
export default ['$scope',
|
||||
function ($scope) {
|
||||
$scope.unselectSelectedRow = function(index) {
|
||||
|
||||
angular.forEach($scope.availableRows, function(value) {
|
||||
if(value.id === $scope.selectedRows[index].id) {
|
||||
value.isSelected = false;
|
||||
}
|
||||
});
|
||||
|
||||
$scope.selectedRows.splice(index, 1);
|
||||
|
||||
};
|
||||
}
|
||||
];
|
||||
@ -0,0 +1,20 @@
|
||||
/*************************************************
|
||||
* Copyright (c) 2017 Ansible, Inc.
|
||||
*
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
import MultiSelectPreviewController from './multi-select-preview.controller';
|
||||
|
||||
export default ['templateUrl', function(templateUrl) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
replace: true,
|
||||
scope: {
|
||||
selectedRows: '=',
|
||||
availableRows: '='
|
||||
},
|
||||
controller: MultiSelectPreviewController,
|
||||
templateUrl: templateUrl('shared/multi-select-preview/multi-select-preview')
|
||||
};
|
||||
}];
|
||||
@ -0,0 +1,19 @@
|
||||
<div class="MultiSelectPreview" ng-show="selectedRows.length > 0">
|
||||
<div class="MultiSelectPreview-selectedItems">
|
||||
<div class="MultiSelectPreview-selectedItemsLabel">
|
||||
<span>SELECTED:</span>
|
||||
</div>
|
||||
<div class="MultiSelectPreview-previewTags--outer">
|
||||
<div class="MultiSelectPreview-previewTags--inner">
|
||||
<div class="MultiSelectPreview-previewTagContainer" ng-repeat="selectedRow in selectedRows">
|
||||
<div class="MultiSelectPreview-previewTagContainerDelete" ng-click="unselectSelectedRow($index)">
|
||||
<i class="fa fa-times MultiSelectPreview-previewTagContainerTagDelete"></i>
|
||||
</div>
|
||||
<div class="MultiSelectPreview-previewTag MultiSelectPreview-previewTag--deletable">
|
||||
<span>{{selectedRow.name}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Loading…
x
Reference in New Issue
Block a user