Merge "Image uses hz-property for its drawer information"
This commit is contained in:
commit
97123bdd93
@ -1,34 +1,14 @@
|
||||
<div ng-controller="horizon.app.core.images.DrawerController as drawerCtrl">
|
||||
|
||||
<div class="row">
|
||||
<dl class="col-md-2">
|
||||
<dt translate>Is Public</dt>
|
||||
<dd>{$ item.is_public | yesno $}</dd>
|
||||
</dl>
|
||||
<dl class="col-md-2">
|
||||
<dt translate>Protected</dt>
|
||||
<dd>{$ item.protected | yesno $}</dd>
|
||||
</dl>
|
||||
<dl class="col-md-2">
|
||||
<dt translate>Format</dt>
|
||||
<dd>{$ item.disk_format | noValue | uppercase $}</dd>
|
||||
</dl>
|
||||
<dl class="col-md-2">
|
||||
<dt translate>Size</dt>
|
||||
<dd>{$ item.size | bytes $}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<dl class="col-md-2">
|
||||
<dt translate>Min. Disk</dt>
|
||||
<dd>{$ item.min_disk | gb | noValue $}</dd>
|
||||
</dl>
|
||||
<dl class="col-md-2">
|
||||
<dt translate>Min. RAM</dt>
|
||||
<dd>{$ item.min_ram | mb | noValue $}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<hz-resource-property-list
|
||||
resource-type-name="OS::Glance::Image"
|
||||
item="item"
|
||||
property-groups="[
|
||||
['name', 'id'],
|
||||
['is_public', 'protected'],
|
||||
['disk_format', 'size'],
|
||||
['min_disk', 'min_ram']]">
|
||||
</hz-resource-property-list>
|
||||
|
||||
<div class="row" ng-if="drawerCtrl.metadataDefs">
|
||||
<div class="col-sm-12">
|
||||
|
@ -3,29 +3,21 @@
|
||||
<div class="col-md-6 detail">
|
||||
<h3 translate>Image</h3>
|
||||
<hr>
|
||||
<dl class="dl-horizontal">
|
||||
<dt translate>Type</dt>
|
||||
<dd>{$ ctrl.image | imageType $}</dd>
|
||||
<dt translate>Filename</dt>
|
||||
<dd>{$ ctrl.image.properties.filename $}</dd>
|
||||
<dt translate>Status</dt>
|
||||
<dd>{$ ctrl.image.status $}</dd>
|
||||
<dt translate>Size</dt>
|
||||
<dd>{$ ctrl.image.size | bytes $}</dd>
|
||||
<dt translate>Min. Disk</dt>
|
||||
<dd>{$ ctrl.image.min_disk | gb $}</dd>
|
||||
<dt translate>Min. RAM</dt>
|
||||
<dd>{$ ctrl.image.min_ram | mb $}</dd>
|
||||
<dt translate>Disk Format</dt>
|
||||
<dd>{$ ctrl.image.disk_format | uppercase $}</dd>
|
||||
<dt translate>Container Format</dt>
|
||||
<dd>{$ ctrl.image.container_format | uppercase $}</dd>
|
||||
</dl>
|
||||
<hz-resource-property-list
|
||||
resource-type-name="OS::Glance::Image"
|
||||
cls="dl-horizontal"
|
||||
item="ctrl.image"
|
||||
property-groups="[[
|
||||
'type', 'status', 'size', 'min_disk', 'min_ram', 'disk_format',
|
||||
'container_format']]">
|
||||
</hz-resource-property-list>
|
||||
</div>
|
||||
<div class="col-md-6 detail">
|
||||
<h3>{$ 'Security' | translate $}</h3>
|
||||
<hr>
|
||||
<dl class="dl-horizontal">
|
||||
<dt translate>Filename</dt>
|
||||
<dd>{$ ctrl.image.properties.filename $}</dd>
|
||||
<dt translate>Visibility</dt>
|
||||
<dd>{$ ctrl.image | imageVisibility $}</dd>
|
||||
<dt translate>Protected</dt>
|
||||
|
@ -1,53 +0,0 @@
|
||||
/**
|
||||
* (c) Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
*
|
||||
* 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.images')
|
||||
.filter('imageStatus', imageStatusFilter);
|
||||
|
||||
imageStatusFilter.$inject = [
|
||||
'horizon.framework.util.i18n.gettext'
|
||||
];
|
||||
|
||||
function imageStatusFilter(gettext) {
|
||||
var imageStatuses = {
|
||||
'active': gettext('Active'),
|
||||
'saving': gettext('Saving'),
|
||||
'queued': gettext('Queued'),
|
||||
'pending_delete': gettext('Pending Delete'),
|
||||
'killed': gettext('Killed'),
|
||||
'deleted': gettext('Deleted')
|
||||
};
|
||||
|
||||
return filter;
|
||||
|
||||
/**
|
||||
* @ngdoc filter
|
||||
* @name imageStatusFilter
|
||||
* @param {string} input - The status code
|
||||
* @description
|
||||
* Takes raw image status from the API and returns the user friendly status.
|
||||
* @returns {string} The user-friendly status
|
||||
*/
|
||||
function filter(input) {
|
||||
var result = imageStatuses[input];
|
||||
return angular.isDefined(result) ? result : input;
|
||||
}
|
||||
}
|
||||
|
||||
}());
|
@ -1,40 +0,0 @@
|
||||
/**
|
||||
* (c) Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
*
|
||||
* 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.images.imageStatus Filter', function () {
|
||||
beforeEach(module('horizon.framework.util.i18n'));
|
||||
beforeEach(module('horizon.app.core.images'));
|
||||
|
||||
describe('iumageStatus', function () {
|
||||
var imageStatusFilter;
|
||||
beforeEach(inject(function (_imageStatusFilter_) {
|
||||
imageStatusFilter = _imageStatusFilter_;
|
||||
}));
|
||||
|
||||
it('Returns value when key is present', function () {
|
||||
expect(imageStatusFilter('active')).toBe('Active');
|
||||
});
|
||||
|
||||
it('Returns input when key is not present', function () {
|
||||
expect(imageStatusFilter('unknown')).toBe('unknown');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
})();
|
@ -1,50 +0,0 @@
|
||||
/**
|
||||
* (c) Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
*
|
||||
* 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.images')
|
||||
.filter('imageType', imageTypeFilter);
|
||||
|
||||
imageTypeFilter.$inject = [
|
||||
'horizon.framework.util.i18n.gettext'
|
||||
];
|
||||
|
||||
function imageTypeFilter(gettext) {
|
||||
return filter;
|
||||
|
||||
/**
|
||||
* @ngdoc filter
|
||||
* @name imageTypeFilter
|
||||
* @param {Object} input - An image object
|
||||
* @description
|
||||
* Takes a raw image object from the API and returns the user friendly type.
|
||||
* @returns {Function} The filter
|
||||
*/
|
||||
function filter(input) {
|
||||
if (null !== input &&
|
||||
angular.isDefined(input) &&
|
||||
angular.isDefined(input.properties) &&
|
||||
input.properties.image_type === 'snapshot') {
|
||||
return gettext('Snapshot');
|
||||
} else {
|
||||
return gettext('Image');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}());
|
@ -1,48 +0,0 @@
|
||||
/**
|
||||
* (c) Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||
*
|
||||
* 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.images.imageType Filter', function () {
|
||||
beforeEach(module('horizon.framework.util.i18n'));
|
||||
beforeEach(module('horizon.app.core.images'));
|
||||
|
||||
describe('imageType', function () {
|
||||
var imageTypeFilter;
|
||||
beforeEach(inject(function (_imageTypeFilter_) {
|
||||
imageTypeFilter = _imageTypeFilter_;
|
||||
}));
|
||||
|
||||
it('returns Snapshot for snapshot', function () {
|
||||
expect(imageTypeFilter({properties:{image_type:'snapshot'}})).toBe('Snapshot');
|
||||
});
|
||||
|
||||
it('returns Image for image', function () {
|
||||
expect(imageTypeFilter({properties:{image_type:'image'}})).toBe('Image');
|
||||
});
|
||||
|
||||
it('returns Image for null', function () {
|
||||
expect(imageTypeFilter(null)).toBe('Image');
|
||||
});
|
||||
|
||||
it('returns Image for undefined', function () {
|
||||
expect(imageTypeFilter()).toBe('Image');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
})();
|
@ -36,17 +36,26 @@
|
||||
.constant('horizon.app.core.images.validationRules', validationRules())
|
||||
.constant('horizon.app.core.images.imageFormats', imageFormats())
|
||||
.constant('horizon.app.core.images.resourceType', 'OS::Glance::Image')
|
||||
.constant('horizon.app.core.images.statuses', {
|
||||
'active': gettext('Active'),
|
||||
'saving': gettext('Saving'),
|
||||
'queued': gettext('Queued'),
|
||||
'pending_delete': gettext('Pending Delete'),
|
||||
'killed': gettext('Killed'),
|
||||
'deleted': gettext('Deleted')
|
||||
})
|
||||
.run(run)
|
||||
.config(config);
|
||||
|
||||
run.$inject = [
|
||||
'horizon.framework.conf.resource-type-registry.service',
|
||||
'horizon.app.core.openstack-service-api.glance',
|
||||
'horizon.app.core.images.basePath',
|
||||
'horizon.app.core.images.service',
|
||||
'horizon.app.core.images.statuses',
|
||||
'horizon.app.core.images.resourceType'
|
||||
];
|
||||
|
||||
function run(registry, glance, basePath, imageResourceType) {
|
||||
function run(registry, basePath, imagesService, statuses, imageResourceType) {
|
||||
registry.getResourceType(imageResourceType)
|
||||
.setNames(gettext('Image'), gettext('Images'))
|
||||
.setSummaryTemplateUrl(basePath + 'details/drawer.html')
|
||||
@ -54,19 +63,26 @@
|
||||
label: gettext('Checksum')
|
||||
})
|
||||
.setProperty('container_format', {
|
||||
label: gettext('Container Format')
|
||||
label: gettext('Container Format'),
|
||||
filters: ['uppercase']
|
||||
})
|
||||
.setProperty('created_at', {
|
||||
label: gettext('Created At')
|
||||
})
|
||||
.setProperty('disk_format', {
|
||||
label: gettext('Disk Format')
|
||||
label: gettext('Disk Format'),
|
||||
filters: ['noValue', 'uppercase']
|
||||
})
|
||||
.setProperty('id', {
|
||||
label: gettext('ID')
|
||||
})
|
||||
.setProperty('is_public', {
|
||||
label: gettext('Is Public'),
|
||||
filters: ['yesno']
|
||||
})
|
||||
.setProperty('type', {
|
||||
label: gettext('Type')
|
||||
label: gettext('Type'),
|
||||
filters: [imagesService.imageType]
|
||||
})
|
||||
.setProperty('members', {
|
||||
label: gettext('Members')
|
||||
@ -84,13 +100,16 @@
|
||||
label: gettext('Owner')
|
||||
})
|
||||
.setProperty('protected', {
|
||||
label: gettext('Protected')
|
||||
label: gettext('Protected'),
|
||||
filters: ['yesno']
|
||||
})
|
||||
.setProperty('size', {
|
||||
label: gettext('Size')
|
||||
label: gettext('Size'),
|
||||
filters: ['bytes']
|
||||
})
|
||||
.setProperty('status', {
|
||||
label: gettext('Status')
|
||||
label: gettext('Status'),
|
||||
values: statuses
|
||||
})
|
||||
.setProperty('tags', {
|
||||
label: gettext('Tags')
|
||||
@ -116,38 +135,33 @@
|
||||
.setProperty('ramdisk_id', {
|
||||
label: gettext('Ramdisk ID')
|
||||
})
|
||||
.setListFunction(listFunction)
|
||||
.setListFunction(imagesService.getImagesPromise)
|
||||
.tableColumns
|
||||
.append({
|
||||
id: 'name',
|
||||
priority: 1,
|
||||
sortDefault: true,
|
||||
urlFunction: urlFunction
|
||||
urlFunction: imagesService.getDetailsPath
|
||||
})
|
||||
.append({
|
||||
id: 'type',
|
||||
priority: 1,
|
||||
filters: ['imageType']
|
||||
priority: 1
|
||||
})
|
||||
.append({
|
||||
id: 'status',
|
||||
priority: 1,
|
||||
filters: ['imageStatus']
|
||||
priority: 1
|
||||
})
|
||||
.append({
|
||||
id: 'protected',
|
||||
priority: 1,
|
||||
filters: ['yesno']
|
||||
priority: 1
|
||||
})
|
||||
.append({
|
||||
id: 'disk_format',
|
||||
priority: 2,
|
||||
filters: ['noValue', 'uppercase']
|
||||
priority: 2
|
||||
})
|
||||
.append({
|
||||
id: 'size',
|
||||
priority: 2,
|
||||
filters: ['bytes']
|
||||
priority: 2
|
||||
});
|
||||
|
||||
registry.getResourceType(imageResourceType).filterFacets
|
||||
@ -214,23 +228,6 @@
|
||||
isServer: true,
|
||||
singleton: true
|
||||
});
|
||||
|
||||
function listFunction(params) {
|
||||
return glance.getImages(params).then(modifyResponse);
|
||||
|
||||
function modifyResponse(response) {
|
||||
return {data: {items: response.data.items.map(addTrackBy)}};
|
||||
|
||||
function addTrackBy(image) {
|
||||
image.trackBy = image.id + image.updated_at;
|
||||
return image;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function urlFunction(item) {
|
||||
return 'project/ngdetails/OS::Glance::Image/' + item.id;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
97
openstack_dashboard/static/app/core/images/images.service.js
Normal file
97
openstack_dashboard/static/app/core/images/images.service.js
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* (c) Copyright 2016 Hewlett Packard Enterprise Development LP
|
||||
*
|
||||
* 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.images')
|
||||
.factory('horizon.app.core.images.service', imageService);
|
||||
|
||||
imageService.$inject = [
|
||||
'horizon.app.core.openstack-service-api.glance'
|
||||
];
|
||||
|
||||
/*
|
||||
* @ngdoc factory
|
||||
* @name horizon.app.core.images.service
|
||||
*
|
||||
* @description
|
||||
* This service provides functions that are used through the Images
|
||||
* 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 imageService(glance) {
|
||||
return {
|
||||
getDetailsPath: getDetailsPath,
|
||||
getImagesPromise: getImagesPromise,
|
||||
imageType: imageType
|
||||
};
|
||||
|
||||
/*
|
||||
* @ngdoc function
|
||||
* @name getDetailsPath
|
||||
* @param item {Object} - The image object
|
||||
* @description
|
||||
* Given an Image object, returns the relative path to the details
|
||||
* view.
|
||||
*/
|
||||
function getDetailsPath(item) {
|
||||
return 'project/ngdetails/OS::Glance::Image/' + item.id;
|
||||
}
|
||||
|
||||
/*
|
||||
* @ngdoc function
|
||||
* @name imageType
|
||||
* @param item {Object} - The image object
|
||||
* @description
|
||||
* Given an Image object, returns a name describing the type of image,
|
||||
* either an 'Image' or a 'Snapshot' type.
|
||||
*/
|
||||
function imageType(item) {
|
||||
if (null !== item &&
|
||||
angular.isDefined(item) &&
|
||||
angular.isDefined(item.properties) &&
|
||||
item.properties.image_type === 'snapshot') {
|
||||
return gettext('Snapshot');
|
||||
} else {
|
||||
return gettext('Image');
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* @ngdoc function
|
||||
* @name getImagesPromise
|
||||
* @description
|
||||
* Given filter/query parameters, returns a promise for the matching
|
||||
* images. This is used in displaying lists of Images. 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 getImagesPromise(params) {
|
||||
return glance.getImages(params).then(modifyResponse);
|
||||
|
||||
function modifyResponse(response) {
|
||||
return {data: {items: response.data.items.map(addTrackBy)}};
|
||||
|
||||
function addTrackBy(image) {
|
||||
image.trackBy = image.id + image.updated_at;
|
||||
return image;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* (c) Copyright 2016 Hewlett Packard Enterprise Development LP
|
||||
*
|
||||
* 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('images service', function() {
|
||||
var service;
|
||||
beforeEach(module('horizon.app.core.images'));
|
||||
beforeEach(inject(function($injector) {
|
||||
service = $injector.get('horizon.app.core.images.service');
|
||||
}));
|
||||
|
||||
it("getDetailsPath creates urls using the item's ID", function() {
|
||||
var myItem = {id: "1234"};
|
||||
expect(service.getDetailsPath(myItem)).toBe('project/ngdetails/OS::Glance::Image/1234');
|
||||
});
|
||||
|
||||
describe('imageType', function() {
|
||||
it("imageType returns Snapshot when appropriate", function() {
|
||||
var myItem = {properties: {image_type: 'snapshot'}};
|
||||
expect(service.imageType(myItem)).toBe('Snapshot');
|
||||
});
|
||||
|
||||
it("imageType returns Image when no item", function() {
|
||||
var myItem;
|
||||
expect(service.imageType(myItem)).toBe('Image');
|
||||
});
|
||||
|
||||
it("imageType returns Image when no properties", function() {
|
||||
var myItem = {};
|
||||
expect(service.imageType(myItem)).toBe('Image');
|
||||
});
|
||||
|
||||
it("imageType returns Image when properties but not type 'snapshot'", function() {
|
||||
var myItem = {properties: {image_type: 'unknown'}};
|
||||
expect(service.imageType(myItem)).toBe('Image');
|
||||
});
|
||||
});
|
||||
|
||||
describe('getImagesPromise', function() {
|
||||
it("provides a promise that gets translated", inject(function($q, $injector, $timeout) {
|
||||
var glance = $injector.get('horizon.app.core.openstack-service-api.glance');
|
||||
var deferred = $q.defer();
|
||||
spyOn(glance, 'getImages').and.returnValue(deferred.promise);
|
||||
var result = service.getImagesPromise({});
|
||||
deferred.resolve({data: {items: [{id: 1, updated_at: 'jul1'}]}});
|
||||
$timeout.flush();
|
||||
expect(result.$$state.value.data.items[0].trackBy).toBe('1jul1');
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
})();
|
Loading…
x
Reference in New Issue
Block a user