Merge "Add Angular keystone user details use registry"

This commit is contained in:
Jenkins 2017-01-11 05:12:09 +00:00 committed by Gerrit Code Review
commit 691db471a6
8 changed files with 391 additions and 33 deletions

View File

@ -0,0 +1,56 @@
/**
* (c) Copyright 2016 99Cloud
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
(function() {
'use strict';
/**
* @ngdoc overview
* @ngname horizon.dashboard.identity.users.details
*
* @description
* Provides details features for users.
*/
angular
.module('horizon.dashboard.identity.users.details', [
'horizon.framework.conf',
'horizon.app.core'
])
.run(registerUserDetails);
registerUserDetails.$inject = [
'horizon.dashboard.identity.users.basePath',
'horizon.dashboard.identity.users.resourceType',
'horizon.framework.conf.resource-type-registry.service',
'horizon.dashboard.identity.users.service'
];
function registerUserDetails(
basePath,
userResourceType,
registry,
usersService
) {
registry.getResourceType(userResourceType)
.setLoadFunction(usersService.getUserPromise)
.detailsViews.append({
id: 'userDetailsOverview',
name: gettext('Overview'),
template: basePath + 'details/overview.html'
});
}
})();

View File

@ -1,14 +1,7 @@
<div class="row">
<dl class="col-sm-2">
<dt translate>Domain ID</dt>
<dd>{$ item.domain_id | noValue $}</dd>
</dl>
<dl class="col-sm-2">
<dt translate>Primary Project ID</dt>
<dd>{$ item.tenantId || user.default_project_id | noValue $}</dd>
</dl>
<dl class="col-sm-2">
<dt translate>Description</dt>
<dd>{$ item.description | noValue $}</dd>
</dl>
</div>
<hz-resource-property-list
resource-type-name="OS::Keystone::User"
item="item"
property-groups="[['domain_id'],
['default_project_id'],
['description']]">
</hz-resource-property-list>

View File

