Merge "Angularize Key Pairs index view"

This commit is contained in:
Jenkins 2017-08-27 06:09:38 +00:00 committed by Gerrit Code Review
commit 6aa242bd73
12 changed files with 264 additions and 8 deletions

View File

@ -48,6 +48,7 @@ Default:
{
'images_panel': True,
'key_pairs_panel': False,
'flavors_panel': False,
'users_panel': False,
'roles_panel': False,

View File

@ -16,12 +16,23 @@
# License for the specific language governing permissions and limitations
# under the License.
from django.conf import settings
from django.conf.urls import url
from openstack_dashboard.dashboards.project.key_pairs import views
from django.utils.translation import ugettext_lazy as _
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^import/$', views.ImportView.as_view(), name='import'),
url(r'^(?P<keypair_name>[^/]+)/$', views.DetailView.as_view(),
name='detail'),
]
from horizon.browsers import views
from openstack_dashboard.dashboards.project.key_pairs import views as \
legacy_views
if settings.ANGULAR_FEATURES.get('key_pairs_panel'):
title = _("Key Pairs")
urlpatterns = [
url('', views.AngularIndexView.as_view(title=title), name='index'),
]
else:
urlpatterns = [
url(r'^$', legacy_views.IndexView.as_view(), name='index'),
url(r'^import/$', legacy_views.ImportView.as_view(), name='import'),
url(r'^(?P<keypair_name>[^/]+)/$', legacy_views.DetailView.as_view(),
name='detail'),
]

View File

@ -324,6 +324,7 @@ COMPRESS_OFFLINE_CONTEXT = 'horizon.themes.offline_context'
# Dictionary of currently available angular features
ANGULAR_FEATURES = {
'images_panel': True,
'key_pairs_panel': False,
'flavors_panel': False,
'users_panel': False,
'roles_panel': False,

View File

@ -1 +1,2 @@
@import "images/images";
@import "keypairs/keypairs";

View File

@ -0,0 +1,9 @@
hz-resource-property-list[resource-type-name="OS::Nova::Keypair"] {
hz-resource-property[prop-name="public_key"] dd {
overflow-wrap: break-word;
width: calc(100vw - 61px);
@media (min-width: 992px) {
width: calc(100vw - 281px);
}
}
}

View File

@ -0,0 +1,5 @@
<hz-resource-property-list
resource-type-name="OS::Nova::Keypair"
item="item"
property-groups="[['fingerprint', 'public_key']]">
</hz-resource-property-list>

View File

@ -27,7 +27,79 @@
*/
angular
.module('horizon.app.core.keypairs', [
'ngRoute',
'horizon.app.core',
'horizon.framework.conf'
])
;
.constant('horizon.app.core.keypairs.resourceType', 'OS::Nova::Keypair')
.run(run)
.config(config);
run.$inject = [
'horizon.framework.conf.resource-type-registry.service',
'horizon.app.core.openstack-service-api.nova',
'horizon.app.core.keypairs.basePath',
'horizon.app.core.keypairs.resourceType',
'horizon.app.core.keypairs.service'
];
function run(registry, nova, basePath, resourceType, keypairsService) {
registry.getResourceType(resourceType)
.setNames(gettext('Key Pair'), gettext('Key Pairs'))
// for detail summary view on table row.
.setSummaryTemplateUrl(basePath + 'details/drawer.html')
.setProperties(keypairProperties())
.setListFunction(keypairsService.getKeypairsPromise)
.tableColumns
.append({
id: 'name',
priority: 1,
sortDefault: true
})
.append({
id: 'fingerprint',
priority: 2
});
// for magic-search
registry.getResourceType(resourceType).filterFacets
.append({
'label': gettext('Name'),
'name': 'name',
'singleton': true
});
}
function keypairProperties() {
return {
'id': {label: gettext('ID'), filters: ['noValue'] },
'name': {label: gettext('Name'), filters: ['noName'] },
'fingerprint': {label: gettext('Fingerprint'), filters: ['noValue'] },
'created_at': {label: gettext('Created'), filters: ['simpleDate'] },
'user_id': {label: gettext('User ID'), filters: ['noValue'] },
'public_key': {label: gettext('Public Key'), filters: ['noValue'] }
};
}
config.$inject = [
'$provide',
'$windowProvider',
'$routeProvider'
];
/**
* @name config
* @param {Object} $provide
* @param {Object} $windowProvider
* @param {Object} $routeProvider
* @description Routes used by this module.
* @returns {undefined} Returns nothing
*/
function config($provide, $windowProvider, $routeProvider) {
var path = $windowProvider.$get().STATIC_URL + 'app/core/keypairs/';
$provide.constant('horizon.app.core.keypairs.basePath', path);
$routeProvider.when('/project/key_pairs', {
templateUrl: path + 'panel.html'
});
}
})();

