mirror of
https://github.com/ansible/awx.git
synced 2026-01-16 12:20:45 -03:30
Start of inventory re-write
This commit is contained in:
parent
1dd0634c8a
commit
f1b99f12b6
@ -32,7 +32,7 @@ angular.module('ansible', [
|
||||
'InventoryHelper',
|
||||
'InventoryHostsFormDefinition',
|
||||
'InventoryGroupsFormDefinition',
|
||||
'InventorySummaryDefinition',
|
||||
'InventoryGroupsDefinition',
|
||||
'AWFilters',
|
||||
'HostFormDefinition',
|
||||
'HostListDefinition',
|
||||
@ -59,8 +59,6 @@ angular.module('ansible', [
|
||||
'JobEventsListDefinition',
|
||||
'JobEventDataDefinition',
|
||||
'JobHostDefinition',
|
||||
'GroupsHelper',
|
||||
'HostsHelper',
|
||||
'ParseHelper',
|
||||
'ChildrenHelper',
|
||||
'EventsHelper',
|
||||
@ -80,7 +78,7 @@ angular.module('ansible', [
|
||||
'InventoryStatusDefinition',
|
||||
'InventorySummaryHelpDefinition',
|
||||
'InventoryHostsHelpDefinition',
|
||||
'TreeSelector',
|
||||
'InventoryTree',
|
||||
'CredentialsHelper',
|
||||
'TimerService',
|
||||
'StreamListDefinition',
|
||||
@ -138,14 +136,8 @@ angular.module('ansible', [
|
||||
when('/inventories/add',
|
||||
{ templateUrl: urlPrefix + 'partials/inventories.html', controller: InventoriesAdd }).
|
||||
|
||||
when('/inventories/:id',
|
||||
{ templateUrl: urlPrefix + 'partials/inventories.html', controller: InventoriesEdit }).
|
||||
|
||||
when('/inventories/:inventory_id/hosts',
|
||||
{ templateUrl: urlPrefix + 'partials/inventories.html', controller: InventoryHosts }).
|
||||
|
||||
when('/inventories/:inventory_id/groups',
|
||||
{ templateUrl: urlPrefix + 'partials/inventories.html', controller: InventoryGroups }).
|
||||
when('/inventories/:inventory_id',
|
||||
{ templateUrl: urlPrefix + 'partials/inventory-edit.html', controller: InventoriesEdit }).
|
||||
|
||||
when('/organizations', { templateUrl: urlPrefix + 'partials/organizations.html',
|
||||
controller: OrganizationsList }).
|
||||
|
||||
@ -198,14 +198,6 @@ function InventoriesList ($scope, $rootScope, $location, $log, $routeParams, Res
|
||||
scope.viewFailedJobs = function(id) {
|
||||
$location.url('/jobs/?inventory__int=' + id + '&status=failed');
|
||||
}
|
||||
|
||||
scope.editHosts = function(id) {
|
||||
$location.url('/inventories/' + id + '/hosts');
|
||||
}
|
||||
|
||||
scope.editGroups = function(id) {
|
||||
$location.url('/inventories/' + id + '/groups');
|
||||
}
|
||||
}
|
||||
|
||||
InventoriesList.$inject = [ '$scope', '$rootScope', '$location', '$log', '$routeParams', 'Rest', 'Alert', 'InventoryList', 'GenerateList',
|
||||
@ -322,67 +314,31 @@ InventoriesAdd.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$lo
|
||||
'OrganizationList', 'SearchInit', 'PaginateInit', 'LookUpInit', 'GetBasePath', 'ParseTypeChange', 'Wait'];
|
||||
|
||||
|
||||
function InventoriesEdit ($scope, $rootScope, $compile, $location, $log, $routeParams, InventoryForm,
|
||||
GenerateForm, Rest, Alert, ProcessErrors, LoadBreadCrumbs, RelatedSearchInit,
|
||||
RelatedPaginateInit, ReturnToCaller, ClearScope, LookUpInit, Prompt, OrganizationList,
|
||||
GetBasePath, LoadInventory, ParseTypeChange, EditInventory, SaveInventory, PostLoadInventory,
|
||||
Stream
|
||||
)
|
||||
function InventoriesEdit ($rootScope, $location, $routeParams, GenerateList, ClearScope, InventoryGroups, BuildTree, Wait)
|
||||
{
|
||||
ClearScope('htmlTemplate'); //Garbage collection. Don't leave behind any listeners/watchers from the prior
|
||||
//scope.
|
||||
|
||||
var generator = GenerateForm;
|
||||
var form = InventoryForm;
|
||||
var defaultUrl=GetBasePath('inventory');
|
||||
var scope = generator.inject(form, { mode: 'edit', related: true });
|
||||
var base = $location.path().replace(/^\//,'').split('/')[0];
|
||||
var id = $routeParams.id;
|
||||
var generator = GenerateList;
|
||||
var list = InventoryGroups;
|
||||
var base = $location.path().replace(/^\//,'').split('/')[0];
|
||||
var scope = $rootScope.$new();
|
||||
var groupScope;
|
||||
|
||||
scope['inventoryParseType'] = 'yaml';
|
||||
scope['inventory_id'] = id;
|
||||
|
||||
ParseTypeChange(scope,'inventory_variables', 'inventoryParseType');
|
||||
|
||||
// Retrieve each related sets and any lookups
|
||||
if (scope.inventoryLoadedRemove) {
|
||||
scope.inventoryLoadedRemove();
|
||||
}
|
||||
scope.inventoryLoadedRemove = scope.$on('inventoryLoaded', function() {
|
||||
LoadBreadCrumbs({ path: '/inventories/' + id, title: scope.inventory_name });
|
||||
PostLoadInventory({ scope: scope });
|
||||
});
|
||||
scope.$on('searchTreeReady', function(e, inventory_name, groups) {
|
||||
// After the tree data loads, generate the groups list
|
||||
groupScope = generator.inject(list, { mode: 'edit', id: 'groups-container', breadCrumbs: false, searchSize: 'col-lg-5' });
|
||||
Wait('stop');
|
||||
groupScope.groups = groups;
|
||||
groupScope.inventory_name = inventory_name;
|
||||
groupScope.inventory_id = $routeParams.inventory_id;
|
||||
});
|
||||
|
||||
LoadInventory({ scope: scope, doPostSteps: false });
|
||||
|
||||
scope.showActivity = function() { Stream(); }
|
||||
|
||||
// Cancel
|
||||
scope.formReset = function() {
|
||||
generator.reset();
|
||||
for (var fld in scope.master) {
|
||||
scope[fld] = scope.master[fld];
|
||||
}
|
||||
};
|
||||
|
||||
if (scope.removeInventorySaved) {
|
||||
scope.removeInventorySaved();
|
||||
}
|
||||
scope.removeInventorySaved = scope.$on('inventorySaved', function() {
|
||||
$location.path('/inventories');
|
||||
});
|
||||
|
||||
scope.formSave = function() {
|
||||
generator.clearApiErrors();
|
||||
SaveInventory({ scope: scope });
|
||||
}
|
||||
BuildTree({ scope: scope, inventory_id: $routeParams.inventory_id });
|
||||
|
||||
}
|
||||
|
||||
InventoriesEdit.$inject = [ '$scope', '$rootScope', '$compile', '$location', '$log', '$routeParams', 'InventoryForm',
|
||||
'GenerateForm', 'Rest', 'Alert', 'ProcessErrors', 'LoadBreadCrumbs', 'RelatedSearchInit',
|
||||
'RelatedPaginateInit', 'ReturnToCaller', 'ClearScope', 'LookUpInit', 'Prompt',
|
||||
'OrganizationList', 'GetBasePath', 'LoadInventory', 'ParseTypeChange', 'EditInventory',
|
||||
'SaveInventory', 'PostLoadInventory', 'Stream'
|
||||
InventoriesEdit.$inject = [ '$rootScope','$location', '$routeParams', 'GenerateList', 'ClearScope', 'InventoryGroups', 'BuildTree',
|
||||
'Wait'
|
||||
];
|
||||
|
||||
|
||||
@ -5,11 +5,11 @@
|
||||
*
|
||||
*/
|
||||
angular.module('JobSubmissionHelper', [ 'RestServices', 'Utilities', 'CredentialFormDefinition', 'CredentialsListDefinition',
|
||||
'LookUpHelper', 'ProjectFormDefinition', 'JobSubmissionHelper', 'GroupFormDefinition', 'GroupsHelper' ])
|
||||
'LookUpHelper', 'ProjectFormDefinition', 'JobSubmissionHelper' ])
|
||||
|
||||
.factory('PromptPasswords', ['CredentialForm', 'JobTemplateForm', 'GroupForm', 'ProjectsForm', '$compile', 'Rest', '$location', 'ProcessErrors',
|
||||
.factory('PromptPasswords', ['CredentialForm', 'JobTemplateForm', '$compile', 'Rest', '$location', 'ProcessErrors',
|
||||
'GetBasePath', 'Alert', 'Empty', 'Wait',
|
||||
function(CredentialForm, JobTemplateForm, ProjectsForm, GroupForm, $compile, Rest, $location, ProcessErrors, GetBasePath, Alert, Empty,
|
||||
function(CredentialForm, JobTemplateForm, $compile, Rest, $location, ProcessErrors, GetBasePath, Alert, Empty,
|
||||
Wait) {
|
||||
return function(params) {
|
||||
|
||||
@ -115,12 +115,14 @@ angular.module('JobSubmissionHelper', [ 'RestServices', 'Utilities', 'Credential
|
||||
if (form.fields[passwords[i]]) {
|
||||
current_form = form;
|
||||
}
|
||||
/*
|
||||
else if (ProjectsForm.fields[passwords[i]]) {
|
||||
current_form = ProjectsForm;
|
||||
}
|
||||
else if (GroupForm.fields[passwords[i]]) {
|
||||
current_form = GroupForm;
|
||||
}
|
||||
*/
|
||||
else {
|
||||
// No match found. Abandon ship!
|
||||
Alert('Form Not Found', 'Could not locate form for: ' + passwords[i], 'alert-danger');
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
angular.module('InventoryHelper', [ 'RestServices', 'Utilities', 'OrganizationListDefinition',
|
||||
'SearchHelper', 'PaginateHelper', 'ListGenerator', 'AuthService',
|
||||
'InventoryHelper', 'RelatedSearchHelper', 'RelatedPaginateHelper',
|
||||
'InventoryFormDefinition', 'ParseHelper', 'InventorySummaryDefinition'
|
||||
'InventoryFormDefinition', 'ParseHelper'
|
||||
])
|
||||
|
||||
.factory('LoadRootGroups', ['Rest', 'ProcessErrors', function(Rest, ProcessErrors) {
|
||||
|
||||
@ -50,7 +50,7 @@ angular.module('CloudCredentialsListDefinition', [])
|
||||
label: 'Create New',
|
||||
mode: 'all', // One of: edit, select, all
|
||||
ngClick: 'addCredential()',
|
||||
"class": 'btn-success btn-xs',
|
||||
"class": 'btn-sm',
|
||||
awToolTip: 'Create a new credential'
|
||||
}
|
||||
},
|
||||
@ -60,7 +60,7 @@ angular.module('CloudCredentialsListDefinition', [])
|
||||
ngClick: "editCredential(\{\{ credential.id \}\})",
|
||||
icon: 'icon-edit',
|
||||
label: 'Edit',
|
||||
"class": 'btn-xs btn-default',
|
||||
"class": 'btn-sm',
|
||||
awToolTip: 'View/Edit credential'
|
||||
},
|
||||
|
||||
@ -68,7 +68,7 @@ angular.module('CloudCredentialsListDefinition', [])
|
||||
ngClick: "deleteCredential(\{\{ credential.id \}\},'\{\{ credential.name \}\}')",
|
||||
icon: 'icon-trash',
|
||||
label: 'Delete',
|
||||
"class": 'btn-xs btn-danger',
|
||||
"class": 'btn-sm',
|
||||
awToolTip: 'Delete credential'
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,11 +59,11 @@ angular.module('CredentialsListDefinition', [])
|
||||
label: 'Create New',
|
||||
mode: 'all', // One of: edit, select, all
|
||||
ngClick: 'addCredential()',
|
||||
"class": 'btn-success btn-xs',
|
||||
"class": 'btn-sm',
|
||||
awToolTip: 'Create a new credential'
|
||||
},
|
||||
stream: {
|
||||
'class': "btn-primary btn-xs activity-btn",
|
||||
'class': "btn-sm activity-btn",
|
||||
ngClick: "showActivity()",
|
||||
awToolTip: "View Activity Stream",
|
||||
dataPlacement: "top",
|
||||
@ -79,7 +79,7 @@ angular.module('CredentialsListDefinition', [])
|
||||
ngClick: "editCredential(\{\{ credential.id \}\})",
|
||||
icon: 'icon-edit',
|
||||
label: 'Edit',
|
||||
"class": 'btn-xs btn-default',
|
||||
"class": 'btn-sm',
|
||||
awToolTip: 'View/Edit credential'
|
||||
},
|
||||
|
||||
@ -87,7 +87,7 @@ angular.module('CredentialsListDefinition', [])
|
||||
ngClick: "deleteCredential(\{\{ credential.id \}\},'\{\{ credential.name \}\}')",
|
||||
icon: 'icon-trash',
|
||||
label: 'Delete',
|
||||
"class": 'btn-xs btn-danger',
|
||||
"class": 'btn-sm',
|
||||
awToolTip: 'Delete credential'
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,7 +35,7 @@ angular.module('GroupListDefinition', [])
|
||||
dataContainer: '#form-modal .modal-content',
|
||||
icon: "icon-question-sign",
|
||||
mode: 'all',
|
||||
'class': 'btn-xs btn-info btn-help pull-right',
|
||||
'class': 'btn-xs btn-help pull-right',
|
||||
awToolTip: 'Click for help',
|
||||
dataTitle: 'Adding Groups',
|
||||
iconSize: 'large'
|
||||
@ -47,7 +47,7 @@ angular.module('GroupListDefinition', [])
|
||||
label: 'Edit',
|
||||
ngClick: "editGroup(\{\{ group.id \}\})",
|
||||
icon: 'icon-edit',
|
||||
"class": 'btn-xs btn-default',
|
||||
"class": 'btn-xs',
|
||||
awToolTip: 'View/Edit group'
|
||||
},
|
||||
|
||||
@ -55,7 +55,7 @@ angular.module('GroupListDefinition', [])
|
||||
label: 'Delete',
|
||||
ngClick: "deleteGroup(\{\{ group.id \}\},'\{\{ group.name \}\}')",
|
||||
icon: 'icon-trash',
|
||||
"class": 'btn-xs btn-danger',
|
||||
"class": 'btn-xs',
|
||||
awToolTip: 'Delete group'
|
||||
}
|
||||
}
|
||||
|
||||
@ -111,7 +111,7 @@ angular.module('HomeGroupListDefinition', [])
|
||||
|
||||
actions: {
|
||||
stream: {
|
||||
'class': "btn-primary btn-xs activity-btn",
|
||||
'class': "btn-xs activity-btn",
|
||||
ngClick: "showActivity()",
|
||||
awToolTip: "View Activity Stream",
|
||||
dataPlacement: "top",
|
||||
|
||||
@ -82,7 +82,7 @@ angular.module('HomeHostListDefinition', [])
|
||||
|
||||
actions: {
|
||||
stream: {
|
||||
'class': "btn-primary btn-xs activity-btn",
|
||||
'class': "btn-xs activity-btn",
|
||||
ngClick: "showActivity()",
|
||||
awToolTip: "View Activity Stream",
|
||||
dataPlacement: "top",
|
||||
|
||||
@ -47,7 +47,7 @@ angular.module('HostListDefinition', [])
|
||||
label: 'Edit',
|
||||
ngClick: "editHost(\{\{ host.id \}\})",
|
||||
icon: 'icon-edit',
|
||||
"class": 'btn-xs btn-default',
|
||||
"class": 'btn-xs',
|
||||
awToolTip: 'View/Edit host'
|
||||
},
|
||||
|
||||
@ -55,7 +55,7 @@ angular.module('HostListDefinition', [])
|
||||
label: 'Delete',
|
||||
ngClick: "deleteHost(\{\{ host.id \}\},'\{\{ host.name \}\}')",
|
||||
icon: 'icon-trash',
|
||||
"class": 'btn-xs btn-danger',
|
||||
"class": 'btn-xs',
|
||||
awToolTip: 'Delete host'
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,28 +82,39 @@ angular.module('InventoriesListDefinition', [])
|
||||
|
||||
actions: {
|
||||
add: {
|
||||
label: 'Create New',
|
||||
label: 'Add',
|
||||
icon: 'icon-plus',
|
||||
mode: 'all', // One of: edit, select, all
|
||||
ngClick: 'addInventory()',
|
||||
"class": 'btn-xs btn-success',
|
||||
awToolTip: 'Create a new inventory'
|
||||
},
|
||||
stream: {
|
||||
'class': "btn-primary btn-xs activity-btn",
|
||||
label: 'Activity',
|
||||
ngClick: "showActivity()",
|
||||
awToolTip: "View Activity Stream",
|
||||
dataPlacement: "top",
|
||||
icon: "icon-comments-alt",
|
||||
mode: 'all',
|
||||
iconSize: 'large',
|
||||
ngShow: "user_is_superuser"
|
||||
}
|
||||
},
|
||||
|
||||
fieldActions: {
|
||||
|
||||
dropdown: {
|
||||
edit: {
|
||||
label: 'Edit',
|
||||
ngClick: "editInventory(\{\{ inventory.id \}\})",
|
||||
icon: 'icon-edit',
|
||||
"class": 'btn-xs btn-default',
|
||||
awToolTip: 'Edit inventory'
|
||||
},
|
||||
"delete": {
|
||||
label: 'Delete',
|
||||
ngClick: "deleteInventory(\{\{ inventory.id \}\},'\{\{ inventory.name \}\}')",
|
||||
icon: 'icon-trash',
|
||||
"class": 'btn-xs btn-danger',
|
||||
awToolTip: 'Delete inventory'
|
||||
},
|
||||
dropdown: {
|
||||
type: 'DropDown',
|
||||
label: 'Jobs',
|
||||
icon: 'icon-zoom-in',
|
||||
@ -112,24 +123,6 @@ angular.module('InventoriesListDefinition', [])
|
||||
{ ngClick: 'viewJobs(\{\{ inventory.id \}\})', label: 'All' },
|
||||
{ ngClick: "viewFailedJobs(\{\{ inventory.id \}\})", label: 'Failed' }
|
||||
]
|
||||
},
|
||||
edit: {
|
||||
type: 'DropDown',
|
||||
label: 'Edit',
|
||||
icon: 'icon-edit',
|
||||
'class': 'btn-default btn-xs',
|
||||
options: [
|
||||
{ ngClick: "editInventory(\{\{ inventory.id \}\})", label: 'Properties' },
|
||||
{ ngClick: "editHosts(\{\{ inventory.id \}\})", label: 'Hosts' },
|
||||
{ ngClick: "editGroups(\{\{ inventory.id \}\})", label: 'Groups' }
|
||||
]
|
||||
},
|
||||
"delete": {
|
||||
label: 'Delete',
|
||||
ngClick: "deleteInventory(\{\{ inventory.id \}\},'\{\{ inventory.name \}\}')",
|
||||
icon: 'icon-trash',
|
||||
"class": 'btn-xs btn-danger',
|
||||
awToolTip: 'Delete inventory'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
186
awx/ui/static/js/lists/InventoryGroups.js
Normal file
186
awx/ui/static/js/lists/InventoryGroups.js
Normal file
@ -0,0 +1,186 @@
|
||||
/*********************************************
|
||||
* Copyright (c) 2013 AnsibleWorks, Inc.
|
||||
*
|
||||
* InventorySummary.js
|
||||
*
|
||||
* Summary of groups contained within an inventory
|
||||
*
|
||||
*/
|
||||
angular.module('InventoryGroupsDefinition', [])
|
||||
.value(
|
||||
'InventoryGroups', {
|
||||
|
||||
name: 'groups',
|
||||
iterator: 'group',
|
||||
editTitle: '{{ inventory_name | capitalize }}',
|
||||
showTitle: false,
|
||||
well: true,
|
||||
index: false,
|
||||
hover: true,
|
||||
hasChildren: true,
|
||||
class: 'table-condensed',
|
||||
|
||||
fields: {
|
||||
name: {
|
||||
key: true,
|
||||
label: 'name',
|
||||
ngClick: "\{\{ 'GroupsEdit(' + group.id + ')' \}\}",
|
||||
//ngClass: "\{\{ 'level' + group.level \}\}",
|
||||
hasChildren: true
|
||||
},
|
||||
status: {
|
||||
label: 'Sync Status',
|
||||
ngClick: "viewUpdateStatus(\{\{ group.id \}\})",
|
||||
searchType: 'select',
|
||||
badgeIcon: "\{\{ 'icon-cloud-' + group.status_badge_class \}\}",
|
||||
badgeToolTip: "\{\{ group.status_badge_tooltip \}\}",
|
||||
awToolTip: "\{\{ group.status_badge_tooltip \}\}",
|
||||
dataPlacement: 'top',
|
||||
badgeTipPlacement: 'top',
|
||||
badgePlacement: 'left',
|
||||
searchOptions: [
|
||||
{ name: "failed", value: "failed" },
|
||||
{ name: "never", value: "never updated" },
|
||||
{ name: "n/a", value: "none" },
|
||||
{ name: "successful", value: "successful" },
|
||||
{ name: "updating", value: "updating" }],
|
||||
sourceModel: 'inventory_source',
|
||||
sourceField: 'status'
|
||||
},
|
||||
failed_hosts: {
|
||||
label: 'Failed Hosts',
|
||||
ngHref: "\{\{ group.failed_hosts_link \}\}",
|
||||
badgeIcon: "\{\{ 'icon-failures-' + group.failed_hosts_class \}\}",
|
||||
badgeNgHref: "\{\{ group.failed_hosts_link \}\}",
|
||||
badgePlacement: 'left',
|
||||
badgeToolTip: "\{\{ group.failed_hosts_tip \}\}",
|
||||
badgeTipPlacement: 'top',
|
||||
awToolTip: "\{\{ group.failed_hosts_tip \}\}",
|
||||
dataPlacement: "top",
|
||||
searchable: false,
|
||||
excludeModal: true,
|
||||
sortField: "hosts_with_active_failures"
|
||||
},
|
||||
source: {
|
||||
label: 'Source',
|
||||
searchType: 'select',
|
||||
searchOptions: [
|
||||
{ name: "ec2", value: "ec2" },
|
||||
{ name: "none", value: "" },
|
||||
{ name: "rax", value: "rax" }],
|
||||
sourceModel: 'inventory_source',
|
||||
sourceField: 'source',
|
||||
searchOnly: true
|
||||
},
|
||||
has_external_source: {
|
||||
label: 'Has external source?',
|
||||
searchType: 'in',
|
||||
searchValue: 'ec2,rax',
|
||||
searchOnly: true,
|
||||
sourceModel: 'inventory_source',
|
||||
sourceField: 'source'
|
||||
},
|
||||
has_active_failures: {
|
||||
label: 'Has failed hosts?',
|
||||
searchSingleValue: true,
|
||||
searchType: 'boolean',
|
||||
searchValue: 'true',
|
||||
searchOnly: true
|
||||
},
|
||||
last_update_failed: {
|
||||
label: 'Update failed?',
|
||||
searchType: 'select',
|
||||
searchSingleValue: true,
|
||||
searchValue: 'failed',
|
||||
searchOnly: true,
|
||||
sourceModel: 'inventory_source',
|
||||
sourceField: 'status'
|
||||
}
|
||||
},
|
||||
|
||||
actions: {
|
||||
create: {
|
||||
label: 'Add',
|
||||
mode: 'all',
|
||||
icon: 'icon-plus',
|
||||
'class': "btn-sm",
|
||||
ngClick: "createGroup()",
|
||||
ngHide: "groupCreateHide",
|
||||
ngDisabled: 'grpBtnDisabled',
|
||||
awToolTip: "Create a new top-level group",
|
||||
dataPlacement: 'top',
|
||||
iconSize: 'large'
|
||||
},
|
||||
refresh: {
|
||||
label: 'Refresh',
|
||||
dataPlacement: 'top',
|
||||
icon: "icon-refresh",
|
||||
mode: 'all',
|
||||
'class': 'btn-sm',
|
||||
awToolTip: "Refresh the page",
|
||||
ngClick: "refresh()",
|
||||
iconSize: 'large'
|
||||
},
|
||||
stream: {
|
||||
label: 'Activity',
|
||||
'class': "btn-sm activity-btn",
|
||||
ngClick: "showActivity()",
|
||||
awToolTip: "View Activity Stream",
|
||||
dataPlacement: "top",
|
||||
icon: "icon-comments-alt",
|
||||
mode: 'all',
|
||||
iconSize: 'large',
|
||||
ngShow: "user_is_superuser"
|
||||
},
|
||||
help: {
|
||||
label: 'Help',
|
||||
dataPlacement: 'top',
|
||||
icon: "icon-question-sign",
|
||||
mode: 'all',
|
||||
'class': 'btn-sm btn-help',
|
||||
awToolTip:
|
||||
//"<div style=\"text-align:left;\"><img src=\"/static/img/cow.png\" style=\"width:50px; height:56px; float:left; padding-right:5px;\">" +
|
||||
//"<p>Need help getting started creating your inventory?</p><p>Click here for help.</p></div>",
|
||||
"<div style=\"text-align:left;\"><p>Need help getting started creating your inventory?</p><p>Click here for help.</p></div>",
|
||||
iconSize: 'large',
|
||||
ngClick: "showHelp()",
|
||||
id: "inventory-summary-help"
|
||||
}
|
||||
},
|
||||
|
||||
fieldActions: {
|
||||
group_update: {
|
||||
label: 'Update',
|
||||
icon: 'icon-cloud-download',
|
||||
"class": 'btn-xs btn-primary',
|
||||
ngClick: 'updateGroup(\{\{ group.id \}\})',
|
||||
awToolTip: "\{\{ group.update_tooltip \}\}",
|
||||
ngClass: "group.update_class",
|
||||
awToolTip: "Start inventory sync"
|
||||
},
|
||||
cancel: {
|
||||
label: 'Cancel',
|
||||
icon: 'icon-minus-sign',
|
||||
ngClick: "cancelUpdate(\{\{ group.id \}\}, '\{\{ group.name \}\}')",
|
||||
"class": 'btn-xs btn-primary',
|
||||
awToolTip: "\{\{ group.cancel_tooltip \}\}",
|
||||
ngClass: "group.cancel_class",
|
||||
ngShow: "group.status == 'running' || group.status == 'pending'"
|
||||
},
|
||||
edit: {
|
||||
label: 'Edit',
|
||||
ngClick: "editGroup(\{\{ group.id \}\})",
|
||||
icon: 'icon-edit',
|
||||
"class": 'btn-xs btn-primary',
|
||||
awToolTip: 'Edit group'
|
||||
},
|
||||
"delete": {
|
||||
label: 'Delete',
|
||||
ngClick: "deleteGroup(\{\{ group.id \}\},'\{\{ group.name \}\}')",
|
||||
icon: 'icon-trash',
|
||||
"class": 'btn-xs btn-primary',
|
||||
awToolTip: 'Delete group'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -89,7 +89,7 @@ angular.module('JobEventsListDefinition', [])
|
||||
dataPlacement: 'top',
|
||||
icon: "icon-refresh",
|
||||
mode: 'all',
|
||||
'class': 'btn-xs btn-primary',
|
||||
'class': 'btn-xs',
|
||||
awToolTip: "Refresh the page",
|
||||
ngClick: "refresh()",
|
||||
iconSize: 'large'
|
||||
|
||||
@ -113,7 +113,7 @@ angular.module('JobHostDefinition', [])
|
||||
dataContainer: "body",
|
||||
icon: "icon-question-sign",
|
||||
mode: 'all',
|
||||
'class': 'btn-info btn-xs btn-help',
|
||||
'class': 'btn-xs btn-help',
|
||||
awToolTip: 'Click for help',
|
||||
dataTitle: 'Job Host Summary',
|
||||
id: 'jobhost-help-button',
|
||||
@ -123,7 +123,7 @@ angular.module('JobHostDefinition', [])
|
||||
dataPlacement: 'top',
|
||||
icon: "icon-refresh",
|
||||
mode: 'all',
|
||||
'class': 'btn-xs btn-primary',
|
||||
'class': 'btn-xs',
|
||||
awToolTip: "Refresh the page",
|
||||
ngClick: "refresh()",
|
||||
iconSize: 'large',
|
||||
|
||||
@ -34,12 +34,12 @@ angular.module('JobTemplatesListDefinition', [])
|
||||
icon: 'icon-plus',
|
||||
mode: 'all', // One of: edit, select, all
|
||||
ngClick: 'addJobTemplate()',
|
||||
"class": 'btn-success btn-xs',
|
||||
"class": 'btn-xs',
|
||||
basePaths: ['job_templates'],
|
||||
awToolTip: 'Create a new template'
|
||||
},
|
||||
stream: {
|
||||
'class': "btn-primary btn-xs activity-btn",
|
||||
'class': "btn-xs activity-btn",
|
||||
ngClick: "showActivity()",
|
||||
awToolTip: "View Activity Stream",
|
||||
dataPlacement: "top",
|
||||
|
||||
@ -79,7 +79,7 @@ angular.module('JobsListDefinition', [])
|
||||
dataPlacement: 'top',
|
||||
icon: "icon-refresh",
|
||||
mode: 'all',
|
||||
'class': 'btn-xs btn-primary',
|
||||
'class': 'btn-xs',
|
||||
awToolTip: "Refresh the page",
|
||||
ngClick: "refresh()",
|
||||
iconSize: 'large'
|
||||
|
||||
@ -33,11 +33,11 @@ angular.module('OrganizationListDefinition', [])
|
||||
icon: 'icon-plus',
|
||||
mode: 'all', // One of: edit, select, all
|
||||
ngClick: 'addOrganization()',
|
||||
"class": 'btn-success btn-xs',
|
||||
"class": 'btn-xs',
|
||||
awToolTip: 'Create a new organization'
|
||||
},
|
||||
stream: {
|
||||
'class': "btn-primary btn-xs activity-btn",
|
||||
'class': "btn-xs activity-btn",
|
||||
ngClick: "showActivity()",
|
||||
awToolTip: "View Activity Stream",
|
||||
dataPlacement: "top",
|
||||
|
||||
@ -47,12 +47,12 @@ angular.module('PermissionListDefinition', [])
|
||||
label: 'Create New',
|
||||
mode: 'all', // One of: edit, select, all
|
||||
ngClick: 'addPermission()',
|
||||
"class": 'btn-success btn-xs',
|
||||
"class": 'btn-xs',
|
||||
awToolTip: 'Add a new permission',
|
||||
ngShow: 'PermissionAddAllowed'
|
||||
},
|
||||
stream: {
|
||||
'class': "btn-primary btn-xs activity-btn",
|
||||
'class': "btn-xs activity-btn",
|
||||
ngClick: "showActivity()",
|
||||
awToolTip: "View Activity Stream",
|
||||
dataPlacement: "top",
|
||||
|
||||
@ -61,7 +61,7 @@ angular.module('ProjectsListDefinition', [])
|
||||
icon: 'icon-plus',
|
||||
mode: 'all', // One of: edit, select, all
|
||||
ngClick: 'addProject()',
|
||||
"class": 'btn-success btn-xs',
|
||||
"class": 'btn-xs',
|
||||
awToolTip: 'Create a new project'
|
||||
},
|
||||
help: {
|
||||
@ -77,7 +77,7 @@ angular.module('ProjectsListDefinition', [])
|
||||
dataContainer: 'body',
|
||||
icon: "icon-question-sign",
|
||||
mode: 'all',
|
||||
'class': 'btn-xs btn-info btn-help',
|
||||
'class': 'btn-xs btn-help',
|
||||
awToolTip: 'Click for help',
|
||||
awTipPlacement: 'top',
|
||||
dataTitle: 'Project Status',
|
||||
@ -87,13 +87,13 @@ angular.module('ProjectsListDefinition', [])
|
||||
dataPlacement: 'top',
|
||||
icon: "icon-refresh",
|
||||
mode: 'all',
|
||||
'class': 'btn-xs btn-primary',
|
||||
'class': 'btn-xs',
|
||||
awToolTip: "Refresh the page",
|
||||
ngClick: "refresh()",
|
||||
iconSize: 'large'
|
||||
},
|
||||
stream: {
|
||||
'class': "btn-primary btn-xs activity-btn",
|
||||
'class': "btn-xs activity-btn",
|
||||
ngClick: "showActivity()",
|
||||
awToolTip: "View Activity Stream",
|
||||
dataPlacement: "top",
|
||||
|
||||
@ -208,7 +208,7 @@ angular.module('StreamListDefinition', [])
|
||||
dataPlacement: 'top',
|
||||
icon: "icon-refresh",
|
||||
mode: 'all',
|
||||
'class': 'btn-xs btn-primary',
|
||||
'class': 'btn-xs',
|
||||
awToolTip: "Refresh the page",
|
||||
ngClick: "refreshStream()",
|
||||
iconSize: 'large'
|
||||
@ -217,7 +217,7 @@ angular.module('StreamListDefinition', [])
|
||||
dataPlacement: 'top',
|
||||
icon: "icon-arrow-left",
|
||||
mode: 'all',
|
||||
'class': 'btn-xs btn-primary',
|
||||
'class': 'btn-xs',
|
||||
awToolTip: "Close Activity Stream view",
|
||||
ngClick: "closeStream()",
|
||||
iconSize: 'large'
|
||||
|
||||
@ -40,11 +40,11 @@ angular.module('TeamsListDefinition', [])
|
||||
icon: 'icon-plus',
|
||||
mode: 'all', // One of: edit, select, all
|
||||
ngClick: 'addTeam()',
|
||||
"class": 'btn-xs btn-success',
|
||||
"class": 'btn-xs',
|
||||
awToolTip: 'Create a new team'
|
||||
},
|
||||
stream: {
|
||||
'class': "btn-primary btn-xs activity-btn",
|
||||
'class': "btn-xs activity-btn",
|
||||
ngClick: "showActivity()",
|
||||
awToolTip: "View Activity Stream",
|
||||
dataPlacement: "top",
|
||||
|
||||
@ -40,11 +40,11 @@ angular.module('UserListDefinition', [])
|
||||
mode: 'all', // One of: edit, select, all
|
||||
ngClick: 'addUser()',
|
||||
basePaths: ['organizations','users'], // base path must be in list, or action not available
|
||||
"class": 'btn-success btn-xs',
|
||||
"class": 'btn-xs',
|
||||
awToolTip: 'Create a new user'
|
||||
},
|
||||
stream: {
|
||||
'class': "btn-primary btn-xs activity-btn",
|
||||
'class': "btn-xs activity-btn",
|
||||
ngClick: "showActivity()",
|
||||
awToolTip: "View Activity Stream",
|
||||
dataPlacement: "top",
|
||||
|
||||
@ -45,6 +45,43 @@ body {
|
||||
.grey-txt { color: @grey; }
|
||||
.text-center { text-align: center !important; }
|
||||
|
||||
|
||||
/* Old style TB default button with grey background */
|
||||
.btn-grey {
|
||||
color: #333;
|
||||
background-color: #ccc;
|
||||
border-color: #ccc;
|
||||
}
|
||||
|
||||
.btn-grey:hover {
|
||||
background-color: #FFF;
|
||||
}
|
||||
|
||||
/* Make button appear to be disabled, but allow mouse events */
|
||||
.btn-disabled {
|
||||
opacity: 0.65;
|
||||
filter: alpha(opacity=65);
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
/* List Actions column */
|
||||
.actions {
|
||||
a {
|
||||
font-size: 14px;
|
||||
margin-left: 15px;
|
||||
}
|
||||
a:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
a:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
.dropdown {
|
||||
margin-left: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.success-badge {
|
||||
color: #ffffff;
|
||||
background-color: #5cb85c;
|
||||
@ -117,15 +154,6 @@ textarea {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
/* Make button appear to be disabled, but allow mouse events */
|
||||
.btn-disabled {
|
||||
opacity: 0.65;
|
||||
filter: alpha(opacity=65);
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
|
||||
hr {
|
||||
border-color: #e3e3e3;
|
||||
}
|
||||
@ -174,11 +202,6 @@ td.actions {
|
||||
}
|
||||
|
||||
.dropdown-toggle,
|
||||
.btn-default {
|
||||
color: #333;
|
||||
background-color: #ccc;
|
||||
border-color: #ccc;
|
||||
}
|
||||
|
||||
.dropdown-toggle:hover,
|
||||
.btn-default:visited,
|
||||
@ -631,6 +654,7 @@ input[type="checkbox"].checkbox-no-label {
|
||||
/* Display list actions next to search widget */
|
||||
.list-actions {
|
||||
text-align: right;
|
||||
margin-bottom: 15px;
|
||||
|
||||
button {
|
||||
margin-left: 4px;
|
||||
@ -767,7 +791,7 @@ input[type="checkbox"].checkbox-no-label {
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
/* Inventory job status badge */
|
||||
/* Inventory job status badge */
|
||||
.failures-true {
|
||||
background-color: @red;
|
||||
color: #fff;
|
||||
@ -885,18 +909,17 @@ input[type="checkbox"].checkbox-no-label {
|
||||
color: @black;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.level-1 {
|
||||
padding-left: 24px;
|
||||
}
|
||||
|
||||
.level-2 {
|
||||
padding-left: 48px;
|
||||
}
|
||||
|
||||
.level-3 {
|
||||
padding-left: 72px;
|
||||
}
|
||||
/* Padding levels used on job events and inventory groups */
|
||||
.level-1 { padding-left: 20px; }
|
||||
.level-2 { padding-left: 40px; }
|
||||
.level-3 { padding-left: 60px; }
|
||||
.level-4 { padding-left: 80px; }
|
||||
.level-5 { padding-left: 100px; }
|
||||
.level-6 { padding-left: 120px; }
|
||||
.level-7 { padding-left: 140px; }
|
||||
.level-8 { padding-left: 160px; }
|
||||
.level-9 { padding-left: 180px; }
|
||||
.level-10 { padding-left: 200px; }
|
||||
|
||||
.level-3-detail {
|
||||
padding-left: 72px;
|
||||
@ -930,6 +953,11 @@ input[type="checkbox"].checkbox-no-label {
|
||||
}
|
||||
}
|
||||
|
||||
.inventory-title {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Inventory-> Groups */
|
||||
|
||||
.inventory-passwd-msg {
|
||||
|
||||
284
awx/ui/static/lib/ansible/InventoryTree.js
Normal file
284
awx/ui/static/lib/ansible/InventoryTree.js
Normal file
@ -0,0 +1,284 @@
|
||||
|
||||
/************************************
|
||||
*
|
||||
* Copyright (c) 2013 AnsibleWorks, Inc.
|
||||
*
|
||||
* InventoryTree.js
|
||||
*
|
||||
* Build data for the tree selector table used on inventory detail page.
|
||||
*
|
||||
*/
|
||||
|
||||
angular.module('InventoryTree', ['Utilities', 'RestServices'])
|
||||
|
||||
.factory('SortNodes', [ function() {
|
||||
return function(data) {
|
||||
//Sort nodes by name
|
||||
var names = [];
|
||||
var newData = [];
|
||||
for (var i=0; i < data.length; i++) {
|
||||
names.push(data[i].name);
|
||||
}
|
||||
names.sort();
|
||||
for (var j=0; j < names.length; j++) {
|
||||
for (i=0; i < data.length; i++) {
|
||||
if (data[i].name == names[j]) {
|
||||
newData.push(data[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return newData;
|
||||
}
|
||||
}])
|
||||
|
||||
// Figure out the group level tool tip
|
||||
.factory('GetToolTip', [ 'FormatDate', function(FormatDate) {
|
||||
return function(params) {
|
||||
|
||||
var node = params.node;
|
||||
|
||||
var tip = '';
|
||||
var link = '';
|
||||
var html_class = '';
|
||||
var active_failures = node.hosts_with_active_failures;
|
||||
var total_hosts = node.total_hosts;
|
||||
var source = node.summary_fields.inventory_source.source;
|
||||
var status = node.summary_fields.inventory_source.status;
|
||||
|
||||
// Return values for the status indicator
|
||||
var status_date = node.summary_fields.inventory_source.last_updated
|
||||
var last_update = ( status_date == "" || status_date == null ) ? null : FormatDate(new Date(status_date));
|
||||
|
||||
switch (status) {
|
||||
case 'never updated':
|
||||
html_class = 'na';
|
||||
tip = '<p>Inventory update has not been performed.</p>';
|
||||
link = '';
|
||||
break;
|
||||
case 'failed':
|
||||
tip = '<p>Inventory update failed! Click to view process output.</p>';
|
||||
link = '/#/inventories/' + node.inventory + '/groups?name=' + node.name;
|
||||
html_class = true;
|
||||
break;
|
||||
case 'successful':
|
||||
tip = '<p>Inventory update completed on ' + last_update + '.</p>';
|
||||
html_class = false;
|
||||
link = '';
|
||||
break;
|
||||
case 'updating':
|
||||
tip = '<p>Inventory update process running now. Click to view status.</p>';
|
||||
link = '/#/inventories/' + node.inventory + '/groups?name=' + node.name;
|
||||
html_class = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (status !== 'failed' && status !== 'updating') {
|
||||
// update status will not override job status
|
||||
if (active_failures > 0) {
|
||||
tip += "<p>Contains " + active_failures +
|
||||
[ (active_failures == 1) ? ' host' : ' hosts' ] + ' with failed jobs. Click to view the offending ' +
|
||||
[ (active_failures == 1) ? ' host' : ' hosts' ] + '.</p>';
|
||||
link = '/#/inventories/' + node.inventory + '/hosts?has_active_failures=true';
|
||||
html_class = 'true';
|
||||
}
|
||||
else {
|
||||
if (total_hosts == 0) {
|
||||
// no hosts
|
||||
tip += "<p>There are no hosts in this group. It's a sad empty shell.</p>";
|
||||
html_class = (html_class == '') ? 'na' : html_class;
|
||||
}
|
||||
else if (total_hosts == 1) {
|
||||
// on host with 0 failures
|
||||
tip += "<p>The 1 host in this group is happy! It does not have a job failure.</p>";
|
||||
html_class = 'false';
|
||||
}
|
||||
else {
|
||||
// many hosts with 0 failures
|
||||
tip += "<p>All " + total_hosts + " hosts in this group are happy! None of them have " +
|
||||
" job failures.</p>";
|
||||
html_class = 'false';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { tooltip: tip, url: link, 'class': html_class };
|
||||
|
||||
}
|
||||
}])
|
||||
|
||||
.factory('GetInventoryToolTip', [ 'FormatDate', function(FormatDate) {
|
||||
return function(params) {
|
||||
|
||||
var node = params.node;
|
||||
|
||||
var tip = '';
|
||||
var link = '';
|
||||
var html_class = '';
|
||||
var active_failures = node.hosts_with_active_failures;
|
||||
var total_hosts = node.total_hosts;
|
||||
var group_failures = node.groups_with_active_failures;
|
||||
var total_groups = node.total_groups;
|
||||
var inventory_sources = node.total_inventory_sources;
|
||||
|
||||
if (group_failures > 0) {
|
||||
tip += "Has " + group_failures +
|
||||
[ (group_failures == 1) ? ' group' : ' groups' ] + ' with failed inventory updates. ' +
|
||||
'Click to view the offending ' +
|
||||
[ (group_failures == 1) ? ' group.' : ' groups.' ];
|
||||
link = '/#/inventories/' + node.id + '/groups?status=failed';
|
||||
html_class = 'true';
|
||||
}
|
||||
else if (inventory_sources == 1) {
|
||||
// on host with 0 failures
|
||||
tip += "<p>1 group with an inventory source is happy! No updates have failed.</p>";
|
||||
link = '';
|
||||
html_class = 'false';
|
||||
}
|
||||
else if (inventory_sources > 0) {
|
||||
tip += "<p>" + inventory_sources + " groups with an inventory source are happy! No updates have failed.</p>";
|
||||
link = 0;
|
||||
html_class = 'false';
|
||||
}
|
||||
|
||||
if (html_class !== 'true') {
|
||||
// Add job status
|
||||
if (active_failures > 0) {
|
||||
tip += "<p>Contains " + scope.inventories[i].hosts_with_active_failures +
|
||||
[ (active_failures == 1) ? ' host' : ' hosts' ] + ' with job failures. Click to view the offending ' +
|
||||
[ (active_failures == 1) ? ' host' : ' hosts' ] + '.</p>';
|
||||
link = '/#/inventories/' + node.id + '/hosts?has_active_failures=true';
|
||||
html_class = 'true';
|
||||
}
|
||||
else if (total_hosts == 0) {
|
||||
tip += "<p>There are no hosts in this inventory. It's a sad empty shell.</p>";
|
||||
link = "";
|
||||
html_class = (html_class == '') ? 'na' : html_class;
|
||||
}
|
||||
else if (total_hosts == 1) {
|
||||
tip += "<p>The 1 host found in this inventory is happy! There are no job failures.</p>";
|
||||
link = "";
|
||||
html_class = "false";
|
||||
}
|
||||
else if (total_hosts > 0) {
|
||||
tip += "<p>All " + total_hosts + " hosts are happy! There are no job failures.";
|
||||
link = "";
|
||||
html_class = "false";
|
||||
}
|
||||
}
|
||||
|
||||
return { tooltip: tip, url: link, 'class': html_class };
|
||||
|
||||
}
|
||||
}])
|
||||
|
||||
.factory('BuildTree', ['Rest', 'GetBasePath', 'ProcessErrors', 'SortNodes', 'Wait',
|
||||
function(Rest, GetBasePath, ProcessErrors, SortNodes, Wait) {
|
||||
return function(params) {
|
||||
|
||||
var inventory_id = params.inventory_id;
|
||||
var scope = params.scope;
|
||||
|
||||
var groups = [];
|
||||
var id = 1;
|
||||
|
||||
function buildGroups(tree_data, parent, level) {
|
||||
var sorted = SortNodes(tree_data);
|
||||
for(var i=0; i < sorted.length; i++) {
|
||||
var currentId= id;
|
||||
var group = {
|
||||
name: sorted[i].name,
|
||||
has_active_failures: sorted[i].has_active_failures,
|
||||
total_hosts: sorted[i].total_hosts,
|
||||
hosts_with_active_failures: sorted[i].hosts_with_active_failures,
|
||||
total_groups: sorted[i].total_groups,
|
||||
groups_with_active_failures: sorted[i].groups_with_active_failures,
|
||||
parent: parent,
|
||||
has_children: (sorted[i].children.length > 0) ? true : false,
|
||||
id: id,
|
||||
event_level: level,
|
||||
ngicon: (sorted[i].children.length > 0) ? 'icon-collapse-alt' : null,
|
||||
related: { children: (sorted[i].children.length > 0) ? sorted[i].related.children : '' }
|
||||
}
|
||||
groups.push(group);
|
||||
id++;
|
||||
if (sorted[i].children.length > 0) {
|
||||
buildGroups(sorted[i].children, currentId, level + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Build the HTML for our tree
|
||||
if (scope.buildAllGroupsRemove) {
|
||||
scope.buildAllGroupsRemove();
|
||||
}
|
||||
scope.buildAllGroupsRemove = scope.$on('buildAllGroups', function(e, inventory_name, inventory_tree) {
|
||||
Rest.setUrl(inventory_tree);
|
||||
Rest.get()
|
||||
.success( function(data, status, headers, config) {
|
||||
buildGroups(data, 0, 0);
|
||||
scope.$emit('searchTreeReady', inventory_name, groups);
|
||||
})
|
||||
.error( function(data, status, headers, config) {
|
||||
Wait('stop');
|
||||
ProcessErrors(scope, data, status, null,
|
||||
{ hdr: 'Error!', msg: 'Failed to get inventory tree for: ' + inventory_id + '. GET returned: ' + status });
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
function loadTreeData() {
|
||||
// Load the inventory root node
|
||||
Wait('start');
|
||||
Rest.setUrl (GetBasePath('inventory') + inventory_id + '/');
|
||||
Rest.get()
|
||||
.success( function(data, status, headers, config) {
|
||||
scope.$emit('buildAllGroups', data.name, data.related.tree, data.related.groups);
|
||||
})
|
||||
.error( function(data, status, headers, config) {
|
||||
Wait('stop');
|
||||
ProcessErrors(scope, data, status, null,
|
||||
{ hdr: 'Error!', msg: 'Failed to get inventory: ' + inventory_id + '. GET returned: ' + status });
|
||||
});
|
||||
}
|
||||
|
||||
loadTreeData();
|
||||
|
||||
}
|
||||
}])
|
||||
|
||||
// Set node name and description after an update to Group properties.
|
||||
.factory('SetNodeName', [ function() {
|
||||
return function(params) {
|
||||
var scope = params.scope;
|
||||
var name = params.name;
|
||||
var descr = params.description;
|
||||
var group_id = (params.group_id !== undefined) ? params.group_id : null;
|
||||
var inventory_id = (params.inventory_id != undefined) ? params.inventory_id : null;
|
||||
|
||||
if (group_id !== null) {
|
||||
$('#inventory-tree').find('li [data-group-id="' + group_id + '"]').each(function(idx) {
|
||||
$(this).attr('data-name',name);
|
||||
$(this).attr('data-description',descr);
|
||||
$(this).find('.activate').first().text(name);
|
||||
});
|
||||
}
|
||||
|
||||
if (inventory_id !== null) {
|
||||
$('#inventory-root-node').attr('data-name', name).attr('data-description', descr).find('.activate').first().text(name);
|
||||
}
|
||||
}
|
||||
}])
|
||||
|
||||
.factory('ClickNode', [ function() {
|
||||
return function(params) {
|
||||
var selector = params.selector; //jquery selector string to find the correct <li>
|
||||
$(selector + ' .activate').first().click();
|
||||
}
|
||||
}])
|
||||
|
||||
.factory('DeleteNode', [ function() {
|
||||
return function(params) {
|
||||
var selector = params.selector; //jquery selector string to find the correct <li>
|
||||
$(selector).first().detach();
|
||||
}
|
||||
}]);
|
||||
@ -8,7 +8,7 @@
|
||||
var INTEGER_REGEXP = /^\-?\d*$/;
|
||||
|
||||
|
||||
angular.module('AWDirectives', ['RestServices', 'Utilities', 'AuthService', 'HostsHelper'])
|
||||
angular.module('AWDirectives', ['RestServices', 'Utilities', 'AuthService'])
|
||||
// awpassmatch: Add to password_confirm field. Will test if value
|
||||
// matches that of 'input[name="password"]'
|
||||
.directive('awpassmatch', function() {
|
||||
|
||||
@ -109,9 +109,10 @@ angular.module('GeneratorHelpers', ['GeneratorHelpers'])
|
||||
html += "<button type=\"button\" ";
|
||||
html += "class=\"btn";
|
||||
if (btn.awRefresh && !btn['class']) {
|
||||
html += ' btn-primary btn-xs refresh-btn';
|
||||
html += ' btn-xs refresh-btn';
|
||||
}
|
||||
else if (btn['class']) {
|
||||
else
|
||||
if (btn['class']) {
|
||||
html += ' ' + btn['class'];
|
||||
}
|
||||
else {
|
||||
@ -147,7 +148,7 @@ angular.module('GeneratorHelpers', ['GeneratorHelpers'])
|
||||
html += (btn['img']) ? "<img src=\"" + $basePath + "img/" + btn.img + "\" style=\"width: 12px; height: 12px;\" >" : "";
|
||||
html += (btn['icon']) ? Attr(btn,'icon') : "";
|
||||
html += (btn['awRefresh'] && !btn['icon']) ? "<i class=\"icon-refresh\"></i> " : "";
|
||||
html += (btn.label) ? " " + btn.label : "";
|
||||
html += (btn.label) ? "<br />" + btn.label : "";
|
||||
html += "</button> ";
|
||||
if (btn['awRefresh']) {
|
||||
html += '<span class=\"refresh-msg\" aw-refresh>{{ refreshMsg }}</span>\n';
|
||||
@ -492,7 +493,7 @@ angular.module('GeneratorHelpers', ['GeneratorHelpers'])
|
||||
for (var i=1; i <= searchWidgets; i++) {
|
||||
var modifier = (i == 1) ? '' : i;
|
||||
html += "<div class=\"";
|
||||
html += (params.size) ? params.size : "col-lg-4 col-md-6 col-sm-11 col-xs-11";
|
||||
html += (params.size) ? params.size : "col-lg-4 col-md-6 col-sm-12 col-xs-12";
|
||||
html += "\" id=\"search-widget-container" + modifier + "\">\n";
|
||||
|
||||
html += "<div class=\"input-group";
|
||||
|
||||
@ -193,31 +193,27 @@ angular.module('ListGenerator', ['GeneratorHelpers'])
|
||||
html += "<div class=\"well\">\n";
|
||||
}
|
||||
|
||||
/*
|
||||
if (list.editTitle.match(/^Inventory Summary/)) {
|
||||
html += "<div class=\"row groups-issue\">\n";
|
||||
html += "<div class=\"col-lg-12\">\n";
|
||||
html += "<label class=\"checkbox-inline pull-right\"><input type=\"checkbox\" ng-model=\"groupFailureFilter\" " +
|
||||
"ng-change=\"search()\" id=\"groups-issue-chbox\"> Show only groups with errors</label>\n";
|
||||
html += "</div>\n";
|
||||
html += "</div>\n";
|
||||
}
|
||||
*/
|
||||
|
||||
if (options.searchSize) {
|
||||
html += SearchWidget({ iterator: list.iterator, template: list, mini: true , size: options.searchSize,
|
||||
searchWidgets: list.searchWidgets });
|
||||
}
|
||||
else if (options.mode == 'summary') {
|
||||
html += SearchWidget({ iterator: list.iterator, template: list, mini: true , size: 'col-lg-6' });
|
||||
}
|
||||
else if (options.mode == 'lookup' || options.id != undefined) {
|
||||
html += SearchWidget({ iterator: list.iterator, template: list, mini: true , size: 'col-lg-8' });
|
||||
if (list.name == 'groups') {
|
||||
// Inventory groups
|
||||
html += "<div class=\"row\">\n";
|
||||
html += "<div class=\"inventory-title " + options.searchSize + "\">" + list.editTitle + "</div>\n";
|
||||
}
|
||||
else {
|
||||
html += SearchWidget({ iterator: list.iterator, template: list, mini: true });
|
||||
if (options.searchSize) {
|
||||
html += SearchWidget({ iterator: list.iterator, template: list, mini: true , size: options.searchSize,
|
||||
searchWidgets: list.searchWidgets });
|
||||
}
|
||||
else if (options.mode == 'summary') {
|
||||
html += SearchWidget({ iterator: list.iterator, template: list, mini: true , size: 'col-lg-6' });
|
||||
}
|
||||
else if (options.mode == 'lookup' || options.id != undefined) {
|
||||
html += SearchWidget({ iterator: list.iterator, template: list, mini: true , size: 'col-lg-8' });
|
||||
}
|
||||
else {
|
||||
html += SearchWidget({ iterator: list.iterator, template: list, mini: true });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (options.mode != 'lookup') {
|
||||
//actions
|
||||
var base = $location.path().replace(/^\//,'').split('/')[0];
|
||||
@ -241,12 +237,18 @@ angular.module('ListGenerator', ['GeneratorHelpers'])
|
||||
html += "\">\n";
|
||||
|
||||
html += "<div class=\"list-actions\">\n";
|
||||
// all but refresh button
|
||||
|
||||
for (action in list.actions) {
|
||||
if (list.actions[action].mode == 'all' || list.actions[action].mode == options.mode) {
|
||||
if ( (list.actions[action].basePaths == undefined) ||
|
||||
(list.actions[action].basePaths && list.actions[action].basePaths.indexOf(base) > -1) ) {
|
||||
html += this.button(list.actions[action], action);
|
||||
list.actions[action]['class'] = 'btn-xs btn-primary';
|
||||
list.actions[action]['iconSize'] = 'large';
|
||||
delete list.actions[action]['label'];
|
||||
if (action == 'stream') {
|
||||
list.actions[action]['icon'] = 'icon-time';
|
||||
}
|
||||
html += this.button(list.actions[action], action);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -258,7 +260,7 @@ angular.module('ListGenerator', ['GeneratorHelpers'])
|
||||
dataPlacement: 'left',
|
||||
dataContainer: 'body',
|
||||
icon: "icon-question-sign",
|
||||
'class': 'btn-xs btn-help btn-info',
|
||||
'class': 'btn-xs btn-help',
|
||||
awToolTip: 'Click for help',
|
||||
dataTitle: 'Help',
|
||||
iconSize: 'large'
|
||||
@ -286,7 +288,8 @@ angular.module('ListGenerator', ['GeneratorHelpers'])
|
||||
html += "<table id=\"" + list.name + "_table\" ";
|
||||
html += "class=\"table"
|
||||
html += (list['class']) ? " " + list['class'] : "";
|
||||
html += (options.mode !== 'summary' && (options.mode == 'lookup' || options.id)) ? ' table-hover-inverse' : '';
|
||||
html += (options.mode !== 'summary' && options.mode !== 'edit' && (options.mode == 'lookup' || options.id)) ?
|
||||
' table-hover-inverse' : '';
|
||||
html += (list.hover) ? ' table-hover' : '';
|
||||
html += (options.mode == 'summary') ? ' table-summary' : '';
|
||||
html += "\" ";
|
||||
@ -330,7 +333,7 @@ angular.module('ListGenerator', ['GeneratorHelpers'])
|
||||
html += "<th>Select</th>";
|
||||
}
|
||||
else if (options.mode == 'edit') {
|
||||
html += "<th class=\"actions-column\"></th>\n";
|
||||
html += "<th class=\"actions-column\">Actions</th>\n";
|
||||
}
|
||||
html += "</tr>\n";
|
||||
html += "</thead>\n";
|
||||
@ -378,7 +381,19 @@ angular.module('ListGenerator', ['GeneratorHelpers'])
|
||||
});
|
||||
}
|
||||
else {
|
||||
html += this.button(list.fieldActions[action]);
|
||||
//list.fieldActions[action]['class'] = 'btn-xs btn-default';
|
||||
//list.fieldActions[action]['iconSize'] = 'large';
|
||||
//html += this.button(list.fieldActions[action]);
|
||||
var fAction = list.fieldActions[action];
|
||||
html += "<a ";
|
||||
html += (fAction.href) ? "href=\"" + fAction.href + "\" " : "";
|
||||
html += (fAction.ngClick) ? this.attr(fAction,'ngClick') : "";
|
||||
html += (fAction.ngHref) ? this.attr(fAction,'ngHref') : "";
|
||||
html += (fAction.ngShow) ? this.attr(fAction,'ngShow') : "";
|
||||
html += ">";
|
||||
html += (fAction.icon) ? this.attr(fAction, 'icon') : "";
|
||||
html += (fAction.label) ? list.fieldActions[action]['label'] : "";
|
||||
html += "</a>";
|
||||
}
|
||||
}
|
||||
html += "</td>";
|
||||
@ -400,23 +415,25 @@ angular.module('ListGenerator', ['GeneratorHelpers'])
|
||||
html += "</table>\n";
|
||||
|
||||
if (options.mode == 'select' && (options.selectButton == undefined || options.selectButton == true)) {
|
||||
html += "<div class=\"navigation-buttons\">\n";
|
||||
html += " <button class=\"btn btn-sm btn-primary pull-right\" aw-tool-tip=\"Complete your selection\" " +
|
||||
"ng-click=\"finishSelection()\" ng-disabled=\"disableSelectBtn\"><i class=\"icon-check\"></i> Select</button>\n";
|
||||
html += "</div>\n";
|
||||
html += "<div class=\"navigation-buttons\">\n";
|
||||
html += " <button class=\"btn btn-sm btn-primary pull-right\" aw-tool-tip=\"Complete your selection\" " +
|
||||
"ng-click=\"finishSelection()\" ng-disabled=\"disableSelectBtn\"><i class=\"icon-check\"></i> Select</button>\n";
|
||||
html += "</div>\n";
|
||||
}
|
||||
|
||||
if (options.mode != 'lookup' && (list.well == undefined || list.well == true)) {
|
||||
html += "</div>\n"; //well
|
||||
}
|
||||
|
||||
if ( options.mode == 'lookup' || (options.id && options.id == "form-modal-body") ) {
|
||||
html += PaginateWidget({ set: list.name, iterator: list.iterator, mini: true, mode: 'lookup' });
|
||||
}
|
||||
else {
|
||||
html += PaginateWidget({ set: list.name, iterator: list.iterator, mini: true });
|
||||
html += "</div>\n"; //well
|
||||
}
|
||||
|
||||
if (list.name !== 'groups') {
|
||||
if ( options.mode == 'lookup' || (options.id && options.id == "form-modal-body") ) {
|
||||
html += PaginateWidget({ set: list.name, iterator: list.iterator, mini: true, mode: 'lookup' });
|
||||
}
|
||||
else {
|
||||
html += PaginateWidget({ set: list.name, iterator: list.iterator, mini: true });
|
||||
}
|
||||
}
|
||||
|
||||
return html;
|
||||
|
||||
}
|
||||
|
||||
8
awx/ui/static/partials/inventory-edit.html
Normal file
8
awx/ui/static/partials/inventory-edit.html
Normal file
@ -0,0 +1,8 @@
|
||||
<div class="tab-pane" id="inventory_edit">
|
||||
<div id="htmlTemplate">
|
||||
<div class="row">
|
||||
<div id="groups-container" class="col-lg-6"></div>
|
||||
<div id="hosts-container" class="col-lg-6"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -43,7 +43,7 @@
|
||||
<script src="{{ STATIC_URL }}lib/ansible/api-loader.js"></script>
|
||||
<script src="{{ STATIC_URL }}lib/ansible/license.js"></script>
|
||||
<script src="{{ STATIC_URL }}lib/ansible/pwdmeter.js"></script>
|
||||
<script src="{{ STATIC_URL }}lib/ansible/TreeSelector.js"></script>
|
||||
<script src="{{ STATIC_URL }}lib/ansible/InventoryTree.js"></script>
|
||||
<script src="{{ STATIC_URL }}lib/ansible/Timer.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/controllers/Authentication.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/controllers/Organizations.js"></script>
|
||||
@ -51,8 +51,6 @@
|
||||
<script src="{{ STATIC_URL }}js/controllers/Admins.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/controllers/Inventories.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/controllers/Home.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/controllers/Hosts.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/controllers/Groups.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/controllers/Teams.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/controllers/Credentials.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/controllers/JobTemplates.js"></script>
|
||||
@ -86,7 +84,7 @@
|
||||
<script src="{{ STATIC_URL }}js/lists/Inventories.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/lists/Teams.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/lists/Hosts.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/lists/InventorySummary.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/lists/InventoryGroups.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/lists/Groups.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/lists/Credentials.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/lists/JobTemplates.js"></script>
|
||||
@ -108,8 +106,6 @@
|
||||
<script src="{{ STATIC_URL }}js/helpers/teams.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/helpers/JobSubmission.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/helpers/Lookup.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/helpers/Groups.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/helpers/Hosts.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/helpers/Parse.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/helpers/Events.js"></script>
|
||||
<script src="{{ STATIC_URL }}js/helpers/Children.js"></script>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user