diff --git a/awx/ui/client/legacy-styles/forms.less b/awx/ui/client/legacy-styles/forms.less index 8869fa3a7a..741b7bd70e 100644 --- a/awx/ui/client/legacy-styles/forms.less +++ b/awx/ui/client/legacy-styles/forms.less @@ -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 { diff --git a/awx/ui/client/src/app.js b/awx/ui/client/src/app.js index 357f5ec638..dc33fe1d15 100644 --- a/awx/ui/client/src/app.js +++ b/awx/ui/client/src/app.js @@ -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) { diff --git a/awx/ui/client/src/controllers/Organizations.js b/awx/ui/client/src/controllers/Organizations.js index 3319addd64..f92c1479e3 100644 --- a/awx/ui/client/src/controllers/Organizations.js +++ b/awx/ui/client/src/controllers/Organizations.js @@ -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'); }; diff --git a/awx/ui/client/src/helpers/refresh.js b/awx/ui/client/src/helpers/refresh.js index 742bee18cc..41bb6bf01b 100644 --- a/awx/ui/client/src/helpers/refresh.js +++ b/awx/ui/client/src/helpers/refresh.js @@ -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']; diff --git a/awx/ui/client/src/organizations/orgcards.block.less b/awx/ui/client/src/organizations/orgcards.block.less new file mode 100644 index 0000000000..e3438c2fbb --- /dev/null +++ b/awx/ui/client/src/organizations/orgcards.block.less @@ -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; + } +} diff --git a/awx/ui/client/src/partials/organizations.crud.html b/awx/ui/client/src/partials/organizations.crud.html new file mode 100644 index 0000000000..5db1583d13 --- /dev/null +++ b/awx/ui/client/src/partials/organizations.crud.html @@ -0,0 +1,4 @@ +
+
+
+
diff --git a/awx/ui/client/src/partials/organizations.html b/awx/ui/client/src/partials/organizations.html index 5db1583d13..c027c3b6fa 100644 --- a/awx/ui/client/src/partials/organizations.html +++ b/awx/ui/client/src/partials/organizations.html @@ -1,4 +1,47 @@
-
+
+
+
+
+ organizations +
+ + {{ orgCount }} + +
+
+ +
+
+
+
+
+
+

{{ card.name }}

+
+ + +
+
+

{{ card.description || "Place organization description here" }}

+
+
diff --git a/awx/ui/client/src/shared/branding/colors.default.less b/awx/ui/client/src/shared/branding/colors.default.less index 3c0337a009..9016d88c40 100644 --- a/awx/ui/client/src/shared/branding/colors.default.less +++ b/awx/ui/client/src/shared/branding/colors.default.less @@ -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;