View File

@ -22,4 +22,27 @@
});
});
describe('loading the module', function () {
var registry;
beforeEach(module('horizon.app.core.keypairs'));
beforeEach(inject(function($injector) {
registry = $injector.get('horizon.framework.conf.resource-type-registry.service');
}));
it('registers names', function() {
expect(registry.getResourceType('OS::Nova::Keypair').getName()).toBe("Key Pairs");
});
it('should set facets for search', function () {
var names = registry.getResourceType('OS::Nova::Keypair').filterFacets
.map(getName);
expect(names).toContain('name');
function getName(x) {
// underscore.js and .pluck() would be great here.
return x.name;
}
});
});
})();

View File

@ -0,0 +1,66 @@
/*
* 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.app.core.keypairs')
.factory('horizon.app.core.keypairs.service', keypairsService);
keypairsService.$inject = [
'$filter',
'horizon.app.core.openstack-service-api.nova'
];
/*
* @ngdoc factory
* @name horizon.app.core.keypairs.service
*
* @description
* This service provides functions that are used through the key pair
* features. These are primarily used in the module registrations
* but do not need to be restricted to such use. Each exposed function
* is documented below.
*/
function keypairsService($filter, nova) {
return {
getKeypairsPromise: getKeypairsPromise
};
/*
* @ngdoc function
* @name getKeypairsPromise
* @description
* Given filter/query parameters, returns a promise for the matching
* key pairs. This is used in displaying lists of key pairs. In this
* case, we need to modify the API's response by adding a composite value
* called 'trackBy' to assist the display mechanism when updating rows.
*/
function getKeypairsPromise(params) {
return nova.getKeypairs(params).then(modifyResponse);
function modifyResponse(response) {
return {data: {items: response.data.items.map(modifyItems)}};
function modifyItems(item) {
item = item.keypair;
item.trackBy = item.name;
return item;
}
}
}
}
})();

View File

@ -0,0 +1,54 @@
/*
* 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('horizon.app.core.keypairs', function () {
it('should exist', function () {
expect(angular.module('horizon.app.core.keypairs')).toBeDefined();
});
});
describe('keypairsService', function() {
var service;
beforeEach(module('horizon.app.core'));
beforeEach(inject(function($injector) {
service = $injector.get('horizon.app.core.keypairs.service');
}));
describe('getKeypairsPromise', function() {
it("provides a promise that gets translated", inject(function($q, $injector, $timeout) {
var nova = $injector.get('horizon.app.core.openstack-service-api.nova');
var session = $injector.get('horizon.app.core.openstack-service-api.userSession');
var deferred = $q.defer();
var deferredSession = $q.defer();
spyOn(nova, 'getKeypairs').and.returnValue(deferred.promise);
spyOn(session, 'get').and.returnValue(deferredSession.promise);
var result = service.getKeypairsPromise({});
deferredSession.resolve({});
deferred.resolve({
data: {
items: [{keypair: {name: 'keypair1'}}]
}
});
$timeout.flush();
expect(nova.getKeypairs).toHaveBeenCalled();
expect(result.$$state.value.data.items[0].name).toBe('keypair1');
expect(result.$$state.value.data.items[0].trackBy).toBe('keypair1');
}));
});
});
})();

View File

@ -0,0 +1,5 @@
<hz-resource-panel resource-type-name="OS::Nova::Keypair">
<hz-resource-table resource-type-name="OS::Nova::Keypair"
track-by="trackBy">
</hz-resource-table>
</hz-resource-panel>

View File

@ -0,0 +1,8 @@
---
features:
- |
[`blueprint ng-keypairs <https://blueprints.launchpad.net/horizon/+spec/ng-keypairs>`_]
Add Angular Key Pairs panel. The Key Pairs panel allows users to view
a list of created or imported key pairs. This panel displays a table
view of the name and fingerprint of each key pair. Also, public key
is shown in expanded row.