Merge "Angularize Key Pairs index view"
This commit is contained in:
commit
6aa242bd73
|
@ -48,6 +48,7 @@ Default:
|
|||
|
||||
{
|
||||
'images_panel': True,
|
||||
'key_pairs_panel': False,
|
||||
'flavors_panel': False,
|
||||
'users_panel': False,
|
||||
'roles_panel': False,
|
||||
|
|
|
@ -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'),
|
||||
]
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
@import "images/images";
|
||||
@import "keypairs/keypairs";
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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>
|
|
@ -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'
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
});
|
||||
});
|
||||
})();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
})();
|
|
@ -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');
|
||||
}));
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
})();
|
|
@ -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>
|
|
@ -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.
|
Loading…
Reference in New Issue