mirror of
https://github.com/ansible/awx.git
synced 2026-02-21 13:10:11 -03:30
Organizations bug fixes including getting action buttons working and adding close buttons to the panels.
This commit is contained in:
@@ -976,6 +976,7 @@ input[type="checkbox"].checkbox-no-label {
|
|||||||
/* Display list actions next to search widget */
|
/* Display list actions next to search widget */
|
||||||
.list-actions {
|
.list-actions {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
.fa-lg {
|
.fa-lg {
|
||||||
vertical-align: -8%;
|
vertical-align: -8%;
|
||||||
@@ -1970,7 +1971,6 @@ tr td button i {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.list-actions {
|
.list-actions {
|
||||||
margin-bottom: 20px;
|
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -112,7 +112,9 @@ export default
|
|||||||
// use $state.go with reload: true option to re-instantiate sockets in
|
// use $state.go with reload: true option to re-instantiate sockets in
|
||||||
$state.go('jobDetail', {id: job}, {reload: true});
|
$state.go('jobDetail', {id: job}, {reload: true});
|
||||||
}
|
}
|
||||||
scope.clearDialog();
|
if(scope.clearDialog) {
|
||||||
|
scope.clearDialog();
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.error(function(data, status) {
|
.error(function(data, status) {
|
||||||
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
|
ProcessErrors(scope, data, status, null, { hdr: 'Error!',
|
||||||
|
|||||||
@@ -19,6 +19,6 @@ export default {
|
|||||||
},
|
},
|
||||||
ncyBreadcrumb: {
|
ncyBreadcrumb: {
|
||||||
parent: "organizations",
|
parent: "organizations",
|
||||||
label: "{{name}}"
|
label: "{{organization_name}}"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<div class="AddUsers-header">
|
<div class="AddUsers-header">
|
||||||
<div class="List-header">
|
<div class="List-header">
|
||||||
<div class="List-title">
|
<div class="List-title">
|
||||||
<div class="List-titleText ng-binding">{{ $parent.org_name }}<div class="List-titleLockup"></div>Add {{ addType }}
|
<div class="List-titleText ng-binding">{{ $parent.organization_name }}<div class="List-titleLockup"></div>Add {{ addType }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="Form-exitHolder">
|
<div class="Form-exitHolder">
|
||||||
|
|||||||
@@ -0,0 +1,101 @@
|
|||||||
|
/*************************************************
|
||||||
|
* Copyright (c) 2016 Ansible, Inc.
|
||||||
|
*
|
||||||
|
* All Rights Reserved
|
||||||
|
*************************************************/
|
||||||
|
|
||||||
|
export default ['$stateParams', '$scope', 'UserList', 'Rest', '$state', 'generateList', '$compile',
|
||||||
|
'SearchInit', 'PaginateInit', 'Wait', 'Prompt', 'ProcessErrors', 'GetBasePath',
|
||||||
|
function($stateParams, $scope, UserList, Rest, $state, GenerateList, $compile,
|
||||||
|
SearchInit, PaginateInit, Wait, Prompt, ProcessErrors, GetBasePath) {
|
||||||
|
|
||||||
|
var list,
|
||||||
|
url,
|
||||||
|
generator = GenerateList,
|
||||||
|
orgBase = GetBasePath('organizations');
|
||||||
|
|
||||||
|
Rest.setUrl(orgBase + $stateParams.organization_id);
|
||||||
|
Rest.get()
|
||||||
|
.success(function (data) {
|
||||||
|
// include name of item in listTitle
|
||||||
|
var listTitle = data.name + "<div class='List-titleLockup'></div>ADMINS";
|
||||||
|
|
||||||
|
$scope.$parent.activeCard = parseInt($stateParams.organization_id);
|
||||||
|
$scope.$parent.activeMode = 'admins';
|
||||||
|
$scope.organization_name = data.name;
|
||||||
|
$scope.org_id = data.id;
|
||||||
|
var listMode = 'users';
|
||||||
|
|
||||||
|
list = _.cloneDeep(UserList);
|
||||||
|
list.emptyListText = "Please add items to this list";
|
||||||
|
delete list.actions.add;
|
||||||
|
list.searchRowActions = {
|
||||||
|
add: {
|
||||||
|
buttonContent: '+ ADD administrator',
|
||||||
|
awToolTip: 'Add existing user to organization as administrator',
|
||||||
|
actionClass: 'btn List-buttonSubmit',
|
||||||
|
ngClick: 'addUsers()'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
url = data.related.admins;
|
||||||
|
list.listTitle = listTitle;
|
||||||
|
list.basePath = url;
|
||||||
|
|
||||||
|
$scope.orgRelatedUrls = data.related;
|
||||||
|
|
||||||
|
generator.inject(list, { mode: 'edit', scope: $scope, cancelButton: true });
|
||||||
|
|
||||||
|
SearchInit({
|
||||||
|
scope: $scope,
|
||||||
|
set: listMode,
|
||||||
|
list: list,
|
||||||
|
url: url
|
||||||
|
});
|
||||||
|
PaginateInit({
|
||||||
|
scope: $scope,
|
||||||
|
list: list,
|
||||||
|
url: url
|
||||||
|
});
|
||||||
|
$scope.search(list.iterator);
|
||||||
|
});
|
||||||
|
|
||||||
|
$scope.addUsers = function () {
|
||||||
|
$compile("<add-users class='AddUsers'></add-users>")($scope);
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.editUser = function (id) {
|
||||||
|
$state.transitionTo('users.edit', {user_id: id});
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.deleteUser = function (id, name) {
|
||||||
|
var action = function () {
|
||||||
|
$('#prompt-modal').modal('hide');
|
||||||
|
Wait('start');
|
||||||
|
var url = orgBase + $stateParams.organization_id + '/admins/';
|
||||||
|
Rest.setUrl(url);
|
||||||
|
Rest.post({
|
||||||
|
id: id,
|
||||||
|
disassociate: true
|
||||||
|
}).success(function () {
|
||||||
|
$scope.search(list.iterator);
|
||||||
|
})
|
||||||
|
.error(function (data, status) {
|
||||||
|
ProcessErrors($scope, data, status, null, { hdr: 'Error!',
|
||||||
|
msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status });
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Prompt({
|
||||||
|
hdr: 'Delete',
|
||||||
|
body: '<div class="Prompt-bodyQuery">Are you sure you want to remove the following administrator from this organization?</div><div class="Prompt-bodyTarget">' + name + '</div>',
|
||||||
|
action: action,
|
||||||
|
actionText: 'DELETE'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.formCancel = function(){
|
||||||
|
$state.go('organizations');
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
];
|
||||||
@@ -0,0 +1,343 @@
|
|||||||
|
/*************************************************
|
||||||
|
* Copyright (c) 2016 Ansible, Inc.
|
||||||
|
*
|
||||||
|
* All Rights Reserved
|
||||||
|
*************************************************/
|
||||||
|
|
||||||
|
export default ['$scope', '$rootScope', '$location', '$log',
|
||||||
|
'$stateParams', '$compile', '$filter', 'sanitizeFilter', 'Rest', 'Alert', 'InventoryList',
|
||||||
|
'generateList', 'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller',
|
||||||
|
'ClearScope', 'ProcessErrors', 'GetBasePath', 'Wait', 'Find', 'Empty', '$state',
|
||||||
|
function($scope, $rootScope, $location, $log,
|
||||||
|
$stateParams, $compile, $filter, sanitizeFilter, Rest, Alert, InventoryList,
|
||||||
|
generateList, Prompt, SearchInit, PaginateInit, ReturnToCaller,
|
||||||
|
ClearScope, ProcessErrors, GetBasePath, Wait,
|
||||||
|
Find, Empty, $state) {
|
||||||
|
|
||||||
|
var list,
|
||||||
|
invUrl,
|
||||||
|
orgBase = GetBasePath('organizations'),
|
||||||
|
generator = generateList;
|
||||||
|
|
||||||
|
// Go out and get the organization
|
||||||
|
Rest.setUrl(orgBase + $stateParams.organization_id);
|
||||||
|
Rest.get()
|
||||||
|
.success(function (data) {
|
||||||
|
// include name of item in listTitle
|
||||||
|
var listTitle = data.name + "<div class='List-titleLockup'></div>INVENTORIES";
|
||||||
|
|
||||||
|
$scope.$parent.activeCard = parseInt($stateParams.organization_id);
|
||||||
|
$scope.$parent.activeMode = 'inventories';
|
||||||
|
$scope.organization_name = data.name;
|
||||||
|
$scope.org_id = data.id;
|
||||||
|
|
||||||
|
list = _.cloneDeep(InventoryList);
|
||||||
|
list.emptyListText = "This list is populated by inventories added from the <a ui-sref='inventories.add'>Inventories</a> section";
|
||||||
|
delete list.actions.add;
|
||||||
|
delete list.fieldActions.delete;
|
||||||
|
invUrl = data.related.inventories;
|
||||||
|
list.listTitle = listTitle;
|
||||||
|
list.basePath = invUrl;
|
||||||
|
|
||||||
|
$scope.orgRelatedUrls = data.related;
|
||||||
|
|
||||||
|
generator.inject(list, { mode: 'edit', scope: $scope, cancelButton: true });
|
||||||
|
$rootScope.flashMessage = null;
|
||||||
|
|
||||||
|
SearchInit({
|
||||||
|
scope: $scope,
|
||||||
|
set: 'inventories',
|
||||||
|
list: list,
|
||||||
|
url: invUrl
|
||||||
|
});
|
||||||
|
PaginateInit({
|
||||||
|
scope: $scope,
|
||||||
|
list: list,
|
||||||
|
url: invUrl
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($stateParams.name) {
|
||||||
|
$scope[InventoryList.iterator + 'InputDisable'] = false;
|
||||||
|
$scope[InventoryList.iterator + 'SearchValue'] = $stateParams.name;
|
||||||
|
$scope[InventoryList.iterator + 'SearchField'] = 'name';
|
||||||
|
$scope[InventoryList.iterator + 'SearchFieldLabel'] = InventoryList.fields.name.label;
|
||||||
|
$scope[InventoryList.iterator + 'SearchSelectValue'] = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($stateParams.has_active_failures) {
|
||||||
|
$scope[InventoryList.iterator + 'InputDisable'] = true;
|
||||||
|
$scope[InventoryList.iterator + 'SearchValue'] = $stateParams.has_active_failures;
|
||||||
|
$scope[InventoryList.iterator + 'SearchField'] = 'has_active_failures';
|
||||||
|
$scope[InventoryList.iterator + 'SearchFieldLabel'] = InventoryList.fields.has_active_failures.label;
|
||||||
|
$scope[InventoryList.iterator + 'SearchSelectValue'] = ($stateParams.has_active_failures === 'true') ? {
|
||||||
|
value: 1
|
||||||
|
} : {
|
||||||
|
value: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($stateParams.has_inventory_sources) {
|
||||||
|
$scope[InventoryList.iterator + 'InputDisable'] = true;
|
||||||
|
$scope[InventoryList.iterator + 'SearchValue'] = $stateParams.has_inventory_sources;
|
||||||
|
$scope[InventoryList.iterator + 'SearchField'] = 'has_inventory_sources';
|
||||||
|
$scope[InventoryList.iterator + 'SearchFieldLabel'] = InventoryList.fields.has_inventory_sources.label;
|
||||||
|
$scope[InventoryList.iterator + 'SearchSelectValue'] = ($stateParams.has_inventory_sources === 'true') ? {
|
||||||
|
value: 1
|
||||||
|
} : {
|
||||||
|
value: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($stateParams.inventory_sources_with_failures) {
|
||||||
|
// pass a value of true, however this field actually contains an integer value
|
||||||
|
$scope[InventoryList.iterator + 'InputDisable'] = true;
|
||||||
|
$scope[InventoryList.iterator + 'SearchValue'] = $stateParams.inventory_sources_with_failures;
|
||||||
|
$scope[InventoryList.iterator + 'SearchField'] = 'inventory_sources_with_failures';
|
||||||
|
$scope[InventoryList.iterator + 'SearchFieldLabel'] = InventoryList.fields.inventory_sources_with_failures.label;
|
||||||
|
$scope[InventoryList.iterator + 'SearchType'] = 'gtzero';
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.search(list.iterator);
|
||||||
|
});
|
||||||
|
|
||||||
|
function ellipsis(a) {
|
||||||
|
if (a.length > 20) {
|
||||||
|
return a.substr(0,20) + '...';
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
function attachElem(event, html, title) {
|
||||||
|
var elem = $(event.target).parent();
|
||||||
|
try {
|
||||||
|
elem.tooltip('hide');
|
||||||
|
elem.popover('destroy');
|
||||||
|
}
|
||||||
|
catch(err) {
|
||||||
|
//ignore
|
||||||
|
}
|
||||||
|
$('.popover').each(function() {
|
||||||
|
// remove lingering popover <div>. Seems to be a bug in TB3 RC1
|
||||||
|
$(this).remove();
|
||||||
|
});
|
||||||
|
$('.tooltip').each( function() {
|
||||||
|
// close any lingering tool tipss
|
||||||
|
$(this).hide();
|
||||||
|
});
|
||||||
|
elem.attr({
|
||||||
|
"aw-pop-over": html,
|
||||||
|
"data-popover-title": title,
|
||||||
|
"data-placement": "right" });
|
||||||
|
$compile(elem)($scope);
|
||||||
|
elem.on('shown.bs.popover', function() {
|
||||||
|
$('.popover').each(function() {
|
||||||
|
$compile($(this))($scope); //make nested directives work!
|
||||||
|
});
|
||||||
|
$('.popover-content, .popover-title').click(function() {
|
||||||
|
elem.popover('hide');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
elem.popover('show');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($scope.removePostRefresh) {
|
||||||
|
$scope.removePostRefresh();
|
||||||
|
}
|
||||||
|
$scope.removePostRefresh = $scope.$on('PostRefresh', function () {
|
||||||
|
//If we got here by deleting an inventory, stop the spinner and cleanup events
|
||||||
|
Wait('stop');
|
||||||
|
try {
|
||||||
|
$('#prompt-modal').modal('hide');
|
||||||
|
}
|
||||||
|
catch(e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
$scope.inventories.forEach(function(inventory, idx) {
|
||||||
|
$scope.inventories[idx].launch_class = "";
|
||||||
|
if (inventory.has_inventory_sources) {
|
||||||
|
if (inventory.inventory_sources_with_failures > 0) {
|
||||||
|
$scope.inventories[idx].syncStatus = 'error';
|
||||||
|
$scope.inventories[idx].syncTip = inventory.inventory_sources_with_failures + ' groups with sync failures. Click for details';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$scope.inventories[idx].syncStatus = 'successful';
|
||||||
|
$scope.inventories[idx].syncTip = 'No inventory sync failures. Click for details.';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$scope.inventories[idx].syncStatus = 'na';
|
||||||
|
$scope.inventories[idx].syncTip = 'Not configured for inventory sync.';
|
||||||
|
$scope.inventories[idx].launch_class = "btn-disabled";
|
||||||
|
}
|
||||||
|
if (inventory.has_active_failures) {
|
||||||
|
$scope.inventories[idx].hostsStatus = 'error';
|
||||||
|
$scope.inventories[idx].hostsTip = inventory.hosts_with_active_failures + ' hosts with failures. Click for details.';
|
||||||
|
}
|
||||||
|
else if (inventory.total_hosts) {
|
||||||
|
$scope.inventories[idx].hostsStatus = 'successful';
|
||||||
|
$scope.inventories[idx].hostsTip = 'No hosts with failures. Click for details.';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$scope.inventories[idx].hostsStatus = 'none';
|
||||||
|
$scope.inventories[idx].hostsTip = 'Inventory contains 0 hosts.';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($scope.removeRefreshInventories) {
|
||||||
|
$scope.removeRefreshInventories();
|
||||||
|
}
|
||||||
|
$scope.removeRefreshInventories = $scope.$on('RefreshInventories', function () {
|
||||||
|
// Reflect changes after inventory properties edit completes
|
||||||
|
$scope.search(list.iterator);
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($scope.removeHostSummaryReady) {
|
||||||
|
$scope.removeHostSummaryReady();
|
||||||
|
}
|
||||||
|
$scope.removeHostSummaryReady = $scope.$on('HostSummaryReady', function(e, event, data) {
|
||||||
|
|
||||||
|
var html, title = "Recent Jobs";
|
||||||
|
Wait('stop');
|
||||||
|
if (data.count > 0) {
|
||||||
|
html = "<table class=\"table table-condensed flyout\" style=\"width: 100%\">\n";
|
||||||
|
html += "<thead>\n";
|
||||||
|
html += "<tr>";
|
||||||
|
html += "<th>Status</th>";
|
||||||
|
html += "<th>Finished</th>";
|
||||||
|
html += "<th>Name</th>";
|
||||||
|
html += "</tr>\n";
|
||||||
|
html += "</thead>\n";
|
||||||
|
html += "<tbody>\n";
|
||||||
|
|
||||||
|
data.results.forEach(function(row) {
|
||||||
|
html += "<tr>\n";
|
||||||
|
html += "<td><a href=\"#/jobs/" + row.id + "\" " + "aw-tool-tip=\"" + row.status.charAt(0).toUpperCase() + row.status.slice(1) +
|
||||||
|
". Click for details\" aw-tip-placement=\"top\"><i class=\"fa icon-job-" + row.status + "\"></i></a></td>\n";
|
||||||
|
html += "<td>" + ($filter('longDate')(row.finished)).replace(/ /,'<br />') + "</td>";
|
||||||
|
html += "<td><a href=\"#/jobs/" + row.id + "\" " + "aw-tool-tip=\"" + row.status.charAt(0).toUpperCase() + row.status.slice(1) +
|
||||||
|
". Click for details\" aw-tip-placement=\"top\">" + ellipsis(row.name) + "</a></td>";
|
||||||
|
html += "</tr>\n";
|
||||||
|
});
|
||||||
|
html += "</tbody>\n";
|
||||||
|
html += "</table>\n";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
html = "<p>No recent job data available for this inventory.</p>\n";
|
||||||
|
}
|
||||||
|
attachElem(event, html, title);
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($scope.removeGroupSummaryReady) {
|
||||||
|
$scope.removeGroupSummaryReady();
|
||||||
|
}
|
||||||
|
$scope.removeGroupSummaryReady = $scope.$on('GroupSummaryReady', function(e, event, inventory, data) {
|
||||||
|
var html, title;
|
||||||
|
|
||||||
|
Wait('stop');
|
||||||
|
|
||||||
|
// Build the html for our popover
|
||||||
|
html = "<table class=\"table table-condensed flyout\" style=\"width: 100%\">\n";
|
||||||
|
html += "<thead>\n";
|
||||||
|
html += "<tr>";
|
||||||
|
html += "<th>Status</th>";
|
||||||
|
html += "<th>Last Sync</th>";
|
||||||
|
html += "<th>Group</th>";
|
||||||
|
html += "</tr>";
|
||||||
|
html += "</thead>\n";
|
||||||
|
html += "<tbody>\n";
|
||||||
|
data.results.forEach( function(row) {
|
||||||
|
if (row.related.last_update) {
|
||||||
|
html += "<tr>";
|
||||||
|
html += "<td><a href=\"\" ng-click=\"viewJob('" + row.related.last_update + "')\" aw-tool-tip=\"" + row.status.charAt(0).toUpperCase() + row.status.slice(1) + ". Click for details\" aw-tip-placement=\"top\"><i class=\"fa icon-job-" + row.status + "\"></i></a></td>";
|
||||||
|
html += "<td>" + ($filter('longDate')(row.last_updated)).replace(/ /,'<br />') + "</td>";
|
||||||
|
html += "<td><a href=\"\" ng-click=\"viewJob('" + row.related.last_update + "')\">" + ellipsis(row.summary_fields.group.name) + "</a></td>";
|
||||||
|
html += "</tr>\n";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
html += "<tr>";
|
||||||
|
html += "<td><a href=\"\" aw-tool-tip=\"No sync data\" aw-tip-placement=\"top\"><i class=\"fa icon-job-none\"></i></a></td>";
|
||||||
|
html += "<td>NA</td>";
|
||||||
|
html += "<td><a href=\"\">" + ellipsis(row.summary_fields.group.name) + "</a></td>";
|
||||||
|
html += "</tr>\n";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
html += "</tbody>\n";
|
||||||
|
html += "</table>\n";
|
||||||
|
title = "Sync Status";
|
||||||
|
attachElem(event, html, title);
|
||||||
|
});
|
||||||
|
|
||||||
|
$scope.showGroupSummary = function(event, id) {
|
||||||
|
var inventory;
|
||||||
|
if (!Empty(id)) {
|
||||||
|
inventory = Find({ list: $scope.inventories, key: 'id', val: id });
|
||||||
|
if (inventory.syncStatus !== 'na') {
|
||||||
|
Wait('start');
|
||||||
|
Rest.setUrl(inventory.related.inventory_sources + '?or__source=ec2&or__source=rax&order_by=-last_job_run&page_size=5');
|
||||||
|
Rest.get()
|
||||||
|
.success(function(data) {
|
||||||
|
$scope.$emit('GroupSummaryReady', event, inventory, data);
|
||||||
|
})
|
||||||
|
.error(function(data, status) {
|
||||||
|
ProcessErrors( $scope, data, status, null, { hdr: 'Error!',
|
||||||
|
msg: 'Call to ' + inventory.related.inventory_sources + ' failed. GET returned status: ' + status
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.showHostSummary = function(event, id) {
|
||||||
|
var url, inventory;
|
||||||
|
if (!Empty(id)) {
|
||||||
|
inventory = Find({ list: $scope.inventories, key: 'id', val: id });
|
||||||
|
if (inventory.total_hosts > 0) {
|
||||||
|
Wait('start');
|
||||||
|
url = GetBasePath('jobs') + "?type=job&inventory=" + id + "&failed=";
|
||||||
|
url += (inventory.has_active_failures) ? 'true' : "false";
|
||||||
|
url += "&order_by=-finished&page_size=5";
|
||||||
|
Rest.setUrl(url);
|
||||||
|
Rest.get()
|
||||||
|
.success( function(data) {
|
||||||
|
$scope.$emit('HostSummaryReady', event, data);
|
||||||
|
})
|
||||||
|
.error( function(data, status) {
|
||||||
|
ProcessErrors( $scope, data, status, null, { hdr: 'Error!',
|
||||||
|
msg: 'Call to ' + url + ' failed. GET returned: ' + status
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.viewJob = function(url) {
|
||||||
|
// Pull the id out of the URL
|
||||||
|
var id = url.replace(/^\//, '').split('/')[3];
|
||||||
|
$state.go('inventorySyncStdout', {id: id});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.editInventory = function (id) {
|
||||||
|
$state.go('inventories.edit', {inventory_id: id});
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.manageInventory = function(id){
|
||||||
|
$location.path($location.path() + '/' + id + '/manage');
|
||||||
|
};
|
||||||
|
|
||||||
|
// Failed jobs link. Go to the jobs tabs, find all jobs for the inventory and sort by status
|
||||||
|
$scope.viewJobs = function (id) {
|
||||||
|
$location.url('/jobs/?inventory__int=' + id);
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.viewFailedJobs = function (id) {
|
||||||
|
$location.url('/jobs/?inventory__int=' + id + '&status=failed');
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.formCancel = function(){
|
||||||
|
$state.go('organizations');
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
];
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
/*************************************************
|
||||||
|
* Copyright (c) 2016 Ansible, Inc.
|
||||||
|
*
|
||||||
|
* All Rights Reserved
|
||||||
|
*************************************************/
|
||||||
|
|
||||||
|
export default ['$scope', '$rootScope', '$location', '$log',
|
||||||
|
'$stateParams', 'Rest', 'Alert', 'JobTemplateList', 'generateList',
|
||||||
|
'Prompt', 'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope',
|
||||||
|
'ProcessErrors', 'GetBasePath', 'JobTemplateForm', 'CredentialList',
|
||||||
|
'LookUpInit', 'InitiatePlaybookRun', 'Wait', '$compile',
|
||||||
|
'$state',
|
||||||
|
function($scope, $rootScope, $location, $log,
|
||||||
|
$stateParams, Rest, Alert, JobTemplateList, GenerateList, Prompt,
|
||||||
|
SearchInit, PaginateInit, ReturnToCaller, ClearScope, ProcessErrors,
|
||||||
|
GetBasePath, JobTemplateForm, CredentialList, LookUpInit, InitiatePlaybookRun,
|
||||||
|
Wait, $compile, $state) {
|
||||||
|
|
||||||
|
var list,
|
||||||
|
jobTemplateUrl,
|
||||||
|
generator = GenerateList,
|
||||||
|
orgBase = GetBasePath('organizations');
|
||||||
|
|
||||||
|
Rest.setUrl(orgBase + $stateParams.organization_id);
|
||||||
|
Rest.get()
|
||||||
|
.success(function (data) {
|
||||||
|
// include name of item in listTitle
|
||||||
|
var listTitle = data.name + "<div class='List-titleLockup'></div>JOB TEMPLATES";
|
||||||
|
|
||||||
|
$scope.$parent.activeCard = parseInt($stateParams.organization_id);
|
||||||
|
$scope.$parent.activeMode = 'job_templates';
|
||||||
|
$scope.organization_name = data.name;
|
||||||
|
$scope.org_id = data.id;
|
||||||
|
|
||||||
|
list = _.cloneDeep(JobTemplateList);
|
||||||
|
list.emptyListText = "This list is populated by job templates added from the <a ui-sref='jobTemplates.add'>Job Templates</a> section";
|
||||||
|
delete list.actions.add;
|
||||||
|
delete list.fieldActions.delete;
|
||||||
|
jobTemplateUrl = "/api/v1/job_templates/?project__organization=" + data.id;
|
||||||
|
list.listTitle = listTitle;
|
||||||
|
list.basePath = jobTemplateUrl;
|
||||||
|
|
||||||
|
$scope.orgRelatedUrls = data.related;
|
||||||
|
|
||||||
|
generator.inject(list, { mode: 'edit', scope: $scope, cancelButton: true });
|
||||||
|
|
||||||
|
if ($scope.removePostRefresh) {
|
||||||
|
$scope.removePostRefresh();
|
||||||
|
}
|
||||||
|
$scope.removePostRefresh = $scope.$on('PostRefresh', function () {
|
||||||
|
// Cleanup after a delete
|
||||||
|
Wait('stop');
|
||||||
|
$('#prompt-modal').modal('hide');
|
||||||
|
});
|
||||||
|
|
||||||
|
SearchInit({
|
||||||
|
scope: $scope,
|
||||||
|
set: 'job_templates',
|
||||||
|
list: list,
|
||||||
|
url: jobTemplateUrl
|
||||||
|
});
|
||||||
|
PaginateInit({
|
||||||
|
scope: $scope,
|
||||||
|
list: list,
|
||||||
|
url: jobTemplateUrl
|
||||||
|
});
|
||||||
|
$scope.search(list.iterator);
|
||||||
|
});
|
||||||
|
|
||||||
|
$scope.addJobTemplate = function () {
|
||||||
|
$state.transitionTo('jobTemplates.add');
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.editJobTemplate = function (id) {
|
||||||
|
$state.transitionTo('jobTemplates.edit', {template_id: id});
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.submitJob = function (id) {
|
||||||
|
InitiatePlaybookRun({ scope: $scope, id: id });
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.scheduleJob = function (id) {
|
||||||
|
$state.go('jobTemplateSchedules', {id: id});
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.formCancel = function(){
|
||||||
|
$state.go('organizations');
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
];
|
||||||
@@ -0,0 +1,350 @@
|
|||||||
|
/*************************************************
|
||||||
|
* Copyright (c) 2016 Ansible, Inc.
|
||||||
|
*
|
||||||
|
* All Rights Reserved
|
||||||
|
*************************************************/
|
||||||
|
|
||||||
|
export default ['$scope', '$rootScope', '$location', '$log',
|
||||||
|
'$stateParams', 'Rest', 'Alert', 'ProjectList', 'generateList', 'Prompt',
|
||||||
|
'SearchInit', 'PaginateInit', 'ReturnToCaller', 'ClearScope',
|
||||||
|
'ProcessErrors', 'GetBasePath', 'SelectionInit', 'ProjectUpdate',
|
||||||
|
'Refresh', 'Wait', 'GetChoices', 'Empty', 'Find',
|
||||||
|
'GetProjectIcon', 'GetProjectToolTip', '$filter', '$state',
|
||||||
|
function($scope, $rootScope, $location, $log, $stateParams,
|
||||||
|
Rest, Alert, ProjectList, GenerateList, Prompt, SearchInit,
|
||||||
|
PaginateInit, ReturnToCaller, ClearScope, ProcessErrors, GetBasePath,
|
||||||
|
SelectionInit, ProjectUpdate, Refresh, Wait, GetChoices, Empty,
|
||||||
|
Find, GetProjectIcon, GetProjectToolTip, $filter, $state) {
|
||||||
|
|
||||||
|
var list,
|
||||||
|
projUrl,
|
||||||
|
choiceCount = 0,
|
||||||
|
orgBase = GetBasePath('organizations'),
|
||||||
|
projBase = GetBasePath('projects'),
|
||||||
|
generator = GenerateList;
|
||||||
|
|
||||||
|
// Go out and get the organization
|
||||||
|
Rest.setUrl(orgBase + $stateParams.organization_id);
|
||||||
|
Rest.get()
|
||||||
|
.success(function (data) {
|
||||||
|
// include name of item in listTitle
|
||||||
|
var listTitle = data.name + "<div class='List-titleLockup'></div>PROJECTS";
|
||||||
|
|
||||||
|
$scope.$parent.activeCard = parseInt($stateParams.organization_id);
|
||||||
|
$scope.$parent.activeMode = 'projects';
|
||||||
|
$scope.organization_name = data.name;
|
||||||
|
$scope.org_id = data.id;
|
||||||
|
|
||||||
|
list = _.cloneDeep(ProjectList);
|
||||||
|
list.emptyListText = "This list is populated by projects added from the <a ui-sref='projects.add'>Projects</a> section";
|
||||||
|
delete list.actions.add;
|
||||||
|
delete list.fieldActions.delete;
|
||||||
|
projUrl = data.related.projects;
|
||||||
|
list.listTitle = listTitle;
|
||||||
|
list.basePath = projUrl;
|
||||||
|
|
||||||
|
$scope.orgRelatedUrls = data.related;
|
||||||
|
|
||||||
|
generator.inject(list, { mode: 'edit', scope: $scope, cancelButton: true });
|
||||||
|
$rootScope.flashMessage = null;
|
||||||
|
|
||||||
|
if ($scope.removePostRefresh) {
|
||||||
|
$scope.removePostRefresh();
|
||||||
|
}
|
||||||
|
$scope.removePostRefresh = $scope.$on('PostRefresh', function () {
|
||||||
|
Wait('stop');
|
||||||
|
if ($scope.projects) {
|
||||||
|
$scope.projects.forEach(function(project, i) {
|
||||||
|
$scope.projects[i].statusIcon = GetProjectIcon(project.status);
|
||||||
|
$scope.projects[i].statusTip = GetProjectToolTip(project.status);
|
||||||
|
$scope.projects[i].scm_update_tooltip = "Start an SCM update";
|
||||||
|
$scope.projects[i].scm_schedule_tooltip = "Schedule future SCM updates";
|
||||||
|
$scope.projects[i].scm_type_class = "";
|
||||||
|
|
||||||
|
if (project.status === 'failed' && project.summary_fields.last_update && project.summary_fields.last_update.status === 'canceled') {
|
||||||
|
$scope.projects[i].statusTip = 'Canceled. Click for details';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (project.status === 'running' || project.status === 'updating') {
|
||||||
|
$scope.projects[i].scm_update_tooltip = "SCM update currently running";
|
||||||
|
$scope.projects[i].scm_type_class = "btn-disabled";
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.project_scm_type_options.forEach(function(type) {
|
||||||
|
if (type.value === project.scm_type) {
|
||||||
|
$scope.projects[i].scm_type = type.label;
|
||||||
|
if (type.label === 'Manual') {
|
||||||
|
$scope.projects[i].scm_update_tooltip = 'Manual projects do not require an SCM update';
|
||||||
|
$scope.projects[i].scm_schedule_tooltip = 'Manual projects do not require a schedule';
|
||||||
|
$scope.projects[i].scm_type_class = 'btn-disabled';
|
||||||
|
$scope.projects[i].statusTip = 'Not configured for SCM';
|
||||||
|
$scope.projects[i].statusIcon = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle project update status changes
|
||||||
|
if ($rootScope.removeJobStatusChange) {
|
||||||
|
$rootScope.removeJobStatusChange();
|
||||||
|
}
|
||||||
|
$rootScope.removeJobStatusChange = $rootScope.$on('JobStatusChange-projects', function(e, data) {
|
||||||
|
var project;
|
||||||
|
$log.debug(data);
|
||||||
|
if ($scope.projects) {
|
||||||
|
// Assuming we have a list of projects available
|
||||||
|
project = Find({ list: $scope.projects, key: 'id', val: data.project_id });
|
||||||
|
if (project) {
|
||||||
|
// And we found the affected project
|
||||||
|
$log.debug('Received event for project: ' + project.name);
|
||||||
|
$log.debug('Status changed to: ' + data.status);
|
||||||
|
if (data.status === 'successful' || data.status === 'failed') {
|
||||||
|
$scope.search(list.iterator, null, null, null, null, false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
project.scm_update_tooltip = "SCM update currently running";
|
||||||
|
project.scm_type_class = "btn-disabled";
|
||||||
|
}
|
||||||
|
project.status = data.status;
|
||||||
|
project.statusIcon = GetProjectIcon(data.status);
|
||||||
|
project.statusTip = GetProjectToolTip(data.status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($scope.removeChoicesHere) {
|
||||||
|
$scope.removeChoicesHere();
|
||||||
|
}
|
||||||
|
$scope.removeChoicesHere = $scope.$on('choicesCompleteProjectList', function () {
|
||||||
|
var opt;
|
||||||
|
|
||||||
|
list.fields.scm_type.searchOptions = $scope.project_scm_type_options;
|
||||||
|
list.fields.status.searchOptions = $scope.project_status_options;
|
||||||
|
|
||||||
|
if ($stateParams.scm_type && $stateParams.status) {
|
||||||
|
// Request coming from home page. User wants all errors for an scm_type
|
||||||
|
projUrl += '?status=' + $stateParams.status;
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchInit({
|
||||||
|
scope: $scope,
|
||||||
|
set: 'projects',
|
||||||
|
list: list,
|
||||||
|
url: projUrl
|
||||||
|
});
|
||||||
|
PaginateInit({
|
||||||
|
scope: $scope,
|
||||||
|
list: list,
|
||||||
|
url: projUrl
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($stateParams.scm_type) {
|
||||||
|
$scope[list.iterator + 'SearchType'] = '';
|
||||||
|
$scope[list.iterator + 'SearchField'] = 'scm_type';
|
||||||
|
$scope[list.iterator + 'SelectShow'] = true;
|
||||||
|
$scope[list.iterator + 'SearchSelectOpts'] = list.fields.scm_type.searchOptions;
|
||||||
|
$scope[list.iterator + 'SearchFieldLabel'] = list.fields.scm_type.label.replace(/<br\>/g, ' ');
|
||||||
|
for (opt in list.fields.scm_type.searchOptions) {
|
||||||
|
if (list.fields.scm_type.searchOptions[opt].value === $stateParams.scm_type) {
|
||||||
|
$scope[list.iterator + 'SearchSelectValue'] = list.fields.scm_type.searchOptions[opt];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ($stateParams.status) {
|
||||||
|
$scope[list.iterator + 'SearchType'] = '';
|
||||||
|
$scope[list.iterator + 'SearchValue'] = $stateParams.status;
|
||||||
|
$scope[list.iterator + 'SearchField'] = 'status';
|
||||||
|
$scope[list.iterator + 'SelectShow'] = true;
|
||||||
|
$scope[list.iterator + 'SearchFieldLabel'] = list.fields.status.label;
|
||||||
|
$scope[list.iterator + 'SearchSelectOpts'] = list.fields.status.searchOptions;
|
||||||
|
for (opt in list.fields.status.searchOptions) {
|
||||||
|
if (list.fields.status.searchOptions[opt].value === $stateParams.status) {
|
||||||
|
$scope[list.iterator + 'SearchSelectValue'] = list.fields.status.searchOptions[opt];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$scope.search(list.iterator);
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($scope.removeChoicesReadyList) {
|
||||||
|
$scope.removeChoicesReadyList();
|
||||||
|
}
|
||||||
|
$scope.removeChoicesReadyList = $scope.$on('choicesReadyProjectList', function () {
|
||||||
|
choiceCount++;
|
||||||
|
if (choiceCount === 2) {
|
||||||
|
$scope.$emit('choicesCompleteProjectList');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Load options for status --used in search
|
||||||
|
GetChoices({
|
||||||
|
scope: $scope,
|
||||||
|
url: projBase,
|
||||||
|
field: 'status',
|
||||||
|
variable: 'project_status_options',
|
||||||
|
callback: 'choicesReadyProjectList'
|
||||||
|
});
|
||||||
|
|
||||||
|
// Load the list of options for Kind
|
||||||
|
GetChoices({
|
||||||
|
scope: $scope,
|
||||||
|
url: projBase,
|
||||||
|
field: 'scm_type',
|
||||||
|
variable: 'project_scm_type_options',
|
||||||
|
callback: 'choicesReadyProjectList'
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
$scope.editProject = function (id) {
|
||||||
|
$state.transitionTo('projects.edit', {id: id});
|
||||||
|
};
|
||||||
|
|
||||||
|
if ($scope.removeGoToJobDetails) {
|
||||||
|
$scope.removeGoToJobDetails();
|
||||||
|
}
|
||||||
|
$scope.removeGoToJobDetails = $scope.$on('GoToJobDetails', function(e, data) {
|
||||||
|
if (data.summary_fields.current_update || data.summary_fields.last_update) {
|
||||||
|
|
||||||
|
Wait('start');
|
||||||
|
|
||||||
|
// Grab the id from summary_fields
|
||||||
|
var id = (data.summary_fields.current_update) ? data.summary_fields.current_update.id : data.summary_fields.last_update.id;
|
||||||
|
|
||||||
|
$state.go('scmUpdateStdout', {id: id});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Alert('No Updates Available', 'There is no SCM update information available for this project. An update has not yet been ' +
|
||||||
|
' completed. If you have not already done so, start an update for this project.', 'alert-info');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$scope.showSCMStatus = function (id) {
|
||||||
|
// Refresh the project list
|
||||||
|
var project = Find({ list: $scope.projects, key: 'id', val: id });
|
||||||
|
if (Empty(project.scm_type) || project.scm_type === 'Manual') {
|
||||||
|
Alert('No SCM Configuration', 'The selected project is not configured for SCM. To configure for SCM, edit the project and provide SCM settings, ' +
|
||||||
|
'and then run an update.', 'alert-info');
|
||||||
|
} else {
|
||||||
|
// Refresh what we have in memory to insure we're accessing the most recent status record
|
||||||
|
Rest.setUrl(project.url);
|
||||||
|
Rest.get()
|
||||||
|
.success(function(data) {
|
||||||
|
$scope.$emit('GoToJobDetails', data);
|
||||||
|
})
|
||||||
|
.error(function(data, status) {
|
||||||
|
ProcessErrors($scope, data, status, null, { hdr: 'Error!',
|
||||||
|
msg: 'Project lookup failed. GET returned: ' + status });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if ($scope.removeCancelUpdate) {
|
||||||
|
$scope.removeCancelUpdate();
|
||||||
|
}
|
||||||
|
$scope.removeCancelUpdate = $scope.$on('Cancel_Update', function (e, url) {
|
||||||
|
// Cancel the project update process
|
||||||
|
Rest.setUrl(url);
|
||||||
|
Rest.post()
|
||||||
|
.success(function () {
|
||||||
|
Alert('SCM Update Cancel', 'Your request to cancel the update was submitted to the task manager.', 'alert-info');
|
||||||
|
$scope.refresh();
|
||||||
|
})
|
||||||
|
.error(function (data, status) {
|
||||||
|
ProcessErrors($scope, data, status, null, { hdr: 'Error!', msg: 'Call to ' + url + ' failed. POST status: ' + status });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($scope.removeCheckCancel) {
|
||||||
|
$scope.removeCheckCancel();
|
||||||
|
}
|
||||||
|
$scope.removeCheckCancel = $scope.$on('Check_Cancel', function (e, data) {
|
||||||
|
// Check that we 'can' cancel the update
|
||||||
|
var url = data.related.cancel;
|
||||||
|
Rest.setUrl(url);
|
||||||
|
Rest.get()
|
||||||
|
.success(function (data) {
|
||||||
|
if (data.can_cancel) {
|
||||||
|
$scope.$emit('Cancel_Update', url);
|
||||||
|
} else {
|
||||||
|
Alert('Cancel Not Allowed', 'Either you do not have access or the SCM update process completed. ' +
|
||||||
|
'Click the <em>Refresh</em> button to view the latest status.', 'alert-info', null, null, null, null, true);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.error(function (data, status) {
|
||||||
|
ProcessErrors($scope, data, status, null, { hdr: 'Error!', msg: 'Call to ' + url + ' failed. GET status: ' + status });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$scope.cancelUpdate = function (id, name) {
|
||||||
|
Rest.setUrl(GetBasePath("projects") + id);
|
||||||
|
Rest.get()
|
||||||
|
.success(function (data) {
|
||||||
|
if (data.related.current_update) {
|
||||||
|
Rest.setUrl(data.related.current_update);
|
||||||
|
Rest.get()
|
||||||
|
.success(function (data) {
|
||||||
|
$scope.$emit('Check_Cancel', data);
|
||||||
|
})
|
||||||
|
.error(function (data, status) {
|
||||||
|
ProcessErrors($scope, data, status, null, { hdr: 'Error!',
|
||||||
|
msg: 'Call to ' + data.related.current_update + ' failed. GET status: ' + status });
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Alert('Update Not Found', 'An SCM update does not appear to be running for project: ' + $filter('sanitize')(name) + '. Click the <em>Refresh</em> ' +
|
||||||
|
'button to view the latest status.', 'alert-info',undefined,undefined,undefined,undefined,true);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.error(function (data, status) {
|
||||||
|
ProcessErrors($scope, data, status, null, { hdr: 'Error!',
|
||||||
|
msg: 'Call to get project failed. GET status: ' + status });
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.refresh = function () {
|
||||||
|
$scope.search(list.iterator);
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.SCMUpdate = function (project_id, event) {
|
||||||
|
try {
|
||||||
|
$(event.target).tooltip('hide');
|
||||||
|
}
|
||||||
|
catch(e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
$scope.projects.every(function(project) {
|
||||||
|
if (project.id === project_id) {
|
||||||
|
if (project.scm_type === "Manual" || Empty(project.scm_type)) {
|
||||||
|
// Do not respond. Button appears greyed out as if it is disabled. Not disabled though, because we need mouse over event
|
||||||
|
// to work. So user can click, but we just won't do anything.
|
||||||
|
//Alert('Missing SCM Setup', 'Before running an SCM update, edit the project and provide the SCM access information.', 'alert-info');
|
||||||
|
} else if (project.status === 'updating' || project.status === 'running' || project.status === 'pending') {
|
||||||
|
// Alert('Update in Progress', 'The SCM update process is running. Use the Refresh button to monitor the status.', 'alert-info');
|
||||||
|
} else {
|
||||||
|
ProjectUpdate({ scope: $scope, project_id: project.id });
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.editSchedules = function(id) {
|
||||||
|
var project = Find({ list: $scope.projects, key: 'id', val: id });
|
||||||
|
if (project.scm_type === "Manual" || Empty(project.scm_type)) {
|
||||||
|
// Nothing to do
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$location.path('/projects/' + id + '/schedules');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.formCancel = function(){
|
||||||
|
$state.go('organizations');
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
];
|
||||||
@@ -0,0 +1,93 @@
|
|||||||
|
/*************************************************
|
||||||
|
* Copyright (c) 2016 Ansible, Inc.
|
||||||
|
*
|
||||||
|
* All Rights Reserved
|
||||||
|
*************************************************/
|
||||||
|
|
||||||
|
export default ['$scope', '$rootScope', '$location', '$log', '$stateParams',
|
||||||
|
'Rest', 'Alert', 'TeamList', 'generateList', 'Prompt', 'SearchInit', 'PaginateInit',
|
||||||
|
'ReturnToCaller', 'ClearScope', 'ProcessErrors', 'SetTeamListeners', 'GetBasePath',
|
||||||
|
'SelectionInit', 'Wait', '$state', 'Refresh',
|
||||||
|
function($scope, $rootScope, $location, $log, $stateParams,
|
||||||
|
Rest, Alert, TeamList, GenerateList, Prompt, SearchInit, PaginateInit,
|
||||||
|
ReturnToCaller, ClearScope, ProcessErrors, SetTeamListeners, GetBasePath,
|
||||||
|
SelectionInit, Wait, $state, Refresh) {
|
||||||
|
|
||||||
|
var list,
|
||||||
|
teamUrl,
|
||||||
|
orgBase = GetBasePath('organizations'),
|
||||||
|
generator = GenerateList;
|
||||||
|
|
||||||
|
// Go out and get the organization
|
||||||
|
Rest.setUrl(orgBase + $stateParams.organization_id);
|
||||||
|
Rest.get()
|
||||||
|
.success(function (data) {
|
||||||
|
// include name of item in listTitle
|
||||||
|
var listTitle = data.name + "<div class='List-titleLockup'></div>TEAMS";
|
||||||
|
|
||||||
|
$scope.$parent.activeCard = parseInt($stateParams.organization_id);
|
||||||
|
$scope.$parent.activeMode = 'teams';
|
||||||
|
$scope.organization_name = data.name;
|
||||||
|
$scope.org_id = data.id;
|
||||||
|
|
||||||
|
list = _.cloneDeep(TeamList);
|
||||||
|
list.emptyListText = "This list is populated by teams added from the <a ui-sref='teams.add'>Teams</a> section";
|
||||||
|
delete list.actions.add;
|
||||||
|
delete list.fieldActions.delete;
|
||||||
|
teamUrl = data.related.teams;
|
||||||
|
list.listTitle = listTitle;
|
||||||
|
list.basePath = teamUrl;
|
||||||
|
|
||||||
|
$scope.orgRelatedUrls = data.related;
|
||||||
|
|
||||||
|
generator.inject(list, { mode: 'edit', scope: $scope, cancelButton: true });
|
||||||
|
$rootScope.flashMessage = null;
|
||||||
|
|
||||||
|
$scope.$on("RefreshTeamsList", function() {
|
||||||
|
generator.inject(list, { mode: 'edit', scope: $scope, cancelButton: true });
|
||||||
|
Refresh({
|
||||||
|
scope: $scope,
|
||||||
|
set: 'teams',
|
||||||
|
iterator: 'team',
|
||||||
|
url: GetBasePath('teams') + "?order_by=name&page_size=" + $scope.team_page_size
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($scope.removePostRefresh) {
|
||||||
|
$scope.removePostRefresh();
|
||||||
|
}
|
||||||
|
$scope.removePostRefresh = $scope.$on('PostRefresh', function () {
|
||||||
|
// After a refresh, populate the organization name on each row
|
||||||
|
var i;
|
||||||
|
if ($scope.teams) {
|
||||||
|
for (i = 0; i < $scope.teams.length; i++) {
|
||||||
|
if ($scope.teams[i].summary_fields.organization) {
|
||||||
|
$scope.teams[i].organization_name = $scope.teams[i].summary_fields.organization.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
SearchInit({
|
||||||
|
scope: $scope,
|
||||||
|
set: 'teams',
|
||||||
|
list: list,
|
||||||
|
url: teamUrl
|
||||||
|
});
|
||||||
|
PaginateInit({
|
||||||
|
scope: $scope,
|
||||||
|
list: list,
|
||||||
|
url: teamUrl
|
||||||
|
});
|
||||||
|
$scope.search(list.iterator);
|
||||||
|
});
|
||||||
|
|
||||||
|
$scope.editTeam = function (id) {
|
||||||
|
$state.transitionTo('teams.edit', {team_id: id});
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.formCancel = function(){
|
||||||
|
$state.go('organizations');
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
/*************************************************
|
||||||
|
* Copyright (c) 2016 Ansible, Inc.
|
||||||
|
*
|
||||||
|
* All Rights Reserved
|
||||||
|
*************************************************/
|
||||||
|
|
||||||
|
export default ['$stateParams', '$scope', 'UserList', 'Rest', '$state', 'generateList', '$compile',
|
||||||
|
'SearchInit', 'PaginateInit', 'Wait', 'Prompt', 'ProcessErrors', 'GetBasePath',
|
||||||
|
function($stateParams, $scope, UserList, Rest, $state, GenerateList, $compile,
|
||||||
|
SearchInit, PaginateInit, Wait, Prompt, ProcessErrors, GetBasePath) {
|
||||||
|
|
||||||
|
var list,
|
||||||
|
url,
|
||||||
|
generator = GenerateList,
|
||||||
|
orgBase = GetBasePath('organizations');
|
||||||
|
|
||||||
|
Rest.setUrl(orgBase + $stateParams.organization_id);
|
||||||
|
Rest.get()
|
||||||
|
.success(function (data) {
|
||||||
|
// include name of item in listTitle
|
||||||
|
var listTitle = data.name + "<div class='List-titleLockup'></div>USERS";
|
||||||
|
|
||||||
|
$scope.$parent.activeCard = parseInt($stateParams.organization_id);
|
||||||
|
$scope.$parent.activeMode = 'users';
|
||||||
|
$scope.organization_name = data.name;
|
||||||
|
$scope.org_id = data.id;
|
||||||
|
|
||||||
|
list = _.cloneDeep(UserList);
|
||||||
|
list.emptyListText = "Please add items to this list";
|
||||||
|
delete list.actions.add;
|
||||||
|
list.searchRowActions = {
|
||||||
|
add: {
|
||||||
|
buttonContent: '+ ADD user',
|
||||||
|
awToolTip: 'Add existing user to organization',
|
||||||
|
actionClass: 'btn List-buttonSubmit',
|
||||||
|
ngClick: 'addUsers()'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
url = data.related.users;
|
||||||
|
list.listTitle = listTitle;
|
||||||
|
list.basePath = url;
|
||||||
|
|
||||||
|
$scope.orgRelatedUrls = data.related;
|
||||||
|
|
||||||
|
generator.inject(list, { mode: 'edit', scope: $scope, cancelButton: true });
|
||||||
|
|
||||||
|
SearchInit({
|
||||||
|
scope: $scope,
|
||||||
|
set: 'users',
|
||||||
|
list: list,
|
||||||
|
url: url
|
||||||
|
});
|
||||||
|
PaginateInit({
|
||||||
|
scope: $scope,
|
||||||
|
list: list,
|
||||||
|
url: url
|
||||||
|
});
|
||||||
|
$scope.search(list.iterator);
|
||||||
|
});
|
||||||
|
|
||||||
|
$scope.addUsers = function () {
|
||||||
|
$compile("<add-users class='AddUsers'></add-users>")($scope);
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.editUser = function (id) {
|
||||||
|
$state.transitionTo('users.edit', {user_id: id});
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.deleteUser = function (id, name) {
|
||||||
|
var action = function () {
|
||||||
|
$('#prompt-modal').modal('hide');
|
||||||
|
Wait('start');
|
||||||
|
var url = orgBase + $stateParams.organization_id + '/users/';
|
||||||
|
Rest.setUrl(url);
|
||||||
|
Rest.post({
|
||||||
|
id: id,
|
||||||
|
disassociate: true
|
||||||
|
}).success(function () {
|
||||||
|
$scope.search(list.iterator);
|
||||||
|
})
|
||||||
|
.error(function (data, status) {
|
||||||
|
ProcessErrors($scope, data, status, null, { hdr: 'Error!',
|
||||||
|
msg: 'Call to ' + url + ' failed. DELETE returned status: ' + status });
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Prompt({
|
||||||
|
hdr: 'Delete',
|
||||||
|
body: '<div class="Prompt-bodyQuery">Are you sure you want to remove the following user from this organization?</div><div class="Prompt-bodyTarget">' + name + '</div>',
|
||||||
|
action: action,
|
||||||
|
actionText: 'DELETE'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.formCancel = function(){
|
||||||
|
$state.go('organizations');
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
];
|
||||||
@@ -1,100 +0,0 @@
|
|||||||
export default ['$compile', '$scope', '$stateParams', '$state', 'Rest', 'UserList', 'InventoryList', 'JobTemplateList', 'TeamList', 'ProjectList', 'generateList', 'SearchInit', 'PaginateInit', function($compile, $scope, $stateParams, $state, Rest, UserList, InventoryList, JobTemplateList, TeamList, ProjectList, GenerateList, SearchInit, PaginateInit) {
|
|
||||||
|
|
||||||
var getList = function(mode) {
|
|
||||||
var list = {};
|
|
||||||
if (mode === 'users') {
|
|
||||||
list = _.cloneDeep(UserList);
|
|
||||||
list.emptyListText = "Please add items to this list";
|
|
||||||
list.actions.add.label = "Add a user to the organization";
|
|
||||||
list.actions.add.buttonContent = '+ ADD user';
|
|
||||||
list.actions.add.awToolTip = 'Add existing user to organization';
|
|
||||||
list.actions.add.ngClick = 'addUsers()';
|
|
||||||
} else if (mode === 'inventories') {
|
|
||||||
list = _.cloneDeep(InventoryList);
|
|
||||||
list.emptyListText = "List is empty";
|
|
||||||
delete list.actions.add;
|
|
||||||
} else if (mode === 'job_templates') {
|
|
||||||
list = _.cloneDeep(JobTemplateList);
|
|
||||||
list.emptyListText = "List is empty";
|
|
||||||
delete list.actions.add;
|
|
||||||
} else if (mode === 'teams') {
|
|
||||||
list = _.cloneDeep(TeamList);
|
|
||||||
list.emptyListText = "List is empty";
|
|
||||||
delete list.actions.add;
|
|
||||||
} else if (mode === 'projects') {
|
|
||||||
list = _.cloneDeep(ProjectList);
|
|
||||||
list.emptyListText = "List is empty";
|
|
||||||
delete list.actions.add;
|
|
||||||
} else if (mode === 'admins') {
|
|
||||||
list = _.cloneDeep(UserList);
|
|
||||||
list.emptyListText = "Please add items to this list";
|
|
||||||
list.actions.add.buttonContent = '+ ADD administrator';
|
|
||||||
list.actions.add.awToolTip = 'Add existing user to organization as administrator';
|
|
||||||
list.actions.add.ngClick = 'addUsers()';
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
};
|
|
||||||
|
|
||||||
var getUrl = function(mode, data) {
|
|
||||||
var url = "";
|
|
||||||
if (mode === 'users') {
|
|
||||||
url = data.related.users;
|
|
||||||
} else if (mode === 'inventories') {
|
|
||||||
url = data.related.inventories;
|
|
||||||
} else if (mode === 'job_templates') {
|
|
||||||
url = "/api/v1/job_templates/?project__organization=" + data.id;
|
|
||||||
} else if (mode === 'teams') {
|
|
||||||
url = data.related.teams;
|
|
||||||
} else if (mode === 'projects') {
|
|
||||||
url = data.related.projects;
|
|
||||||
} else if (mode === 'admins') {
|
|
||||||
url = data.related.admins;
|
|
||||||
}
|
|
||||||
return url;
|
|
||||||
};
|
|
||||||
|
|
||||||
Rest.setUrl("/api/v1/organizations/" + $stateParams.organization_id);
|
|
||||||
Rest.get()
|
|
||||||
.success(function (data) {
|
|
||||||
// include name of item in listTitle
|
|
||||||
var mode = $state.current.name.split(".")[1],
|
|
||||||
listTitle = data.name +
|
|
||||||
"<div class='List-titleLockup'></div>" +
|
|
||||||
mode.replace('_', ' '),
|
|
||||||
list,
|
|
||||||
url,
|
|
||||||
generator = GenerateList;
|
|
||||||
$scope.$parent.activeCard = parseInt($stateParams.organization_id);
|
|
||||||
$scope.$parent.activeMode = mode;
|
|
||||||
$scope.org_name = data.name;
|
|
||||||
$scope.org_id = data.id;
|
|
||||||
var listMode = (mode === 'admins') ? 'users' : mode;
|
|
||||||
|
|
||||||
list = getList(mode);
|
|
||||||
url = getUrl(mode, data);
|
|
||||||
list.listTitle = listTitle;
|
|
||||||
list.basePath = url;
|
|
||||||
|
|
||||||
$scope.orgRelatedUrls = data.related;
|
|
||||||
|
|
||||||
generator
|
|
||||||
.inject(list, { mode: 'edit', scope: $scope });
|
|
||||||
|
|
||||||
$scope.addUsers = function () {
|
|
||||||
$compile("<add-users class='AddUsers'></add-users>")($scope);
|
|
||||||
};
|
|
||||||
|
|
||||||
SearchInit({
|
|
||||||
scope: $scope,
|
|
||||||
set: listMode,
|
|
||||||
list: list,
|
|
||||||
url: url
|
|
||||||
});
|
|
||||||
PaginateInit({
|
|
||||||
scope: $scope,
|
|
||||||
list: list,
|
|
||||||
url: url
|
|
||||||
});
|
|
||||||
$scope.search(list.iterator);
|
|
||||||
});
|
|
||||||
}];
|
|
||||||
@@ -5,14 +5,19 @@
|
|||||||
*************************************************/
|
*************************************************/
|
||||||
|
|
||||||
import {templateUrl} from '../../shared/template-url/template-url.factory';
|
import {templateUrl} from '../../shared/template-url/template-url.factory';
|
||||||
import OrganizationsLinkout from './organizations-linkout.controller';
|
import OrganizationsAdmins from './controllers/organizations-admins.controller';
|
||||||
|
import OrganizationsInventories from './controllers/organizations-inventories.controller';
|
||||||
|
import OrganizationsJobTemplates from './controllers/organizations-job-templates.controller';
|
||||||
|
import OrganizationsProjects from './controllers/organizations-projects.controller';
|
||||||
|
import OrganizationsTeams from './controllers/organizations-teams.controller';
|
||||||
|
import OrganizationsUsers from './controllers/organizations-users.controller';
|
||||||
|
|
||||||
export default [
|
export default [
|
||||||
{
|
{
|
||||||
name: 'organizations.users',
|
name: 'organizations.users',
|
||||||
route: '/:organization_id/users',
|
route: '/:organization_id/users',
|
||||||
templateUrl: templateUrl('organizations/linkout/organizations-linkout'),
|
templateUrl: templateUrl('organizations/linkout/organizations-linkout'),
|
||||||
controller: OrganizationsLinkout,
|
controller: OrganizationsUsers,
|
||||||
data: {
|
data: {
|
||||||
activityStream: true,
|
activityStream: true,
|
||||||
activityStreamTarget: 'organization'
|
activityStreamTarget: 'organization'
|
||||||
@@ -20,9 +25,9 @@ export default [
|
|||||||
ncyBreadcrumb: {
|
ncyBreadcrumb: {
|
||||||
parent: function($scope) {
|
parent: function($scope) {
|
||||||
$scope.$parent.$emit("ReloadOrgListView");
|
$scope.$parent.$emit("ReloadOrgListView");
|
||||||
return "setup";
|
return "organizations.edit";
|
||||||
},
|
},
|
||||||
label: "ORGANIZATIONS"
|
label: "USERS"
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
features: ['FeaturesService', function(FeaturesService) {
|
features: ['FeaturesService', function(FeaturesService) {
|
||||||
@@ -34,7 +39,7 @@ export default [
|
|||||||
name: 'organizations.teams',
|
name: 'organizations.teams',
|
||||||
route: '/:organization_id/teams',
|
route: '/:organization_id/teams',
|
||||||
templateUrl: templateUrl('organizations/linkout/organizations-linkout'),
|
templateUrl: templateUrl('organizations/linkout/organizations-linkout'),
|
||||||
controller: OrganizationsLinkout,
|
controller: OrganizationsTeams,
|
||||||
data: {
|
data: {
|
||||||
activityStream: true,
|
activityStream: true,
|
||||||
activityStreamTarget: 'organization'
|
activityStreamTarget: 'organization'
|
||||||
@@ -42,9 +47,9 @@ export default [
|
|||||||
ncyBreadcrumb: {
|
ncyBreadcrumb: {
|
||||||
parent: function($scope) {
|
parent: function($scope) {
|
||||||
$scope.$parent.$emit("ReloadOrgListView");
|
$scope.$parent.$emit("ReloadOrgListView");
|
||||||
return "setup";
|
return "organizations.edit";
|
||||||
},
|
},
|
||||||
label: "ORGANIZATIONS"
|
label: "TEAMS"
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
features: ['FeaturesService', function(FeaturesService) {
|
features: ['FeaturesService', function(FeaturesService) {
|
||||||
@@ -56,7 +61,7 @@ export default [
|
|||||||
name: 'organizations.inventories',
|
name: 'organizations.inventories',
|
||||||
route: '/:organization_id/inventories',
|
route: '/:organization_id/inventories',
|
||||||
templateUrl: templateUrl('organizations/linkout/organizations-linkout'),
|
templateUrl: templateUrl('organizations/linkout/organizations-linkout'),
|
||||||
controller: OrganizationsLinkout,
|
controller: OrganizationsInventories,
|
||||||
data: {
|
data: {
|
||||||
activityStream: true,
|
activityStream: true,
|
||||||
activityStreamTarget: 'organization'
|
activityStreamTarget: 'organization'
|
||||||
@@ -64,9 +69,9 @@ export default [
|
|||||||
ncyBreadcrumb: {
|
ncyBreadcrumb: {
|
||||||
parent: function($scope) {
|
parent: function($scope) {
|
||||||
$scope.$parent.$emit("ReloadOrgListView");
|
$scope.$parent.$emit("ReloadOrgListView");
|
||||||
return "setup";
|
return "organizations.edit";
|
||||||
},
|
},
|
||||||
label: "ORGANIZATIONS"
|
label: "INVENTORIES"
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
features: ['FeaturesService', function(FeaturesService) {
|
features: ['FeaturesService', function(FeaturesService) {
|
||||||
@@ -78,7 +83,7 @@ export default [
|
|||||||
name: 'organizations.projects',
|
name: 'organizations.projects',
|
||||||
route: '/:organization_id/projects',
|
route: '/:organization_id/projects',
|
||||||
templateUrl: templateUrl('organizations/linkout/organizations-linkout'),
|
templateUrl: templateUrl('organizations/linkout/organizations-linkout'),
|
||||||
controller: OrganizationsLinkout,
|
controller: OrganizationsProjects,
|
||||||
data: {
|
data: {
|
||||||
activityStream: true,
|
activityStream: true,
|
||||||
activityStreamTarget: 'organization'
|
activityStreamTarget: 'organization'
|
||||||
@@ -86,9 +91,9 @@ export default [
|
|||||||
ncyBreadcrumb: {
|
ncyBreadcrumb: {
|
||||||
parent: function($scope) {
|
parent: function($scope) {
|
||||||
$scope.$parent.$emit("ReloadOrgListView");
|
$scope.$parent.$emit("ReloadOrgListView");
|
||||||
return "setup";
|
return "organizations.edit";
|
||||||
},
|
},
|
||||||
label: "ORGANIZATIONS"
|
label: "PROJECTS"
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
features: ['FeaturesService', function(FeaturesService) {
|
features: ['FeaturesService', function(FeaturesService) {
|
||||||
@@ -100,7 +105,7 @@ export default [
|
|||||||
name: 'organizations.job_templates',
|
name: 'organizations.job_templates',
|
||||||
route: '/:organization_id/job_templates',
|
route: '/:organization_id/job_templates',
|
||||||
templateUrl: templateUrl('organizations/linkout/organizations-linkout'),
|
templateUrl: templateUrl('organizations/linkout/organizations-linkout'),
|
||||||
controller: OrganizationsLinkout,
|
controller: OrganizationsJobTemplates,
|
||||||
data: {
|
data: {
|
||||||
activityStream: true,
|
activityStream: true,
|
||||||
activityStreamTarget: 'organization'
|
activityStreamTarget: 'organization'
|
||||||
@@ -108,9 +113,9 @@ export default [
|
|||||||
ncyBreadcrumb: {
|
ncyBreadcrumb: {
|
||||||
parent: function($scope) {
|
parent: function($scope) {
|
||||||
$scope.$parent.$emit("ReloadOrgListView");
|
$scope.$parent.$emit("ReloadOrgListView");
|
||||||
return "setup";
|
return "organizations.edit";
|
||||||
},
|
},
|
||||||
label: "ORGANIZATIONS"
|
label: "JOB TEMPLATES"
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
features: ['FeaturesService', function(FeaturesService) {
|
features: ['FeaturesService', function(FeaturesService) {
|
||||||
@@ -122,7 +127,7 @@ export default [
|
|||||||
name: 'organizations.admins',
|
name: 'organizations.admins',
|
||||||
route: '/:organization_id/admins',
|
route: '/:organization_id/admins',
|
||||||
templateUrl: templateUrl('organizations/linkout/organizations-linkout'),
|
templateUrl: templateUrl('organizations/linkout/organizations-linkout'),
|
||||||
controller: OrganizationsLinkout,
|
controller: OrganizationsAdmins,
|
||||||
data: {
|
data: {
|
||||||
activityStream: true,
|
activityStream: true,
|
||||||
activityStreamTarget: 'organization'
|
activityStreamTarget: 'organization'
|
||||||
@@ -130,9 +135,9 @@ export default [
|
|||||||
ncyBreadcrumb: {
|
ncyBreadcrumb: {
|
||||||
parent: function($scope) {
|
parent: function($scope) {
|
||||||
$scope.$parent.$emit("ReloadOrgListView");
|
$scope.$parent.$emit("ReloadOrgListView");
|
||||||
return "setup";
|
return "organizations.edit";
|
||||||
},
|
},
|
||||||
label: "ORGANIZATIONS"
|
label: "ADMINS"
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
features: ['FeaturesService', function(FeaturesService) {
|
features: ['FeaturesService', function(FeaturesService) {
|
||||||
|
|||||||
@@ -58,7 +58,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-lg-8 col-md-12 col-sm-12 col-xs-12">
|
<div class="col-lg-7 col-md-12 col-sm-12 col-xs-12">
|
||||||
<div class="TagSearch-tagSection">
|
<div class="TagSearch-tagSection">
|
||||||
<div class="TagSearch-flexContainer">
|
<div class="TagSearch-flexContainer">
|
||||||
<div class="TagSearch-tagContainer"
|
<div class="TagSearch-tagContainer"
|
||||||
|
|||||||
@@ -99,9 +99,9 @@
|
|||||||
import {templateUrl} from '../../shared/template-url/template-url.factory';
|
import {templateUrl} from '../../shared/template-url/template-url.factory';
|
||||||
|
|
||||||
export default ['$location', '$compile', '$rootScope', 'SearchWidget', 'PaginateWidget', 'Attr', 'Icon', 'getSearchHtml',
|
export default ['$location', '$compile', '$rootScope', 'SearchWidget', 'PaginateWidget', 'Attr', 'Icon', 'getSearchHtml',
|
||||||
'Column', 'DropDown', 'NavigationLink', 'SelectIcon',
|
'Column', 'DropDown', 'NavigationLink', 'SelectIcon', 'ActionButton',
|
||||||
function ($location, $compile, $rootScope, SearchWidget, PaginateWidget, Attr, Icon, getSearchHtml, Column, DropDown, NavigationLink,
|
function ($location, $compile, $rootScope, SearchWidget, PaginateWidget, Attr, Icon, getSearchHtml, Column, DropDown, NavigationLink,
|
||||||
SelectIcon) {
|
SelectIcon, ActionButton) {
|
||||||
return {
|
return {
|
||||||
|
|
||||||
setList: function (list) {
|
setList: function (list) {
|
||||||
@@ -363,10 +363,7 @@ export default ['$location', '$compile', '$rootScope', 'SearchWidget', 'Paginate
|
|||||||
html += "<div class=\"List-well\">\n";
|
html += "<div class=\"List-well\">\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show the "no items" box when loading is done and the user isn't actively searching and there are no results
|
html += (list.searchRowActions) ? "<div class='row'><div class=\"col-lg-8 col-md-8 col-sm-8 col-xs-12\">" : "";
|
||||||
html += "<div class=\"List-noItems\" ng-show=\"" + list.iterator + "Loading == false && " + list.iterator + "_active_search == false && " + list.iterator + "_total_rows < 1\">";
|
|
||||||
html += (list.emptyListText) ? list.emptyListText : "PLEASE ADD ITEMS TO THIS LIST";
|
|
||||||
html += "</div>";
|
|
||||||
if (options.showSearch=== undefined || options.showSearch === true) {
|
if (options.showSearch=== undefined || options.showSearch === true) {
|
||||||
var tagSearch = getSearchHtml
|
var tagSearch = getSearchHtml
|
||||||
.inject(getSearchHtml.getList(list),
|
.inject(getSearchHtml.getList(list),
|
||||||
@@ -381,12 +378,35 @@ export default ['$location', '$compile', '$rootScope', 'SearchWidget', 'Paginate
|
|||||||
${tagSearch}
|
${tagSearch}
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
}
|
||||||
|
if(list.searchRowActions) {
|
||||||
|
html += "</div><div class='col-lg-4 col-md-4 col-sm-4 col-xs-12'>";
|
||||||
|
|
||||||
|
var actionButtons = "";
|
||||||
|
Object.keys(list.searchRowActions || {})
|
||||||
|
.forEach(act => {
|
||||||
|
actionButtons += ActionButton(list.searchRowActions[act]);
|
||||||
|
});
|
||||||
|
html += `
|
||||||
|
<div class=\"list-actions\">
|
||||||
|
${actionButtons}
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
html += "</div></div>";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.showSearch=== undefined || options.showSearch === true) {
|
||||||
// Message for when a search returns no results. This should only get shown after a search is executed with no results.
|
// Message for when a search returns no results. This should only get shown after a search is executed with no results.
|
||||||
html += "<div class=\"row\" ng-show=\"" + list.iterator + "Loading == false && " + list.iterator + "_active_search == true && " + list.name + ".length == 0\">\n";
|
html += "<div class=\"row\" ng-show=\"" + list.iterator + "Loading == false && " + list.iterator + "_active_search == true && " + list.name + ".length == 0\">\n";
|
||||||
html += "<div class=\"col-lg-12 List-searchNoResults\">No records matched your search.</div>\n";
|
html += "<div class=\"col-lg-12 List-searchNoResults\">No records matched your search.</div>\n";
|
||||||
html += "</div>\n";
|
html += "</div>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Show the "no items" box when loading is done and the user isn't actively searching and there are no results
|
||||||
|
html += "<div class=\"List-noItems\" ng-show=\"" + list.iterator + "Loading == false && " + list.iterator + "_active_search == false && " + list.iterator + "_total_rows < 1\">";
|
||||||
|
html += (list.emptyListText) ? list.emptyListText : "PLEASE ADD ITEMS TO THIS LIST";
|
||||||
|
html += "</div>";
|
||||||
|
|
||||||
// Add a title and optionally a close button (used on Inventory->Groups)
|
// Add a title and optionally a close button (used on Inventory->Groups)
|
||||||
if (options.mode !== 'lookup' && list.showTitle) {
|
if (options.mode !== 'lookup' && list.showTitle) {
|
||||||
html += "<div class=\"form-title\">";
|
html += "<div class=\"form-title\">";
|
||||||
|
|||||||
Reference in New Issue
Block a user