From b7a35daeec6e5700a5e77697976e9f262fb6cafa Mon Sep 17 00:00:00 2001 From: Julien Bramary Date: Mon, 25 Jul 2016 16:55:23 +0100 Subject: [PATCH 1/4] TEAMFOUR-713 - move cluster actions to common controller - moved cluster actions to common controller - empty org cache on list - cache org names in model instead of each controller --- .../endpoints/clusters/cluster/cluster.html | 12 ++- .../clusters/cluster/cluster.module.js | 84 +++++++++++++++++-- .../detail/cluster-detail-organizations.html | 2 +- .../cluster/detail/cluster-detail.html | 13 --- .../cluster/detail/cluster-detail.module.js | 73 +--------------- .../cluster/detail/cluster-detail.scss | 3 +- .../detail/cluster-detail.users.module.js | 2 +- .../detail/cluster-organization-detail.html | 11 --- .../cluster-organization-detail.module.js | 28 +------ .../space/detail/cluster-space-detail.html | 14 ---- .../model/organization/organization.model.js | 15 ++++ 11 files changed, 111 insertions(+), 146 deletions(-) diff --git a/src/app/view/endpoints/clusters/cluster/cluster.html b/src/app/view/endpoints/clusters/cluster/cluster.html index 4f2c6ba472..fa6a2ea858 100644 --- a/src/app/view/endpoints/clusters/cluster/cluster.html +++ b/src/app/view/endpoints/clusters/cluster/cluster.html @@ -1,5 +1,15 @@
- + +
diff --git a/src/app/view/endpoints/clusters/cluster/cluster.module.js b/src/app/view/endpoints/clusters/cluster/cluster.module.js index 67cc5eafcc..8c1c121cd0 100644 --- a/src/app/view/endpoints/clusters/cluster/cluster.module.js +++ b/src/app/view/endpoints/clusters/cluster/cluster.module.js @@ -24,29 +24,94 @@ } ClusterController.$inject = [ - 'app.model.modelManager', '$stateParams', '$log', 'app.utils.utilsService', '$state', - '$q' + '$q', + 'app.model.modelManager', + 'helion.framework.widgets.asyncTaskDialog' ]; - function ClusterController(modelManager, $stateParams, $log, utils, $state, $q) { + function ClusterController($stateParams, $log, utils, $state, $q, modelManager, asyncTaskDialog) { var that = this; - - this.guid = $stateParams.guid; var organizationModel = modelManager.retrieve('cloud-foundry.model.organization'); var serviceBindingModel = modelManager.retrieve('cloud-foundry.model.service-binding'); var privateDomains = modelManager.retrieve('cloud-foundry.model.private-domain'); var sharedDomains = modelManager.retrieve('cloud-foundry.model.shared-domain'); var appModel = modelManager.retrieve('cloud-foundry.model.application'); + var stackatoInfo = modelManager.retrieve('app.model.stackatoInfo'); + this.initialized = false; + this.guid = $stateParams.guid; this.userServiceInstanceModel = modelManager.retrieve('app.model.serviceInstance.user'); + this.getEndpoint = function () { return utils.getClusterEndpoint(that.userServiceInstanceModel.serviceInstances[that.guid]); }; + this.clusterActions = [ + { + name: gettext('Create Organization'), + disabled: true, + execute: function () { + return asyncTaskDialog( + { + title: gettext('Create Organization'), + templateUrl: 'app/view/endpoints/clusters/cluster/detail/actions/create-organization.html', + buttonTitles: { + submit: gettext('Create') + } + }, + { + data: { + // Make the form invalid if the name is already taken + organizationNames: organizationModel.organizationNames[that.guid] + } + }, + function (orgData) { + if (orgData.name && orgData.name.length > 0) { + return organizationModel.createOrganization(that.guid, orgData.name); + } else { + return $q.reject('Invalid Name!'); + } + + } + ); + }, + icon: 'helion-icon-lg helion-icon helion-icon-Tree' + }, + { + name: gettext('Create Space'), + disabled: true, + execute: function () { + }, + icon: 'helion-icon-lg helion-icon helion-icon-Tree' + }, + { + name: gettext('Assign User(s)'), + disabled: true, + execute: function () { + }, + icon: 'helion-icon-lg helion-icon helion-icon-Add_user' + } + ]; + + + /** + * Enable actions based on admin status + * N.B. when finer grain ACLs are wired in this should be updated + * */ + function enableActions() { + if (stackatoInfo.info.endpoints.hcf[that.guid].user.admin) { + _.forEach(that.clusterActions, function (action) { + action.disabled = false; + }); + // Disable these until implemented! + that.clusterActions[1].disabled = that.clusterActions[2].disabled = true; + } + } + function init() { // Cache all organizations associated with this cluster @@ -54,7 +119,7 @@ var promises = []; _.forEach(orgs, function (org) { var promise = organizationModel.getOrganizationDetails(that.guid, org).catch(function () { - //Swallow errors for individual orgs + // Swallow errors for individual orgs $log.error('Failed to fetch details for org - ' + org.entity.name); }); promises.push(promise); @@ -82,7 +147,12 @@ // Reset any cache we may be interested in delete appModel.appSummary; - return $q.all([orgPromise, servicesPromise, serviceBindingPromise, privateDomainsPromise, sharedDomainsPromise]); + return $q.all([orgPromise, servicesPromise, serviceBindingPromise, privateDomainsPromise, sharedDomainsPromise]) + .then(function () { + enableActions(); + }).finally(function () { + that.initialized = true; + }); } utils.chainStateResolve('endpoint.clusters.cluster', $state, init); diff --git a/src/app/view/endpoints/clusters/cluster/detail/cluster-detail-organizations.html b/src/app/view/endpoints/clusters/cluster/detail/cluster-detail-organizations.html index f660be5a7e..b9ad864aef 100644 --- a/src/app/view/endpoints/clusters/cluster/detail/cluster-detail-organizations.html +++ b/src/app/view/endpoints/clusters/cluster/detail/cluster-detail-organizations.html @@ -6,7 +6,7 @@ diff --git a/src/app/view/endpoints/clusters/cluster/detail/cluster-detail.html b/src/app/view/endpoints/clusters/cluster/detail/cluster-detail.html index a73e9b0d6b..596669a264 100644 --- a/src/app/view/endpoints/clusters/cluster/detail/cluster-detail.html +++ b/src/app/view/endpoints/clusters/cluster/detail/cluster-detail.html @@ -55,16 +55,3 @@

{{ clusterController.userServiceInstanceModel.serviceInstances[clusterContro - - - - diff --git a/src/app/view/endpoints/clusters/cluster/detail/cluster-detail.module.js b/src/app/view/endpoints/clusters/cluster/detail/cluster-detail.module.js index 82fd00120d..937fc16a49 100644 --- a/src/app/view/endpoints/clusters/cluster/detail/cluster-detail.module.js +++ b/src/app/view/endpoints/clusters/cluster/detail/cluster-detail.module.js @@ -28,69 +28,21 @@ '$scope', 'app.utils.utilsService', '$state', - '$q', - 'helion.framework.widgets.asyncTaskDialog' + '$q' ]; - function ClusterDetailController(modelManager, $stateParams, $scope, utils, $state, $q, asyncTaskDialog) { + function ClusterDetailController(modelManager, $stateParams, $scope, utils, $state, $q) { var that = this; this.guid = $stateParams.guid; this.$scope = $scope; this.organizations = []; - this.organizationNames = []; + this.totalApps = 0; var organizationModel = modelManager.retrieve('cloud-foundry.model.organization'); - this.clusterActions = [ - { - name: gettext('Create Organization'), - disabled: true, - execute: function () { - return asyncTaskDialog( - { - title: gettext('Create Organization'), - templateUrl: 'app/view/endpoints/clusters/cluster/detail/actions/create-organization.html', - buttonTitles: { - submit: gettext('Create') - } - }, - { - data: { - // Make the form invalid if the name is already taken - organizationNames: that.organizationNames - } - }, - function (orgData) { - if (orgData.name && orgData.name.length > 0) { - return organizationModel.createOrganization(that.guid, orgData.name); - } else { - return $q.reject('Invalid Name!'); - } - - } - ); - }, - icon: 'helion-icon-lg helion-icon helion-icon-Tree' - }, - { - name: gettext('Create Space'), - disabled: true, - execute: function () { - }, - icon: 'helion-icon-lg helion-icon helion-icon-Tree' - }, - { - name: gettext('Assign User(s)'), - disabled: true, - execute: function () { - }, - icon: 'helion-icon-lg helion-icon helion-icon-Add_user' - } - ]; - this.updateTotalApps = function () { that.totalApps = 0; var totalMemoryMb = 0; @@ -110,28 +62,9 @@ return o1.created_at - o2.created_at; }); that.updateTotalApps(); - that.organizationNames = _.map(that.organizations, function (org) { - return org.org.entity.name; - }); - } - - /** - * Enable actions based on admin status - * N.B. when finer grain ACLs are wired in this should be updated - * */ - function enableActions() { - var stackatoInfo = modelManager.retrieve('app.model.stackatoInfo'); - if (stackatoInfo.info.endpoints.hcf[that.guid].user.admin) { - _.forEach(that.clusterActions, function (action) { - action.disabled = false; - }); - // Disable these until implemented! - that.clusterActions[1].disabled = that.clusterActions[2].disabled = true; - } } function init() { - enableActions(); // Start watching for further model changes after parent init chain completes $scope.$watchCollection(function () { diff --git a/src/app/view/endpoints/clusters/cluster/detail/cluster-detail.scss b/src/app/view/endpoints/clusters/cluster/detail/cluster-detail.scss index 9b712aaf56..3677dffd58 100644 --- a/src/app/view/endpoints/clusters/cluster/detail/cluster-detail.scss +++ b/src/app/view/endpoints/clusters/cluster/detail/cluster-detail.scss @@ -28,7 +28,7 @@ cursor: default; float: left; margin: 0 8px 8px 0; - padding: 0 4px 4px 4px; + padding: 1px 4px 4px 4px; border: solid 2px $gray-light; border-radius: 5px; } @@ -38,6 +38,7 @@ font-weight: bolder; color: #aaa; margin-left: 10px; + cursor: pointer; } } diff --git a/src/app/view/endpoints/clusters/cluster/detail/cluster-detail.users.module.js b/src/app/view/endpoints/clusters/cluster/detail/cluster-detail.users.module.js index 024c335bc3..e8d054f8bf 100644 --- a/src/app/view/endpoints/clusters/cluster/detail/cluster-detail.users.module.js +++ b/src/app/view/endpoints/clusters/cluster/detail/cluster-detail.users.module.js @@ -57,7 +57,7 @@ _.forEach(that.organizationModel.organizations[that.guid], function (org) { var roles = org.roles[aUser.metadata.guid]; if (!_.isUndefined(roles)) { - myRoles[org.details.name] = roles; + myRoles[org.details.org.entity.name] = roles; } }); that.userRoles[aUser.metadata.guid] = []; diff --git a/src/app/view/endpoints/clusters/cluster/organization/detail/cluster-organization-detail.html b/src/app/view/endpoints/clusters/cluster/organization/detail/cluster-organization-detail.html index cf192c466d..e3e8758e90 100644 --- a/src/app/view/endpoints/clusters/cluster/organization/detail/cluster-organization-detail.html +++ b/src/app/view/endpoints/clusters/cluster/organization/detail/cluster-organization-detail.html @@ -25,14 +25,3 @@

Organization : {{ clusterOrgDetailController.organization().details.org.enti - - diff --git a/src/app/view/endpoints/clusters/cluster/organization/detail/cluster-organization-detail.module.js b/src/app/view/endpoints/clusters/cluster/organization/detail/cluster-organization-detail.module.js index e0f0176415..da3491ec95 100644 --- a/src/app/view/endpoints/clusters/cluster/organization/detail/cluster-organization-detail.module.js +++ b/src/app/view/endpoints/clusters/cluster/organization/detail/cluster-organization-detail.module.js @@ -37,34 +37,8 @@ this.organizationModel = modelManager.retrieve('cloud-foundry.model.organization'); this.orgPath = this.organizationModel.fetchOrganizationPath(this.clusterGuid, this.organizationGuid); - this.actions = [ - { - name: gettext('Create Organization'), - icon: 'helion-icon-lg helion-icon helion-icon-Tree', - disabled: true, - execute: function () { - } - }, - { - name: gettext('Create Space'), - icon: 'helion-icon-lg helion-icon helion-icon-Tree', - disabled: true, - execute: function () { - } - }, - { - name: gettext('Assign User(s)'), - icon: 'helion-icon-lg helion-icon helion-icon-Add_user', - disabled: true, - execute: function () { - } - } - ]; - function init() { - that.organizationNames = _.map(that.organizationModel.organizations[that.clusterGuid], function (org) { - return org.details.org.entity.name; - }); + that.organizationNames = that.organizationModel.organizationNames[that.clusterGuid]; return $q.resolve(); } diff --git a/src/app/view/endpoints/clusters/cluster/organization/space/detail/cluster-space-detail.html b/src/app/view/endpoints/clusters/cluster/organization/space/detail/cluster-space-detail.html index 23338437dd..fc9e378d61 100644 --- a/src/app/view/endpoints/clusters/cluster/organization/space/detail/cluster-space-detail.html +++ b/src/app/view/endpoints/clusters/cluster/organization/space/detail/cluster-space-detail.html @@ -28,17 +28,3 @@

Space : {{ clusterSpaceController.space().details.space.entity.name }}

- - - - - diff --git a/src/plugins/cloud-foundry/model/organization/organization.model.js b/src/plugins/cloud-foundry/model/organization/organization.model.js index 0230164ef7..b4698a4928 100644 --- a/src/plugins/cloud-foundry/model/organization/organization.model.js +++ b/src/plugins/cloud-foundry/model/organization/organization.model.js @@ -46,6 +46,7 @@ this.utils = utils; this.stackatoInfoModel = modelManager.retrieve('app.model.stackatoInfo'); this.organizations = {}; + this.organizationNames = {}; var passThroughHeader = { 'x-cnap-passthrough': 'true' @@ -71,6 +72,7 @@ * @public */ listAllOrganizations: function (cnsiGuid, params) { + this.unCacheOrganization(cnsiGuid); return this.apiManager.retrieve('cloud-foundry.api.Organizations') .ListAllOrganizations(params, this.makeHttpConfig(cnsiGuid)) .then(function (response) { @@ -167,6 +169,7 @@ initOrganizationCache: function (cnsiGuid, orgGuid) { this.organizations[cnsiGuid] = this.organizations[cnsiGuid] || {}; + this.organizationNames[cnsiGuid] = this.organizationNames[cnsiGuid] || []; this.organizations[cnsiGuid][orgGuid] = this.organizations[cnsiGuid][orgGuid] || { details: {}, roles: {}, @@ -182,6 +185,7 @@ cacheOrganizationDetails: function (cnsiGuid, orgGuid, details) { this.initOrganizationCache(cnsiGuid, orgGuid); this.organizations[cnsiGuid][orgGuid].details = details; + this.organizationNames[cnsiGuid].push(details.org.entity.name); }, cacheOrganizationUsersRoles: function (cnsiGuid, orgGuid, roles) { @@ -209,6 +213,17 @@ }, unCacheOrganization: function (cnsiGuid, orgGuid) { + // If no org is specified uncache the entire cluster + if (angular.isUndefined(orgGuid)) { + delete this.organizations[cnsiGuid]; + delete this.organizationNames[cnsiGuid]; + return; + } + var orgName = _.get(this.organizations, [cnsiGuid, orgGuid, 'details', 'org', 'entity', 'name']); + var idx = this.organizationNames[cnsiGuid].indexOf(orgName); + if (idx > -1) { + this.organizationNames[cnsiGuid].splice(idx, 1); + } delete this.organizations[cnsiGuid][orgGuid]; }, From fcfcc0c6ae3d041dc6102c733f3778a10ab530cf Mon Sep 17 00:00:00 2001 From: Julien Bramary Date: Mon, 25 Jul 2016 17:02:23 +0100 Subject: [PATCH 2/4] Link org names from model to controller --- .../view/endpoints/clusters/cluster/cluster.module.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/app/view/endpoints/clusters/cluster/cluster.module.js b/src/app/view/endpoints/clusters/cluster/cluster.module.js index 8c1c121cd0..ca38c08c58 100644 --- a/src/app/view/endpoints/clusters/cluster/cluster.module.js +++ b/src/app/view/endpoints/clusters/cluster/cluster.module.js @@ -116,15 +116,18 @@ // Cache all organizations associated with this cluster var orgPromise = organizationModel.listAllOrganizations(that.guid, {}).then(function (orgs) { - var promises = []; + var allDetailsP = []; _.forEach(orgs, function (org) { - var promise = organizationModel.getOrganizationDetails(that.guid, org).catch(function () { + var orgDetailsP = organizationModel.getOrganizationDetails(that.guid, org).catch(function () { // Swallow errors for individual orgs $log.error('Failed to fetch details for org - ' + org.entity.name); }); - promises.push(promise); + allDetailsP.push(orgDetailsP); + }); + return $q.all(allDetailsP).then(function (val) { + that.organizationNames = organizationModel.organizationNames[that.guid]; + return val; }); - return $q.all(promises); }).catch(function (error) { $log.error('Error while listing organizations', error); }); From 260ec823823f54dad00357e39d47d37808ab55d1 Mon Sep 17 00:00:00 2001 From: Julien Bramary Date: Mon, 25 Jul 2016 17:03:57 +0100 Subject: [PATCH 3/4] Enable actions slightly sooner --- src/app/view/endpoints/clusters/cluster/cluster.module.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/app/view/endpoints/clusters/cluster/cluster.module.js b/src/app/view/endpoints/clusters/cluster/cluster.module.js index ca38c08c58..3200e08a53 100644 --- a/src/app/view/endpoints/clusters/cluster/cluster.module.js +++ b/src/app/view/endpoints/clusters/cluster/cluster.module.js @@ -125,6 +125,7 @@ allDetailsP.push(orgDetailsP); }); return $q.all(allDetailsP).then(function (val) { + enableActions(); that.organizationNames = organizationModel.organizationNames[that.guid]; return val; }); @@ -151,9 +152,7 @@ delete appModel.appSummary; return $q.all([orgPromise, servicesPromise, serviceBindingPromise, privateDomainsPromise, sharedDomainsPromise]) - .then(function () { - enableActions(); - }).finally(function () { + .finally(function () { that.initialized = true; }); } From 8e93fe46968bb7914245b426fcd2590a167d4bec Mon Sep 17 00:00:00 2001 From: richard-cox Date: Mon, 25 Jul 2016 18:06:33 +0100 Subject: [PATCH 4/4] Fixed lint error, removed ng-if on actions container --- src/app/view/endpoints/clusters/cluster/cluster.html | 2 +- src/app/view/endpoints/clusters/cluster/cluster.module.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/app/view/endpoints/clusters/cluster/cluster.html b/src/app/view/endpoints/clusters/cluster/cluster.html index fa6a2ea858..3b1d2ae619 100644 --- a/src/app/view/endpoints/clusters/cluster/cluster.html +++ b/src/app/view/endpoints/clusters/cluster/cluster.html @@ -1,7 +1,7 @@
-