@ -0,0 +1,46 @@
/*
* (c) Copyright 2016 99Cloud
*
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
"use strict";
angular
.module('horizon.dashboard.identity.users')
.controller('UserOverviewController', UserOverviewController);
UserOverviewController.$inject = [
'horizon.dashboard.identity.users.resourceType',
'horizon.framework.conf.resource-type-registry.service',
'$scope'
];
function UserOverviewController(
userResourceType,
registry,
$scope
) {
var ctrl = this;
ctrl.user = {};
ctrl.resourceType = registry.getResourceType(userResourceType);
$scope.context.loadPromise.then(onGetUser);
function onGetUser(user) {
ctrl.user = user.data;
}
}
})();

View File

@ -0,0 +1,45 @@
/**
* (c) Copyright 2016 99Cloud
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
(function() {
'use strict';
describe('user overview controller', function() {
var ctrl;
var keystone = {
getNamespaces: angular.noop
};
beforeEach(module('horizon.dashboard.identity.users'));
beforeEach(module('horizon.framework.conf'));
beforeEach(inject(function($controller, $q) {
var deferred = $q.defer();
deferred.resolve({data: {properties: {'a': 'apple'}}});
spyOn(keystone, 'getNamespaces').and.returnValue(deferred.promise);
ctrl = $controller('UserOverviewController',
{
'$scope': {context: {loadPromise: deferred.promise}}
}
);
}));
it('sets ctrl.resourceType', function() {
expect(ctrl.resourceType).toBeDefined();
});
});
})();

View File

@ -0,0 +1,16 @@
<div ng-controller="UserOverviewController as ctrl">
<div class="row">
<div class="col-md-6 detail">
<h3 translate>User</h3>
<hr>
<hz-resource-property-list
resource-type-name="OS::Keystone::User"
cls="dl-horizontal"
item="ctrl.user"
property-groups="[[
'domain_id', 'domain_name', 'id', 'name', 'description',
'email', 'enabled', 'default_project_id', 'project_name']]">
</hz-resource-property-list>
</div>
</div>
</div>

View File

@ -28,7 +28,8 @@
*/
angular
.module('horizon.dashboard.identity.users', [
'ngRoute'
'ngRoute',
'horizon.dashboard.identity.users.details'
])
.constant('horizon.dashboard.identity.users.resourceType', 'OS::Keystone::User')
.run(run)
@ -38,21 +39,22 @@
'horizon.framework.conf.resource-type-registry.service',
'horizon.app.core.openstack-service-api.keystone',
'horizon.dashboard.identity.users.basePath',
'horizon.dashboard.identity.users.resourceType'
'horizon.dashboard.identity.users.resourceType',
'horizon.dashboard.identity.users.service'
];
function run(registry, keystone, basePath, userResourceType) {
function run(registry, keystone, basePath, userResourceType, usersService) {
registry.getResourceType(userResourceType)
.setNames(gettext('User'), gettext('Users'))
.setSummaryTemplateUrl(basePath + 'details/drawer.html')
.setProperties(userProperties())
.setListFunction(listFunction)
.setListFunction(usersService.getUsersPromise)
.tableColumns
.append({
id: 'name',
priority: 1,
sortDefault: true,
urlFunction: urlFunction
urlFunction: usersService.getDetailsPath
})
.append({
id: 'email',
@ -96,14 +98,6 @@
]
});
function listFunction() {
return keystone.getUsers();
}
function urlFunction(item) {
return 'identity/ngdetails/OS::Keystone::User/' + item.id;
}
/**
* @name userProperties
* @description resource properties for user module
@ -111,13 +105,14 @@
function userProperties() {
return {
name: gettext('Name'),
email: gettext('Email'),
email: {label: gettext('Email'), filters: ['noValue']},
id: gettext('ID'),
enabled: gettext('Enabled'),
domain_id: gettext('Domain ID'),
domain_name: gettext('Domain Name'),
description: gettext('Description'),
project_id: gettext('Primary Project ID')
enabled: {label: gettext('Enabled'), filters: ['yesno']},
domain_id: {label: gettext('Domain ID'), filters: ['noValue']},
domain_name: {label: gettext('Domain Name'), filters: ['noValue']},
description: {label: gettext('Description'), filters: ['noValue']},
default_project_id: {label: gettext('Primary Project ID'), filters: ['noValue']},
project_name: {label: gettext('Primary Project Name'), filters: ['noValue']}
};
}
}

View File

@ -0,0 +1,98 @@
/*
* Copyright 2016 IBM Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
"use strict";
angular.module('horizon.dashboard.identity.users')
.factory('horizon.dashboard.identity.users.service', userService);
userService.$inject = [
'$q',
'horizon.app.core.openstack-service-api.keystone'
];
/*
* @ngdoc factory
* @name horizon.dashboard.identity.users.service
*/
function userService($q, keystone) {
return {
getDetailsPath: getDetailsPath,
getUserPromise: getUserPromise,
getUsersPromise: getUsersPromise
};
/*
* @ngdoc function
* @name getDetailsPath
* @param item {Object} - The user object
* @description
* Given an user object, returns the relative path to the details view.
*/
function getDetailsPath(item) {
return 'project/ngdetails/OS::Keystone::User/' + item.id;
}
/*
* @ngdoc function
* @name getUsersPromise
* @description
* Returns a promise for the users data.
*/
function getUsersPromise() {
return keystone.getUsers();
}
/*
* @ngdoc function
* @name getUserPromise
* @description
* Given an id, returns a promise for the user data.
* Need to add domain information to user object if v3 supported
*/
function getUserPromise(identifier) {
return $q.all([
keystone.getVersion(),
keystone.getUser(identifier)
]).then(getUserDetails);
}
function getUserDetails(response) {
var version = response[0].data.version;
var user = response[1];
// get project name
if (user.data.default_project_id) {
keystone.getProject(user.data.default_project_id).then(addProjectName);
}
// get domain info if v3 supported
if (version && version >= 3) {
return keystone.getDomain(user.data.domain_id).then(modifyResponse);
} else {
return user;
}
function addProjectName(project) {
user.data.project_name = project.data.name;
return user;
}
function modifyResponse(domain) {
user.data.domain_name = domain.data.name;
return user;
}
}
}
})();

