mirror of
https://github.com/ansible/awx.git
synced 2026-01-13 19:10:07 -03:30
org cards implementation with rollups
This commit is contained in:
parent
c8d7778ed5
commit
3cee94c1e9
@ -27,6 +27,7 @@
|
||||
font-weight: bold;
|
||||
white-space: nowrap;
|
||||
padding-bottom: 20px;
|
||||
min-height: 40px;
|
||||
}
|
||||
|
||||
.Form-title--is_superuser{
|
||||
@ -69,6 +70,7 @@
|
||||
.Form-tabHolder{
|
||||
display: flex;
|
||||
margin-bottom: 20px;
|
||||
min-height: 30px;
|
||||
}
|
||||
|
||||
.Form-tab {
|
||||
|
||||
@ -569,9 +569,14 @@ var tower = angular.module('Tower', [
|
||||
}
|
||||
}).
|
||||
|
||||
state('organizations.cards', {
|
||||
url: '/foo',
|
||||
templateUrl: urlPrefix + 'organizations/cards.partial.html',
|
||||
}).
|
||||
|
||||
state('organizations.add', {
|
||||
url: '/add',
|
||||
templateUrl: urlPrefix + 'partials/organizations.html',
|
||||
templateUrl: urlPrefix + 'partials/organizations.crud.html',
|
||||
controller: OrganizationsAdd,
|
||||
ncyBreadcrumb: {
|
||||
parent: "organizations",
|
||||
@ -586,7 +591,7 @@ var tower = angular.module('Tower', [
|
||||
|
||||
state('organizations.edit', {
|
||||
url: '/:organization_id',
|
||||
templateUrl: urlPrefix + 'partials/organizations.html',
|
||||
templateUrl: urlPrefix + 'partials/organizations.crud.html',
|
||||
controller: OrganizationsEdit,
|
||||
resolve: {
|
||||
features: ['FeaturesService', function(FeaturesService) {
|
||||
|
||||
@ -12,27 +12,58 @@
|
||||
|
||||
|
||||
export function OrganizationsList($stateParams, $scope, $rootScope, $location,
|
||||
$log, Rest, Alert, Prompt, GenerateList, OrganizationList, SearchInit,
|
||||
PaginateInit, ClearScope, ProcessErrors, GetBasePath, SelectionInit, Wait,
|
||||
$log, Rest, Alert, Prompt, ClearScope, ProcessErrors, GetBasePath, Wait,
|
||||
Stream, $state) {
|
||||
|
||||
ClearScope();
|
||||
|
||||
var list = OrganizationList,
|
||||
generate = GenerateList,
|
||||
paths = $location.path().replace(/^\//, '').split('/'),
|
||||
mode = (paths[0] === 'organizations') ? 'edit' : 'select',
|
||||
defaultUrl = GetBasePath('organizations'),
|
||||
url;
|
||||
var defaultUrl = GetBasePath('organizations');
|
||||
|
||||
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;
|
||||
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("ReloadOrganzationCards", function(e, id) {
|
||||
$scope.activeCard = id;
|
||||
getOrganization(id);
|
||||
});
|
||||
|
||||
$scope.$on("HideOrgListHeader", function() {
|
||||
$scope.hideListHeader = true;
|
||||
});
|
||||
|
||||
$scope.$on("ShowOrgListHeader", function() {
|
||||
$scope.hideListHeader = false;
|
||||
});
|
||||
|
||||
getOrganization();
|
||||
|
||||
generate.inject(OrganizationList, { mode: mode, scope: $scope });
|
||||
$rootScope.flashMessage = null;
|
||||
|
||||
if (mode === 'select') {
|
||||
url = GetBasePath('projects') + $stateParams.project_id + '/organizations/';
|
||||
SelectionInit({ scope: $scope, list: list, url: url, returnToCaller: 1 });
|
||||
}
|
||||
|
||||
if ($scope.removePostRefresh) {
|
||||
$scope.removePostRefresh();
|
||||
}
|
||||
@ -42,20 +73,6 @@ export function OrganizationsList($stateParams, $scope, $rootScope, $location,
|
||||
$('#prompt-modal').modal('hide');
|
||||
});
|
||||
|
||||
// Initialize search and pagination, then load data
|
||||
SearchInit({
|
||||
scope: $scope,
|
||||
set: list.name,
|
||||
list: list,
|
||||
url: defaultUrl
|
||||
});
|
||||
PaginateInit({
|
||||
scope: $scope,
|
||||
list: list,
|
||||
url: defaultUrl
|
||||
});
|
||||
$scope.search(list.iterator);
|
||||
|
||||
$scope.showActivity = function () {
|
||||
Stream({ scope: $scope });
|
||||
};
|
||||
@ -65,6 +82,7 @@ export function OrganizationsList($stateParams, $scope, $rootScope, $location,
|
||||
};
|
||||
|
||||
$scope.editOrganization = function (id) {
|
||||
$scope.activeCard = id;
|
||||
$state.transitionTo('organizations.edit', {organization_id: id});
|
||||
};
|
||||
|
||||
@ -77,7 +95,10 @@ export function OrganizationsList($stateParams, $scope, $rootScope, $location,
|
||||
Rest.setUrl(url);
|
||||
Rest.destroy()
|
||||
.success(function () {
|
||||
$scope.search(list.iterator);
|
||||
if ($state.current.name !== "organzations") {
|
||||
$state.transitionTo("organizations");
|
||||
}
|
||||
$scope.$emit("ReloadOrganzationCards");
|
||||
})
|
||||
.error(function (data, status) {
|
||||
ProcessErrors($scope, data, status, null, { hdr: 'Error!',
|
||||
@ -94,9 +115,8 @@ export function OrganizationsList($stateParams, $scope, $rootScope, $location,
|
||||
}
|
||||
|
||||
OrganizationsList.$inject = ['$stateParams', '$scope', '$rootScope',
|
||||
'$location', '$log', 'Rest', 'Alert', 'Prompt', 'generateList',
|
||||
'OrganizationList', 'SearchInit', 'PaginateInit', 'ClearScope',
|
||||
'ProcessErrors', 'GetBasePath', 'SelectionInit', 'Wait',
|
||||
'$location', '$log', 'Rest', 'Alert', 'Prompt', 'ClearScope',
|
||||
'ProcessErrors', 'GetBasePath', 'Wait',
|
||||
'Stream', '$state'
|
||||
];
|
||||
|
||||
@ -115,6 +135,8 @@ export function OrganizationsAdd($scope, $rootScope, $compile, $location, $log,
|
||||
generator.inject(form, { mode: 'add', related: false, scope: $scope});
|
||||
generator.reset();
|
||||
|
||||
$scope.$emit("HideOrgListHeader");
|
||||
|
||||
// Save
|
||||
$scope.formSave = function () {
|
||||
generator.clearApiErrors();
|
||||
@ -125,6 +147,7 @@ export function OrganizationsAdd($scope, $rootScope, $compile, $location, $log,
|
||||
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);
|
||||
@ -139,6 +162,8 @@ export function OrganizationsAdd($scope, $rootScope, $compile, $location, $log,
|
||||
};
|
||||
|
||||
$scope.formCancel = function () {
|
||||
$scope.$emit("ReloadOrganzationCards");
|
||||
$scope.$emit("ShowOrgListHeader");
|
||||
$state.transitionTo('organizations');
|
||||
};
|
||||
}
|
||||
@ -166,6 +191,10 @@ export function OrganizationsEdit($scope, $rootScope, $compile, $location, $log,
|
||||
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});
|
||||
@ -225,11 +254,12 @@ export function OrganizationsEdit($scope, $rootScope, $compile, $location, $log,
|
||||
}
|
||||
Rest.setUrl(defaultUrl + id + '/');
|
||||
Rest.put(params)
|
||||
.success(function () {
|
||||
.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!',
|
||||
@ -244,6 +274,8 @@ export function OrganizationsEdit($scope, $rootScope, $compile, $location, $log,
|
||||
};
|
||||
|
||||
$scope.formCancel = function () {
|
||||
$scope.$emit("ReloadOrganzationCards");
|
||||
$scope.$emit("ShowOrgListHeader");
|
||||
$state.transitionTo('organizations');
|
||||
};
|
||||
|
||||
|
||||
@ -82,8 +82,6 @@ export default
|
||||
scope.getPage(currentPage, set, iterator);
|
||||
});
|
||||
} else if ($location.$$url.split("/")[1] === params.set && $location.$$url.split("/")[2] && $location.$$url.split("/")[2] !== "add" && !scope.getNewPage) {
|
||||
delete $rootScope.rowBeingEdited;
|
||||
delete $rootScope.listBeingEdited;
|
||||
var id = $location.$$url.split("/")[2];
|
||||
var restUrl = params.url.split("?")[0];
|
||||
var pageSize = scope[iterator + '_page_size'];
|
||||
|
||||
98
awx/ui/client/src/organizations/orgcards.block.less
Normal file
98
awx/ui/client/src/organizations/orgcards.block.less
Normal file
@ -0,0 +1,98 @@
|
||||
/** @define OrgCards */
|
||||
|
||||
.OrgCards {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.OrgCards-card {
|
||||
background-color: #fff;
|
||||
padding: 20px;
|
||||
border-radius: 5px;
|
||||
border: 1px solid #e8e8e8;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: baseline;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.OrgCards-card--selected {
|
||||
padding-left: 16px;
|
||||
border-left: 5px solid #1678C4;
|
||||
}
|
||||
|
||||
.OrgCards-header {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
align-items: baseline;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.OrgCards-label {
|
||||
margin-top: 0px;
|
||||
text-transform: uppercase;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
color: #848992;
|
||||
margin-bottom: 25px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.OrgCards-actionItems {
|
||||
margin-left: auto;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
.OrgCards-actionItem {
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
.OrgCards-description {
|
||||
margin-bottom: 0px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
@media (min-width: 1179px) {
|
||||
.OrgCards-card {
|
||||
width: ~"calc(25% - 15px)";
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.OrgCards-card:nth-child(4n+4) {
|
||||
margin-right: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 901px) and (max-width: 1178px) {
|
||||
.OrgCards-card {
|
||||
width: ~"calc(33% - 11px)";
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.OrgCards-card:nth-child(3n+3) {
|
||||
margin-right: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 616px) and (max-width: 900px) {
|
||||
.OrgCards-card {
|
||||
width: ~"calc(50% - 10px)";
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.OrgCards-card:nth-child(2n+2) {
|
||||
margin-right: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 615px) {
|
||||
.OrgCards-card {
|
||||
width: 100%;
|
||||
margin-right: 0px;
|
||||
}
|
||||
}
|
||||
4
awx/ui/client/src/partials/organizations.crud.html
Normal file
4
awx/ui/client/src/partials/organizations.crud.html
Normal file
@ -0,0 +1,4 @@
|
||||
<div class="tab-pane" id="organizations">
|
||||
<div ui-view></div>
|
||||
<div ng-cloak id="htmlTemplate" class="Panel"></div>
|
||||
</div>
|
||||
@ -1,4 +1,47 @@
|
||||
<div class="tab-pane" id="organizations">
|
||||
<div ui-view></div>
|
||||
<div ng-cloak id="htmlTemplate" class="Panel"></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-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>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -53,7 +53,7 @@
|
||||
@list-pagin-bord-act: @default-icon-hov;
|
||||
@list-pagin-bg-act: @default-icon-hov;
|
||||
@list-title-txt: @default-interface-txt;
|
||||
@list-title-badge: @default-icon-hov;
|
||||
@list-title-badge: @default-icon;
|
||||
@list-srch-inpt-bg: @default-secondary-bg;
|
||||
@list-srch-inpt-txt: @default-data-txt;
|
||||
@list-srch-inpt-ph-txt: @default-icon;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user