mirror of
https://github.com/ansible/awx.git
synced 2026-01-11 10:00:01 -03:30
Merge pull request #1264 from kensible/688-orgCards-counts
688 org cards counts
This commit is contained in:
commit
cc98c6ce3c
@ -27,6 +27,7 @@ import {JobsListController} from './controllers/Jobs';
|
||||
import {PortalController} from './controllers/Portal';
|
||||
import systemTracking from './system-tracking/main';
|
||||
import inventoryScripts from './inventory-scripts/main';
|
||||
import organizations from './organizations/main';
|
||||
import permissions from './permissions/main';
|
||||
import managementJobs from './management-jobs/main';
|
||||
import jobDetail from './job-detail/main';
|
||||
@ -50,7 +51,9 @@ import lookUpHelper from './lookup/main';
|
||||
import JobTemplates from './job-templates/main';
|
||||
import {ScheduleEditController} from './controllers/Schedules';
|
||||
import {ProjectsList, ProjectsAdd, ProjectsEdit} from './controllers/Projects';
|
||||
import {OrganizationsList, OrganizationsAdd, OrganizationsEdit} from './controllers/Organizations';
|
||||
import OrganizationsList from './organizations/list/organizations-list.controller';
|
||||
import OrganizationsAdd from './organizations/add/organizations-add.controller';
|
||||
import OrganizationsEdit from './organizations/edit/organizations-edit.controller';
|
||||
import {InventoriesList, InventoriesAdd, InventoriesEdit, InventoriesManage} from './controllers/Inventories';
|
||||
import {AdminsList} from './controllers/Admins';
|
||||
import {UsersList, UsersAdd, UsersEdit} from './controllers/Users';
|
||||
@ -85,6 +88,7 @@ var tower = angular.module('Tower', [
|
||||
browserData.name,
|
||||
systemTracking.name,
|
||||
inventoryScripts.name,
|
||||
organizations.name,
|
||||
permissions.name,
|
||||
managementJobs.name,
|
||||
setupMenu.name,
|
||||
@ -428,61 +432,6 @@ var tower = angular.module('Tower', [
|
||||
}
|
||||
}).
|
||||
|
||||
state('organizations', {
|
||||
url: '/organizations',
|
||||
templateUrl: urlPrefix + 'partials/organizations.html',
|
||||
controller: OrganizationsList,
|
||||
data: {
|
||||
activityStream: true,
|
||||
activityStreamTarget: 'organization'
|
||||
},
|
||||
ncyBreadcrumb: {
|
||||
parent: function($scope) {
|
||||
$scope.$parent.$emit("ReloadOrgListView");
|
||||
return "setup";
|
||||
},
|
||||
label: "ORGANIZATIONS"
|
||||
},
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
state('organizations.add', {
|
||||
url: '/add',
|
||||
templateUrl: urlPrefix + 'partials/organizations.crud.html',
|
||||
controller: OrganizationsAdd,
|
||||
ncyBreadcrumb: {
|
||||
parent: "organizations",
|
||||
label: "CREATE ORGANIZATION"
|
||||
},
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
state('organizations.edit', {
|
||||
url: '/:organization_id',
|
||||
templateUrl: urlPrefix + 'partials/organizations.crud.html',
|
||||
controller: OrganizationsEdit,
|
||||
data: {
|
||||
activityStreamId: 'organization_id'
|
||||
},
|
||||
ncyBreadcrumb: {
|
||||
parent: "organizations",
|
||||
label: "{{name}}"
|
||||
},
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
}).
|
||||
|
||||
state('organizationAdmins', {
|
||||
url: '/organizations/:organization_id/admins',
|
||||
templateUrl: urlPrefix + 'partials/organizations.html',
|
||||
|
||||
@ -1,382 +0,0 @@
|
||||
/*************************************************
|
||||
* Copyright (c) 2015 Ansible, Inc.
|
||||
*
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
/**
|
||||
* @ngdoc function
|
||||
* @name controllers.function:Organizations
|
||||
* @description This controller's for the Organizations page
|
||||
*/
|
||||
|
||||
|
||||
export function OrganizationsList($stateParams, $scope, $rootScope, $location,
|
||||
$log, $compile, Rest, PaginateWidget, PaginateInit, SearchInit, OrganizationList, Alert, Prompt, ClearScope, ProcessErrors, GetBasePath, Wait,
|
||||
$state) {
|
||||
|
||||
ClearScope();
|
||||
|
||||
var defaultUrl = GetBasePath('organizations'),
|
||||
list = OrganizationList,
|
||||
pageSize = $scope.orgCount;
|
||||
|
||||
PaginateInit({
|
||||
scope: $scope,
|
||||
list: list,
|
||||
url: defaultUrl,
|
||||
pageSize: pageSize,
|
||||
});
|
||||
SearchInit({
|
||||
scope: $scope,
|
||||
list: list,
|
||||
url: defaultUrl,
|
||||
});
|
||||
|
||||
$scope.search(list.iterator);
|
||||
|
||||
$scope.PaginateWidget = PaginateWidget({
|
||||
iterator: list.iterator,
|
||||
set: 'organizations'
|
||||
});
|
||||
|
||||
var paginationContainer = $('#pagination-container');
|
||||
paginationContainer.html($scope.PaginateWidget);
|
||||
$compile(paginationContainer.contents())($scope)
|
||||
|
||||
var parseCardData = function (cards) {
|
||||
return cards.map(function (card) {
|
||||
var val = {};
|
||||
val.name = card.name;
|
||||
val.id = card.id;
|
||||
if (card.id + "" === cards.activeCard) {
|
||||
val.isActiveCard = true;
|
||||
}
|
||||
val.description = card.description || undefined;
|
||||
val.links = [];
|
||||
val.links.push({
|
||||
href: card.related.users,
|
||||
name: "USERS"
|
||||
});
|
||||
val.links.push({
|
||||
href: card.related.teams,
|
||||
name: "TEAMS"
|
||||
});
|
||||
val.links.push({
|
||||
href: card.related.inventories,
|
||||
name: "INVENTORIES"
|
||||
});
|
||||
val.links.push({
|
||||
href: card.related.projects,
|
||||
name: "PROJECTS"
|
||||
});
|
||||
val.links.push({
|
||||
href: card.related.job_templates,
|
||||
name: "JOB TEMPLATES"
|
||||
});
|
||||
val.links.push({
|
||||
href: card.related.admins,
|
||||
name: "ADMINS"
|
||||
});
|
||||
return val;
|
||||
});
|
||||
};
|
||||
|
||||
var getOrganization = function (id) {
|
||||
Rest.setUrl(defaultUrl);
|
||||
Rest.get()
|
||||
.success(function (data) {
|
||||
data.results.activeCard = id;
|
||||
$scope.orgCount = data.count;
|
||||
$scope.orgCards = parseCardData(data.results);
|
||||
Wait("stop");
|
||||
})
|
||||
.error(function (data, status) {
|
||||
ProcessErrors($scope, data, status, null, { hdr: 'Error!',
|
||||
msg: 'Call to ' + defaultUrl + ' failed. DELETE returned status: ' + status });
|
||||
});
|
||||
};
|
||||
|
||||
$scope.$on("ReloadOrgListView", function() {
|
||||
if ($state.$current.self.name === "organizations") {
|
||||
delete $scope.activeCard;
|
||||
if ($scope.orgCards) {
|
||||
$scope.orgCards = $scope.orgCards.map(function (card) {
|
||||
delete card.isActiveCard;
|
||||
return card;
|
||||
});
|
||||
}
|
||||
$scope.hideListHeader = false;
|
||||
}
|
||||
});
|
||||
|
||||
$scope.$on("ReloadOrganzationCards", function(e, id) {
|
||||
$scope.activeCard = id;
|
||||
getOrganization(id);
|
||||
});
|
||||
|
||||
$scope.$on("HideOrgListHeader", function() {
|
||||
$scope.hideListHeader = true;
|
||||
});
|
||||
|
||||
$scope.$on("ShowOrgListHeader", function() {
|
||||
$scope.hideListHeader = false;
|
||||
});
|
||||
|
||||
getOrganization();
|
||||
|
||||
$rootScope.flashMessage = null;
|
||||
|
||||
if ($scope.removePostRefresh) {
|
||||
$scope.removePostRefresh();
|
||||
}
|
||||
$scope.removePostRefresh = $scope.$on('PostRefresh', function () {
|
||||
// Cleanup after a delete
|
||||
Wait('stop');
|
||||
$('#prompt-modal').modal('hide');
|
||||
});
|
||||
|
||||
$scope.addOrganization = function () {
|
||||
$state.transitionTo('organizations.add');
|
||||
};
|
||||
|
||||
$scope.editOrganization = function (id) {
|
||||
$scope.activeCard = id;
|
||||
$state.transitionTo('organizations.edit', {organization_id: id});
|
||||
};
|
||||
|
||||
$scope.deleteOrganization = function (id, name) {
|
||||
|
||||
var action = function () {
|
||||
$('#prompt-modal').modal('hide');
|
||||
Wait('start');
|
||||
var url = defaultUrl + id + '/';
|
||||
Rest.setUrl(url);
|
||||
Rest.destroy()
|
||||
.success(function () {
|
||||
if ($state.current.name !== "organzations") {
|
||||
$state.transitionTo("organizations");
|
||||
}
|
||||
$scope.$emit("ReloadOrganzationCards");
|
||||
})
|
||||
.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 delete the organization below?</div><div class="Prompt-bodyTarget">' + name + '</div>',
|
||||
action: action,
|
||||
actionText: 'DELETE'
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
OrganizationsList.$inject = ['$stateParams', '$scope', '$rootScope',
|
||||
'$location', '$log', '$compile', 'Rest', 'PaginateWidget', 'PaginateInit', 'SearchInit', 'OrganizationList', 'Alert', 'Prompt', 'ClearScope',
|
||||
'ProcessErrors', 'GetBasePath', 'Wait',
|
||||
'$state'
|
||||
];
|
||||
|
||||
|
||||
export function OrganizationsAdd($scope, $rootScope, $compile, $location, $log,
|
||||
$stateParams, OrganizationForm, GenerateForm, Rest, Alert, ProcessErrors,
|
||||
ClearScope, GetBasePath, ReturnToCaller, Wait, $state) {
|
||||
|
||||
ClearScope();
|
||||
|
||||
// Inject dynamic view
|
||||
var generator = GenerateForm,
|
||||
form = OrganizationForm,
|
||||
base = $location.path().replace(/^\//, '').split('/')[0];
|
||||
|
||||
generator.inject(form, { mode: 'add', related: false, scope: $scope});
|
||||
generator.reset();
|
||||
|
||||
$scope.$emit("HideOrgListHeader");
|
||||
|
||||
// Save
|
||||
$scope.formSave = function () {
|
||||
generator.clearApiErrors();
|
||||
Wait('start');
|
||||
var url = GetBasePath(base);
|
||||
url += (base !== 'organizations') ? $stateParams.project_id + '/organizations/' : '';
|
||||
Rest.setUrl(url);
|
||||
Rest.post({ name: $scope.name, description: $scope.description })
|
||||
.success(function (data) {
|
||||
Wait('stop');
|
||||
$scope.$emit("ReloadOrganzationCards", data.id);
|
||||
if (base === 'organizations') {
|
||||
$rootScope.flashMessage = "New organization successfully created!";
|
||||
$location.path('/organizations/' + data.id);
|
||||
} else {
|
||||
ReturnToCaller(1);
|
||||
}
|
||||
})
|
||||
.error(function (data, status) {
|
||||
ProcessErrors($scope, data, status, form, { hdr: 'Error!',
|
||||
msg: 'Failed to add new organization. Post returned status: ' + status });
|
||||
});
|
||||
};
|
||||
|
||||
$scope.formCancel = function () {
|
||||
$scope.$emit("ReloadOrganzationCards");
|
||||
$scope.$emit("ShowOrgListHeader");
|
||||
$state.transitionTo('organizations');
|
||||
};
|
||||
}
|
||||
|
||||
OrganizationsAdd.$inject = ['$scope', '$rootScope', '$compile', '$location',
|
||||
'$log', '$stateParams', 'OrganizationForm', 'GenerateForm', 'Rest', 'Alert',
|
||||
'ProcessErrors', 'ClearScope', 'GetBasePath', 'ReturnToCaller', 'Wait',
|
||||
'$state'
|
||||
];
|
||||
|
||||
|
||||
export function OrganizationsEdit($scope, $rootScope, $compile, $location, $log,
|
||||
$stateParams, OrganizationForm, GenerateForm, Rest, Alert, ProcessErrors,
|
||||
RelatedSearchInit, RelatedPaginateInit, Prompt, ClearScope, GetBasePath,
|
||||
Wait, $state) {
|
||||
|
||||
ClearScope();
|
||||
|
||||
// Inject dynamic view
|
||||
var form = OrganizationForm,
|
||||
generator = GenerateForm,
|
||||
defaultUrl = GetBasePath('organizations'),
|
||||
base = $location.path().replace(/^\//, '').split('/')[0],
|
||||
master = {},
|
||||
id = $stateParams.organization_id,
|
||||
relatedSets = {};
|
||||
|
||||
$scope.$emit("HideOrgListHeader");
|
||||
|
||||
$scope.$emit("ReloadOrganzationCards", id);
|
||||
|
||||
$scope.organization_id = id;
|
||||
|
||||
generator.inject(form, { mode: 'edit', related: true, scope: $scope});
|
||||
generator.reset();
|
||||
|
||||
// After the Organization is loaded, retrieve each related set
|
||||
if ($scope.organizationLoadedRemove) {
|
||||
$scope.organizationLoadedRemove();
|
||||
}
|
||||
$scope.organizationLoadedRemove = $scope.$on('organizationLoaded', function () {
|
||||
for (var set in relatedSets) {
|
||||
$scope.search(relatedSets[set].iterator);
|
||||
}
|
||||
Wait('stop');
|
||||
});
|
||||
|
||||
// Retrieve detail record and prepopulate the form
|
||||
Wait('start');
|
||||
Rest.setUrl(defaultUrl + id + '/');
|
||||
Rest.get()
|
||||
.success(function (data) {
|
||||
var fld, related, set;
|
||||
$scope.organization_name = data.name;
|
||||
for (fld in form.fields) {
|
||||
if (data[fld]) {
|
||||
$scope[fld] = data[fld];
|
||||
master[fld] = data[fld];
|
||||
}
|
||||
}
|
||||
related = data.related;
|
||||
for (set in form.related) {
|
||||
if (related[set]) {
|
||||
relatedSets[set] = {
|
||||
url: related[set],
|
||||
iterator: form.related[set].iterator
|
||||
};
|
||||
}
|
||||
}
|
||||
// Initialize related search functions. Doing it here to make sure relatedSets object is populated.
|
||||
RelatedSearchInit({ scope: $scope, form: form, relatedSets: relatedSets });
|
||||
RelatedPaginateInit({ scope: $scope, relatedSets: relatedSets });
|
||||
$scope.$emit('organizationLoaded');
|
||||
})
|
||||
.error(function (data, status) {
|
||||
ProcessErrors($scope, data, status, form, { hdr: 'Error!',
|
||||
msg: 'Failed to retrieve organization: ' + $stateParams.id + '. GET status: ' + status });
|
||||
});
|
||||
|
||||
|
||||
// Save changes to the parent
|
||||
$scope.formSave = function () {
|
||||
var fld, params = {};
|
||||
generator.clearApiErrors();
|
||||
Wait('start');
|
||||
for (fld in form.fields) {
|
||||
params[fld] = $scope[fld];
|
||||
}
|
||||
Rest.setUrl(defaultUrl + id + '/');
|
||||
Rest.put(params)
|
||||
.success(function (data) {
|
||||
Wait('stop');
|
||||
$scope.organization_name = $scope.name;
|
||||
master = params;
|
||||
$rootScope.flashMessage = "Your changes were successfully saved!";
|
||||
$scope.$emit("ReloadOrganzationCards", data.id);
|
||||
})
|
||||
.error(function (data, status) {
|
||||
ProcessErrors($scope, data, status, OrganizationForm, { hdr: 'Error!',
|
||||
msg: 'Failed to update organization: ' + id + '. PUT status: ' + status });
|
||||
});
|
||||
};
|
||||
|
||||
$scope.formCancel = function () {
|
||||
$scope.$emit("ReloadOrganzationCards");
|
||||
$scope.$emit("ShowOrgListHeader");
|
||||
$state.transitionTo('organizations');
|
||||
};
|
||||
|
||||
// Related set: Add button
|
||||
$scope.add = function (set) {
|
||||
$rootScope.flashMessage = null;
|
||||
$location.path('/' + base + '/' + $stateParams.organization_id + '/' + set);
|
||||
};
|
||||
|
||||
// Related set: Edit button
|
||||
$scope.edit = function (set, id) {
|
||||
$rootScope.flashMessage = null;
|
||||
$location.path('/' + set + '/' + id);
|
||||
};
|
||||
|
||||
// Related set: Delete button
|
||||
$scope['delete'] = function (set, itm_id, name, title) {
|
||||
$rootScope.flashMessage = null;
|
||||
|
||||
var action = function () {
|
||||
Wait('start');
|
||||
var url = defaultUrl + $stateParams.organization_id + '/' + set + '/';
|
||||
Rest.setUrl(url);
|
||||
Rest.post({ id: itm_id, disassociate: 1 })
|
||||
.success(function () {
|
||||
$('#prompt-modal').modal('hide');
|
||||
$scope.search(form.related[set].iterator);
|
||||
})
|
||||
.error(function (data, status) {
|
||||
$('#prompt-modal').modal('hide');
|
||||
ProcessErrors($scope, data, status, null, { hdr: 'Error!',
|
||||
msg: 'Call to ' + url + ' failed. POST returned status: ' + status });
|
||||
});
|
||||
};
|
||||
|
||||
Prompt({
|
||||
hdr: 'Delete',
|
||||
body: '<div class="Prompt-bodyQuery">Are you sure you want to remove the ' + title + ' below from ' + $scope.name + '?</div><div class="Prompt-bodyTarget">' + name + '</div>',
|
||||
action: action,
|
||||
actionText: 'DELETE'
|
||||
});
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
OrganizationsEdit.$inject = ['$scope', '$rootScope', '$compile', '$location',
|
||||
'$log', '$stateParams', 'OrganizationForm', 'GenerateForm', 'Rest', 'Alert',
|
||||
'ProcessErrors', 'RelatedSearchInit', 'RelatedPaginateInit', 'Prompt',
|
||||
'ClearScope', 'GetBasePath', 'Wait', '$state'
|
||||
];
|
||||
14
awx/ui/client/src/organizations/add/main.js
Normal file
14
awx/ui/client/src/organizations/add/main.js
Normal file
@ -0,0 +1,14 @@
|
||||
/*************************************************
|
||||
* Copyright (c) 2015 Ansible, Inc.
|
||||
*
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
import route from './organizations-add.route';
|
||||
import controller from './organizations-add.controller';
|
||||
|
||||
export default
|
||||
angular.module('organizationsAdd', [])
|
||||
.run(['$stateExtender', function($stateExtender) {
|
||||
$stateExtender.addState(route);
|
||||
}]);
|
||||
@ -0,0 +1,66 @@
|
||||
/*************************************************
|
||||
* Copyright (c) 2016 Ansible, Inc.
|
||||
*
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
export default ['$scope', '$rootScope', '$compile', '$location',
|
||||
'$log', '$stateParams', 'OrganizationForm', 'GenerateForm', 'Rest', 'Alert',
|
||||
'ProcessErrors', 'ClearScope', 'GetBasePath', 'ReturnToCaller', 'Wait',
|
||||
'$state',
|
||||
function($scope, $rootScope, $compile, $location, $log,
|
||||
$stateParams, OrganizationForm, GenerateForm, Rest, Alert, ProcessErrors,
|
||||
ClearScope, GetBasePath, ReturnToCaller, Wait, $state) {
|
||||
|
||||
ClearScope();
|
||||
|
||||
// Inject dynamic view
|
||||
var generator = GenerateForm,
|
||||
form = OrganizationForm,
|
||||
base = $location.path().replace(/^\//, '').split('/')[0];
|
||||
|
||||
generator.inject(form, {
|
||||
mode: 'add',
|
||||
related: false,
|
||||
scope: $scope
|
||||
});
|
||||
generator.reset();
|
||||
|
||||
$scope.$emit("HideOrgListHeader");
|
||||
|
||||
// Save
|
||||
$scope.formSave = function() {
|
||||
generator.clearApiErrors();
|
||||
Wait('start');
|
||||
var url = GetBasePath(base);
|
||||
url += (base !== 'organizations') ? $stateParams.project_id + '/organizations/' : '';
|
||||
Rest.setUrl(url);
|
||||
Rest.post({
|
||||
name: $scope.name,
|
||||
description: $scope.description
|
||||
})
|
||||
.success(function(data) {
|
||||
Wait('stop');
|
||||
$scope.$emit("ReloadOrganzationCards", data.id);
|
||||
if (base === 'organizations') {
|
||||
$rootScope.flashMessage = "New organization successfully created!";
|
||||
$location.path('/organizations/' + data.id);
|
||||
} else {
|
||||
ReturnToCaller(1);
|
||||
}
|
||||
})
|
||||
.error(function(data, status) {
|
||||
ProcessErrors($scope, data, status, form, {
|
||||
hdr: 'Error!',
|
||||
msg: 'Failed to add new organization. Post returned status: ' + status
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
$scope.formCancel = function() {
|
||||
$scope.$emit("ReloadOrganzationCards");
|
||||
$scope.$emit("ShowOrgListHeader");
|
||||
$state.transitionTo('organizations');
|
||||
};
|
||||
}
|
||||
]
|
||||
@ -0,0 +1,4 @@
|
||||
<div class="tab-pane" id="organizations">
|
||||
<div ui-view></div>
|
||||
<div ng-cloak id="htmlTemplate" class="Panel"></div>
|
||||
</div>
|
||||
@ -0,0 +1,24 @@
|
||||
/*************************************************
|
||||
* Copyright (c) 2016 Ansible, Inc.
|
||||
*
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
import {templateUrl} from '../../shared/template-url/template-url.factory';
|
||||
import OrganizationsAdd from './organizations-add.controller';
|
||||
|
||||
export default {
|
||||
name: 'organizations.add',
|
||||
route: '/add',
|
||||
templateUrl: templateUrl('organizations/add/organizations-add'),
|
||||
controller: OrganizationsAdd,
|
||||
ncyBreadcrumb: {
|
||||
parent: "organizations",
|
||||
label: "CREATE ORGANIZATION"
|
||||
},
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
};
|
||||
15
awx/ui/client/src/organizations/edit/main.js
Normal file
15
awx/ui/client/src/organizations/edit/main.js
Normal file
@ -0,0 +1,15 @@
|
||||
/*************************************************
|
||||
* Copyright (c) 2015 Ansible, Inc.
|
||||
*
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
import route from './organizations-edit.route';
|
||||
import controller from './organizations-edit.controller';
|
||||
|
||||
export default
|
||||
angular.module('organizationsEdit', [])
|
||||
.controller('organizationsEditController', controller)
|
||||
.run(['$stateExtender', function($stateExtender) {
|
||||
$stateExtender.addState(route);
|
||||
}]);
|
||||
@ -0,0 +1,150 @@
|
||||
/*************************************************
|
||||
* Copyright (c) 2016 Ansible, Inc.
|
||||
*
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
export default ['$scope', '$rootScope', '$compile', '$location',
|
||||
'$log', '$stateParams', 'OrganizationForm', 'GenerateForm', 'Rest', 'Alert',
|
||||
'ProcessErrors', 'RelatedSearchInit', 'RelatedPaginateInit', 'Prompt',
|
||||
'ClearScope', 'GetBasePath', 'Wait', '$state',
|
||||
function($scope, $rootScope, $compile, $location, $log,
|
||||
$stateParams, OrganizationForm, GenerateForm, Rest, Alert, ProcessErrors,
|
||||
RelatedSearchInit, RelatedPaginateInit, Prompt, ClearScope, GetBasePath,
|
||||
Wait, $state) {
|
||||
|
||||
ClearScope();
|
||||
|
||||
// Inject dynamic view
|
||||
var form = OrganizationForm,
|
||||
generator = GenerateForm,
|
||||
defaultUrl = GetBasePath('organizations'),
|
||||
base = $location.path().replace(/^\//, '').split('/')[0],
|
||||
master = {},
|
||||
id = $stateParams.organization_id,
|
||||
relatedSets = {};
|
||||
|
||||
$scope.$emit("HideOrgListHeader");
|
||||
|
||||
$scope.$emit("ReloadOrganzationCards", id);
|
||||
|
||||
$scope.organization_id = id;
|
||||
|
||||
generator.inject(form, { mode: 'edit', related: true, scope: $scope});
|
||||
generator.reset();
|
||||
|
||||
// After the Organization is loaded, retrieve each related set
|
||||
if ($scope.organizationLoadedRemove) {
|
||||
$scope.organizationLoadedRemove();
|
||||
}
|
||||
$scope.organizationLoadedRemove = $scope.$on('organizationLoaded', function () {
|
||||
for (var set in relatedSets) {
|
||||
$scope.search(relatedSets[set].iterator);
|
||||
}
|
||||
Wait('stop');
|
||||
});
|
||||
|
||||
// Retrieve detail record and prepopulate the form
|
||||
Wait('start');
|
||||
Rest.setUrl(defaultUrl + id + '/');
|
||||
Rest.get()
|
||||
.success(function (data) {
|
||||
var fld, related, set;
|
||||
$scope.organization_name = data.name;
|
||||
for (fld in form.fields) {
|
||||
if (data[fld]) {
|
||||
$scope[fld] = data[fld];
|
||||
master[fld] = data[fld];
|
||||
}
|
||||
}
|
||||
related = data.related;
|
||||
for (set in form.related) {
|
||||
if (related[set]) {
|
||||
relatedSets[set] = {
|
||||
url: related[set],
|
||||
iterator: form.related[set].iterator
|
||||
};
|
||||
}
|
||||
}
|
||||
// Initialize related search functions. Doing it here to make sure relatedSets object is populated.
|
||||
RelatedSearchInit({ scope: $scope, form: form, relatedSets: relatedSets });
|
||||
RelatedPaginateInit({ scope: $scope, relatedSets: relatedSets });
|
||||
$scope.$emit('organizationLoaded');
|
||||
})
|
||||
.error(function (data, status) {
|
||||
ProcessErrors($scope, data, status, form, { hdr: 'Error!',
|
||||
msg: 'Failed to retrieve organization: ' + $stateParams.id + '. GET status: ' + status });
|
||||
});
|
||||
|
||||
|
||||
// Save changes to the parent
|
||||
$scope.formSave = function () {
|
||||
var fld, params = {};
|
||||
generator.clearApiErrors();
|
||||
Wait('start');
|
||||
for (fld in form.fields) {
|
||||
params[fld] = $scope[fld];
|
||||
}
|
||||
Rest.setUrl(defaultUrl + id + '/');
|
||||
Rest.put(params)
|
||||
.success(function (data) {
|
||||
Wait('stop');
|
||||
$scope.organization_name = $scope.name;
|
||||
master = params;
|
||||
$rootScope.flashMessage = "Your changes were successfully saved!";
|
||||
$scope.$emit("ReloadOrganzationCards", data.id);
|
||||
})
|
||||
.error(function (data, status) {
|
||||
ProcessErrors($scope, data, status, OrganizationForm, { hdr: 'Error!',
|
||||
msg: 'Failed to update organization: ' + id + '. PUT status: ' + status });
|
||||
});
|
||||
};
|
||||
|
||||
$scope.formCancel = function () {
|
||||
$scope.$emit("ReloadOrganzationCards");
|
||||
$scope.$emit("ShowOrgListHeader");
|
||||
$state.transitionTo('organizations');
|
||||
};
|
||||
|
||||
// Related set: Add button
|
||||
$scope.add = function (set) {
|
||||
$rootScope.flashMessage = null;
|
||||
$location.path('/' + base + '/' + $stateParams.organization_id + '/' + set);
|
||||
};
|
||||
|
||||
// Related set: Edit button
|
||||
$scope.edit = function (set, id) {
|
||||
$rootScope.flashMessage = null;
|
||||
$location.path('/' + set + '/' + id);
|
||||
};
|
||||
|
||||
// Related set: Delete button
|
||||
$scope['delete'] = function (set, itm_id, name, title) {
|
||||
$rootScope.flashMessage = null;
|
||||
|
||||
var action = function () {
|
||||
Wait('start');
|
||||
var url = defaultUrl + $stateParams.organization_id + '/' + set + '/';
|
||||
Rest.setUrl(url);
|
||||
Rest.post({ id: itm_id, disassociate: 1 })
|
||||
.success(function () {
|
||||
$('#prompt-modal').modal('hide');
|
||||
$scope.search(form.related[set].iterator);
|
||||
})
|
||||
.error(function (data, status) {
|
||||
$('#prompt-modal').modal('hide');
|
||||
ProcessErrors($scope, data, status, null, { hdr: 'Error!',
|
||||
msg: 'Call to ' + url + ' failed. POST returned status: ' + status });
|
||||
});
|
||||
};
|
||||
|
||||
Prompt({
|
||||
hdr: 'Delete',
|
||||
body: '<div class="Prompt-bodyQuery">Are you sure you want to remove the ' + title + ' below from ' + $scope.name + '?</div><div class="Prompt-bodyTarget">' + name + '</div>',
|
||||
action: action,
|
||||
actionText: 'DELETE'
|
||||
});
|
||||
|
||||
};
|
||||
}
|
||||
]
|
||||
@ -0,0 +1,29 @@
|
||||
/*************************************************
|
||||
* Copyright (c) 2016 Ansible, Inc.
|
||||
*
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
import {
|
||||
templateUrl
|
||||
} from '../../shared/template-url/template-url.factory';
|
||||
import OrganizationsEdit from './organizations-edit.controller';
|
||||
|
||||
export default {
|
||||
name: 'organizations.edit',
|
||||
route: '/:organization_id',
|
||||
templateUrl: templateUrl('organizations/add/organizations-add'),
|
||||
controller: OrganizationsEdit,
|
||||
data: {
|
||||
activityStreamId: 'organization_id'
|
||||
},
|
||||
ncyBreadcrumb: {
|
||||
parent: "organizations",
|
||||
label: "{{name}}"
|
||||
},
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
};
|
||||
14
awx/ui/client/src/organizations/list/main.js
Normal file
14
awx/ui/client/src/organizations/list/main.js
Normal file
@ -0,0 +1,14 @@
|
||||
/*************************************************
|
||||
* Copyright (c) 2015 Ansible, Inc.
|
||||
*
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
import route from './organizations-list.route';
|
||||
import controller from './organizations-list.controller';
|
||||
|
||||
export default
|
||||
angular.module('organizationsList', [])
|
||||
.run(['$stateExtender', function($stateExtender) {
|
||||
$stateExtender.addState(route);
|
||||
}]);
|
||||
@ -0,0 +1,188 @@
|
||||
/*************************************************
|
||||
* Copyright (c) 2016 Ansible, Inc.
|
||||
*
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
export default ['$stateParams', '$scope', '$rootScope', '$location',
|
||||
'$log', '$compile', 'Rest', 'PaginateWidget', 'PaginateInit',
|
||||
'SearchInit', 'OrganizationList', 'Alert', 'Prompt', 'ClearScope',
|
||||
'ProcessErrors', 'GetBasePath', 'Wait',
|
||||
'$state',
|
||||
function($stateParams, $scope, $rootScope, $location,
|
||||
$log, $compile, Rest, PaginateWidget, PaginateInit,
|
||||
SearchInit, OrganizationList, Alert, Prompt, ClearScope,
|
||||
ProcessErrors, GetBasePath, Wait,
|
||||
$state) {
|
||||
|
||||
ClearScope();
|
||||
|
||||
var defaultUrl = GetBasePath('organizations'),
|
||||
list = OrganizationList,
|
||||
pageSize = $scope.orgCount;
|
||||
|
||||
PaginateInit({
|
||||
scope: $scope,
|
||||
list: list,
|
||||
url: defaultUrl,
|
||||
pageSize: pageSize,
|
||||
});
|
||||
SearchInit({
|
||||
scope: $scope,
|
||||
list: list,
|
||||
url: defaultUrl,
|
||||
});
|
||||
|
||||
$scope.search(list.iterator);
|
||||
|
||||
$scope.PaginateWidget = PaginateWidget({
|
||||
iterator: list.iterator,
|
||||
set: 'organizations'
|
||||
});
|
||||
|
||||
var paginationContainer = $('#pagination-container');
|
||||
paginationContainer.html($scope.PaginateWidget);
|
||||
$compile(paginationContainer.contents())($scope)
|
||||
|
||||
var parseCardData = function(cards) {
|
||||
return cards.map(function(card) {
|
||||
var val = {};
|
||||
val.name = card.name;
|
||||
val.id = card.id;
|
||||
if (card.id + "" === cards.activeCard) {
|
||||
val.isActiveCard = true;
|
||||
}
|
||||
val.description = card.description || undefined;
|
||||
val.links = [];
|
||||
val.links.push({
|
||||
href: card.related.users,
|
||||
name: "USERS",
|
||||
count: card.summary_fields.related_field_counts.users
|
||||
});
|
||||
val.links.push({
|
||||
href: card.related.teams,
|
||||
name: "TEAMS",
|
||||
count: card.summary_fields.related_field_counts.teams
|
||||
});
|
||||
val.links.push({
|
||||
href: card.related.inventories,
|
||||
name: "INVENTORIES",
|
||||
count: card.summary_fields.related_field_counts.inventories
|
||||
});
|
||||
val.links.push({
|
||||
href: card.related.projects,
|
||||
name: "PROJECTS",
|
||||
count: card.summary_fields.related_field_counts.projects
|
||||
});
|
||||
val.links.push({
|
||||
href: card.related.job_templates,
|
||||
name: "JOB TEMPLATES",
|
||||
count: card.summary_fields.related_field_counts.job_templates
|
||||
});
|
||||
val.links.push({
|
||||
href: card.related.admins,
|
||||
name: "ADMINS",
|
||||
count: card.summary_fields.related_field_counts.admins
|
||||
});
|
||||
return val;
|
||||
});
|
||||
};
|
||||
|
||||
var getOrganization = function(id) {
|
||||
Rest.setUrl(defaultUrl);
|
||||
Rest.get()
|
||||
.success(function(data) {
|
||||
data.results.activeCard = id;
|
||||
$scope.orgCount = data.count;
|
||||
$scope.orgCards = parseCardData(data.results);
|
||||
Wait("stop");
|
||||
})
|
||||
.error(function(data, status) {
|
||||
ProcessErrors($scope, data, status, null, {
|
||||
hdr: 'Error!',
|
||||
msg: 'Call to ' + defaultUrl + ' failed. DELETE returned status: ' + status
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
$scope.$on("ReloadOrgListView", function() {
|
||||
if ($state.$current.self.name === "organizations") {
|
||||
delete $scope.activeCard;
|
||||
if ($scope.orgCards) {
|
||||
$scope.orgCards = $scope.orgCards.map(function(card) {
|
||||
delete card.isActiveCard;
|
||||
return card;
|
||||
});
|
||||
}
|
||||
$scope.hideListHeader = false;
|
||||
}
|
||||
});
|
||||
|
||||
$scope.$on("ReloadOrganzationCards", function(e, id) {
|
||||
$scope.activeCard = id;
|
||||
getOrganization(id);
|
||||
});
|
||||
|
||||
$scope.$on("HideOrgListHeader", function() {
|
||||
$scope.hideListHeader = true;
|
||||
});
|
||||
|
||||
$scope.$on("ShowOrgListHeader", function() {
|
||||
$scope.hideListHeader = false;
|
||||
});
|
||||
|
||||
getOrganization();
|
||||
|
||||
$rootScope.flashMessage = null;
|
||||
|
||||
if ($scope.removePostRefresh) {
|
||||
$scope.removePostRefresh();
|
||||
}
|
||||
$scope.removePostRefresh = $scope.$on('PostRefresh', function() {
|
||||
// Cleanup after a delete
|
||||
Wait('stop');
|
||||
$('#prompt-modal').modal('hide');
|
||||
});
|
||||
|
||||
$scope.addOrganization = function() {
|
||||
$state.transitionTo('organizations.add');
|
||||
};
|
||||
|
||||
$scope.editOrganization = function(id) {
|
||||
$scope.activeCard = id;
|
||||
$state.transitionTo('organizations.edit', {
|
||||
organization_id: id
|
||||
});
|
||||
};
|
||||
|
||||
$scope.deleteOrganization = function(id, name) {
|
||||
|
||||
var action = function() {
|
||||
$('#prompt-modal').modal('hide');
|
||||
Wait('start');
|
||||
var url = defaultUrl + id + '/';
|
||||
Rest.setUrl(url);
|
||||
Rest.destroy()
|
||||
.success(function() {
|
||||
if ($state.current.name !== "organzations") {
|
||||
$state.transitionTo("organizations");
|
||||
}
|
||||
$scope.$emit("ReloadOrganzationCards");
|
||||
})
|
||||
.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 delete the organization below?</div><div class="Prompt-bodyTarget">' + name + '</div>',
|
||||
action: action,
|
||||
actionText: 'DELETE'
|
||||
});
|
||||
};
|
||||
}
|
||||
]
|
||||
@ -0,0 +1,62 @@
|
||||
<div class="tab-pane" id="organizations">
|
||||
<div ui-view></div>
|
||||
<div ng-cloak id="htmlTemplate" class="Panel" ng-hide="hideListHeader">
|
||||
<div class="List-header">
|
||||
<div class="List-title">
|
||||
<div class="List-titleText">
|
||||
organizations
|
||||
</div>
|
||||
<span class="badge List-titleBadge">
|
||||
{{ orgCount }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="List-actions">
|
||||
<button class="btn List-buttonSubmit"
|
||||
aw-tool-tip="Create a new organization"
|
||||
ng-click="addOrganization()">
|
||||
+ ADD
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="OrgCards">
|
||||
<div class="OrgCards-card"
|
||||
ng-class="{'OrgCards-card--selected': activeCard === card.id || card.isActiveCard }"
|
||||
ng-repeat="card in orgCards track by card.id">
|
||||
<div class="OrgCards-header">
|
||||
<h3 class="OrgCards-label">{{ card.name }}</h3>
|
||||
<div class="OrgCards-actionItems">
|
||||
<button class="OrgCards-actionItem
|
||||
List-actionButton"
|
||||
ng-class="{'List-editButton--selected': activeCard === card.id || card.isActiveCard }"
|
||||
ng-click="editOrganization(card.id)">
|
||||
<i class="OrgCards-actionItemIcon fa fa-pencil">
|
||||
</i>
|
||||
</button>
|
||||
<button class="OrgCards-actionItem List-actionButton
|
||||
List-actionButton--delete"
|
||||
ng-click="deleteOrganization(card.id, card.name)">
|
||||
<i class="OrgCards-actionItemIcon
|
||||
fa fa-trash-o">
|
||||
</i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<p class="OrgCards-description">{{ card.description || "Place organization description here" }}</p>
|
||||
<div class="OrgCards-links">
|
||||
<div class="OrgCards-link" ng-repeat="link in card.links">
|
||||
<span class="badge List-titleBadge
|
||||
OrgCards-linkBadge">
|
||||
{{ link.count }}
|
||||
</span>
|
||||
<a class="OrgCards-linkName"
|
||||
ng-href="{{ link.href }}">
|
||||
{{ link.name }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="pagination-container" ng-hide="organization_num_pages < 2">
|
||||
</div>
|
||||
</div>
|
||||
@ -0,0 +1,31 @@
|
||||
/*************************************************
|
||||
* Copyright (c) 2016 Ansible, Inc.
|
||||
*
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
import {templateUrl} from '../../shared/template-url/template-url.factory';
|
||||
import OrganizationsList from './organizations-list.controller';
|
||||
|
||||
export default {
|
||||
name: 'organizations',
|
||||
route: '/organizations',
|
||||
templateUrl: templateUrl('organizations/list/organizations-list'),
|
||||
controller: OrganizationsList,
|
||||
data: {
|
||||
activityStream: true,
|
||||
activityStreamTarget: 'organization'
|
||||
},
|
||||
ncyBreadcrumb: {
|
||||
parent: function($scope) {
|
||||
$scope.$parent.$emit("ReloadOrgListView");
|
||||
return "setup";
|
||||
},
|
||||
label: "ORGANIZATIONS"
|
||||
},
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
return FeaturesService.get();
|
||||
}]
|
||||
}
|
||||
};
|
||||
16
awx/ui/client/src/organizations/main.js
Normal file
16
awx/ui/client/src/organizations/main.js
Normal file
@ -0,0 +1,16 @@
|
||||
/*************************************************
|
||||
* Copyright (c) 2016 Ansible, Inc.
|
||||
*
|
||||
* All Rights Reserved
|
||||
*************************************************/
|
||||
|
||||
import organizationsList from './list/main';
|
||||
import organizationsAdd from './add/main';
|
||||
import organizationsEdit from './edit/main';
|
||||
|
||||
export default
|
||||
angular.module('organizations', [
|
||||
organizationsList.name,
|
||||
organizationsAdd.name,
|
||||
organizationsEdit.name,
|
||||
]);
|
||||
Loading…
x
Reference in New Issue
Block a user