View File

@ -0,0 +1,109 @@
/*
* Copyright 2016 IBM Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
"use strict";
describe('Identity user service', function() {
var service, keystone, scope, $q;
beforeEach(module('horizon.dashboard.identity.users'));
beforeEach(inject(function($injector, _$q_) {
service = $injector.get('horizon.dashboard.identity.users.service');
keystone = $injector.get('horizon.app.core.openstack-service-api.keystone');
scope = $injector.get('$rootScope').$new();
$q = _$q_;
}));
it("getDetailsPath creates proper url", function() {
var item = {id: 614};
expect(service.getDetailsPath(item)).toBe('project/ngdetails/OS::Keystone::User/614');
});
describe('getUsersPromise', function() {
it("provides a promise", function() {
var deferred = $q.defer();
spyOn(keystone, 'getUsers').and.returnValue(deferred.promise);
var result = service.getUsersPromise();
deferred.resolve({data: {items: [{id: 1, name: 'puff'}]}});
expect(keystone.getUsers).toHaveBeenCalled();
expect(result.$$state.value.data.items[0].name).toBe('puff');
});
});
describe('getUserPromise', function() {
it("provides a promise if keystone version undefined", function() {
var deferredVersion = $q.defer();
var deferredUser = $q.defer();
spyOn(keystone, 'getVersion').and.returnValue(deferredVersion.promise);
spyOn(keystone, 'getUser').and.returnValue(deferredUser.promise);
service.getUserPromise(1);
deferredVersion.resolve({data: {version: ''}});
deferredUser.resolve({data: {id: 1, name: 'puff'}});
scope.$apply();
expect(keystone.getVersion).toHaveBeenCalled();
expect(keystone.getUser).toHaveBeenCalled();
});
it("provides a promise if keystone version < 3", function() {
var deferredVersion = $q.defer();
var deferredUser = $q.defer();
spyOn(keystone, 'getVersion').and.returnValue(deferredVersion.promise);
spyOn(keystone, 'getUser').and.returnValue(deferredUser.promise);
service.getUserPromise(1);
deferredVersion.resolve({data: {version: 2}});
deferredUser.resolve({data: {id: 1, name: 'puff'}});
scope.$apply();
expect(keystone.getVersion).toHaveBeenCalled();
expect(keystone.getUser).toHaveBeenCalled();
});
it("provides a promise if keystone version 3", function() {
var deferredVersion = $q.defer();
var deferredProject = $q.defer();
var deferredUser = $q.defer();
var deferredDomain = $q.defer();
spyOn(keystone, 'getVersion').and.returnValue(deferredVersion.promise);
spyOn(keystone, 'getUser').and.returnValue(deferredUser.promise);
spyOn(keystone, 'getProject').and.returnValue(deferredProject.promise);
spyOn(keystone, 'getDomain').and.returnValue(deferredDomain.promise);
var result = service.getUserPromise(1);
deferredVersion.resolve({data: {version: 3}});
deferredUser.resolve({data: {id: 1, name: 'puff', domain_id: 29,
default_project_id: 26}});
deferredProject.resolve({data: {name: 'puff_project'}});
deferredDomain.resolve({data: {id: 1, name: 'puff_domain'}});
scope.$apply();
expect(keystone.getVersion).toHaveBeenCalled();
expect(keystone.getProject).toHaveBeenCalled();
expect(keystone.getUser).toHaveBeenCalled();
expect(keystone.getDomain).toHaveBeenCalled();
expect(result.$$state.value.data.project_name).toBe('puff_project');
expect(result.$$state.value.data.domain_name).toBe('puff_domain');
});
});
});
})();