org cards implementation with rollups

This commit is contained in:
John Mitchell 2016-01-20 15:55:31 -05:00
parent c8d7778ed5
commit 3cee94c1e9
8 changed files with 221 additions and 39 deletions

View File

@ -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 {

View File

@ -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) {

View File

@ -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');
};

View File

@ -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'];

View 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;
}
}

View File

@ -0,0 +1,4 @@
<div class="tab-pane" id="organizations">
<div ui-view></div>
<div ng-cloak id="htmlTemplate" class="Panel"></div>
</div>

View File

@ -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>

View File

@ -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;