Adding Angular Project Images Table
This patch adds the images table to the projects panel. It follows the pattern established by the following review: https://review.openstack.org/#/c/197373/ However, it pre-fixes the table files with images- to make them easier to find via search in tools like the pycharms debugger and it the javascript console on various browsers. To be added in subsequent patches: - Actions - Forms - Common images table directive (TBD) - Filters via Magic Search - Integration to Searchlight To test set DISABLED = False in _203_project_images_panel.py Change-Id: I5e509fb807c356d3fb4b58e974ffa160828dbf88 Partially-Implements: blueprint angularize-images-table
This commit is contained in:
parent
e62918d706
commit
eaf27075b6
@ -288,9 +288,11 @@ $em-per-priority: floor($table-col-avg-width / $font-size-base) * 3;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.rsp-alt-p1, .rsp-alt-p2,
|
||||
.rsp-alt-p3, .rsp-alt-p4 {
|
||||
display: inline-block;
|
||||
th,td {
|
||||
&.rsp-alt-p1, &.rsp-alt-p2,
|
||||
&.rsp-alt-p3, &.rsp-alt-p4 {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,4 +8,5 @@
|
||||
{% endblock page_header %}
|
||||
|
||||
{% block main %}
|
||||
<ng-include src="'{{ STATIC_URL }}app/core/images/table/images-table.html'"></ng-include>
|
||||
{% endblock %}
|
||||
|
@ -0,0 +1,46 @@
|
||||
/**
|
||||
* (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';
|
||||
|
||||
/**
|
||||
* @ngdoc overview
|
||||
* @ngname hz.dashboard.project.images
|
||||
*
|
||||
* @description
|
||||
* Provides the services and widgets required
|
||||
* to support and display the project images panel.
|
||||
*/
|
||||
angular
|
||||
.module('hz.dashboard.project.images', [])
|
||||
.config(config);
|
||||
|
||||
config.$inject = [
|
||||
'$provide',
|
||||
'$windowProvider'
|
||||
];
|
||||
|
||||
/**
|
||||
* @name hz.dashboard.project.images.basePath
|
||||
* @description Base path for the project dashboard
|
||||
*/
|
||||
function config($provide, $windowProvider) {
|
||||
var path = $windowProvider.$get().STATIC_URL + 'dashboard/project/images/';
|
||||
$provide.constant('hz.dashboard.project.images.basePath', path);
|
||||
}
|
||||
|
||||
})();
|
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* (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('hz.dashboard.project.images', function() {
|
||||
it('should exist', function() {
|
||||
expect(angular.module('hz.dashboard.project.images')).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('hz.dashboard.project.images.basePath constant', function () {
|
||||
var imagesBasePath, staticUrl;
|
||||
|
||||
beforeEach(module('hz.dashboard'));
|
||||
beforeEach(module('hz.dashboard.project'));
|
||||
beforeEach(module('hz.dashboard.project.images'));
|
||||
beforeEach(inject(function ($injector) {
|
||||
imagesBasePath = $injector.get('hz.dashboard.project.images.basePath');
|
||||
staticUrl = $injector.get('$window').STATIC_URL;
|
||||
}));
|
||||
|
||||
it('should be defined', function () {
|
||||
expect(imagesBasePath).toBeDefined();
|
||||
});
|
||||
|
||||
it('should equal to "/static/dashboard/project/images/"', function () {
|
||||
expect(imagesBasePath).toEqual(staticUrl + 'dashboard/project/images/');
|
||||
});
|
||||
});
|
||||
|
||||
})();
|
@ -18,12 +18,28 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc hz.dashboard.project
|
||||
* @ngModule
|
||||
* @ngdoc overview
|
||||
* @ngname hz.dashboard.project
|
||||
*
|
||||
* @description
|
||||
* Dashboard module to host project panels.
|
||||
*/
|
||||
angular
|
||||
.module('hz.dashboard.project', []);
|
||||
.module('hz.dashboard.project', ['hz.dashboard.project.images'])
|
||||
.config(config);
|
||||
|
||||
config.$inject = [
|
||||
'$provide',
|
||||
'$windowProvider'
|
||||
];
|
||||
|
||||
/**
|
||||
* @name hz.dashboard.project.basePath
|
||||
* @description Base path for the project dashboard
|
||||
*/
|
||||
function config($provide, $windowProvider) {
|
||||
var path = $windowProvider.$get().STATIC_URL + 'dashboard/project/';
|
||||
$provide.constant('hz.dashboard.project.basePath', path);
|
||||
}
|
||||
|
||||
})();
|
||||
|
@ -22,4 +22,23 @@
|
||||
});
|
||||
});
|
||||
|
||||
describe('hz.dashboard.project.basePath constant', function () {
|
||||
var projectBasePath, staticUrl;
|
||||
|
||||
beforeEach(module('hz.dashboard'));
|
||||
beforeEach(module('hz.dashboard.project'));
|
||||
beforeEach(inject(function ($injector) {
|
||||
projectBasePath = $injector.get('hz.dashboard.project.basePath');
|
||||
staticUrl = $injector.get('$window').STATIC_URL;
|
||||
}));
|
||||
|
||||
it('should be defined', function () {
|
||||
expect(projectBasePath).toBeDefined();
|
||||
});
|
||||
|
||||
it('should equal to "/static/dashboard/project/"', function () {
|
||||
expect(projectBasePath).toEqual(staticUrl + 'dashboard/project/');
|
||||
});
|
||||
});
|
||||
|
||||
})();
|
||||
|
@ -28,6 +28,7 @@
|
||||
*/
|
||||
angular
|
||||
.module('horizon.app.core', [
|
||||
'horizon.app.core.images',
|
||||
'horizon.app.core.workflow'
|
||||
]);
|
||||
|
||||
|
1
openstack_dashboard/static/app/core/core.scss
Normal file
1
openstack_dashboard/static/app/core/core.scss
Normal file
@ -0,0 +1 @@
|
||||
@import "images/images";
|
@ -0,0 +1,49 @@
|
||||
/**
|
||||
* (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'
|
||||
];
|
||||
|
||||
/**
|
||||
* @ngdoc filter
|
||||
* @name imageStatusFilter
|
||||
* @description
|
||||
* Takes raw image status from the API and returns the user friendly status.
|
||||
*/
|
||||
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 function (input) {
|
||||
var result = imageStatuses[input];
|
||||
return angular.isDefined(result) ? result : input;
|
||||
};
|
||||
}
|
||||
|
||||
}());
|
@ -0,0 +1,40 @@
|
||||
/**
|
||||
* (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');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
})();
|
@ -0,0 +1,46 @@
|
||||
/**
|
||||
* (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'
|
||||
];
|
||||
|
||||
/**
|
||||
* @ngdoc filter
|
||||
* @name imageTypeFilter
|
||||
* @description
|
||||
* Takes a raw image object from the API and returns the user friendly type.
|
||||
*/
|
||||
function imageTypeFilter(gettext) {
|
||||
return function (input) {
|
||||
if (null !== input &&
|
||||
angular.isDefined(input) &&
|
||||
angular.isDefined(input.properties) &&
|
||||
input.properties.image_type === 'snapshot') {
|
||||
return gettext('Snapshot');
|
||||
} else {
|
||||
return gettext('Image');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}());
|
@ -0,0 +1,48 @@
|
||||
/**
|
||||
* (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(undefined)).toBe('Image');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
})();
|
46
openstack_dashboard/static/app/core/images/images.module.js
Normal file
46
openstack_dashboard/static/app/core/images/images.module.js
Normal file
@ -0,0 +1,46 @@
|
||||
/**
|
||||
* (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';
|
||||
|
||||
/**
|
||||
* @ngdoc overview
|
||||
* @ngname horizon.app.core.images
|
||||
*
|
||||
* @description
|
||||
* Provides all of the services and widgets required
|
||||
* to support and display images related content.
|
||||
*/
|
||||
angular
|
||||
.module('horizon.app.core.images', [])
|
||||
.config(config);
|
||||
|
||||
config.$inject = [
|
||||
'$provide',
|
||||
'$windowProvider'
|
||||
];
|
||||
|
||||
/**
|
||||
* @name horizon.app.core.images.basePath
|
||||
* @description Base path for the images code
|
||||
*/
|
||||
function config($provide, $windowProvider) {
|
||||
var path = $windowProvider.$get().STATIC_URL + 'app/core/images/';
|
||||
$provide.constant('horizon.app.core.images.basePath', path);
|
||||
}
|
||||
|
||||
})();
|
@ -0,0 +1,44 @@
|
||||
/**
|
||||
* (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', function () {
|
||||
it('should exist', function () {
|
||||
expect(angular.module('horizon.app.core.images')).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('horizon.app.core.images.basePath constant', function () {
|
||||
var imagesBasePath, staticUrl;
|
||||
|
||||
beforeEach(module('horizon.app.core'));
|
||||
beforeEach(module('horizon.app.core.images'));
|
||||
beforeEach(inject(function ($injector) {
|
||||
imagesBasePath = $injector.get('horizon.app.core.images.basePath');
|
||||
staticUrl = $injector.get('$window').STATIC_URL;
|
||||
}));
|
||||
|
||||
it('should be defined', function () {
|
||||
expect(imagesBasePath).toBeDefined();
|
||||
});
|
||||
|
||||
it('should equal to "/static/app/core/images/"', function () {
|
||||
expect(imagesBasePath).toEqual(staticUrl + 'app/core/images/');
|
||||
});
|
||||
});
|
||||
|
||||
})();
|
11
openstack_dashboard/static/app/core/images/images.scss
Normal file
11
openstack_dashboard/static/app/core/images/images.scss
Normal file
@ -0,0 +1,11 @@
|
||||
table[ng-controller="imagesTableController as table"] {
|
||||
|
||||
.detail-expanded .row {
|
||||
background: none;
|
||||
padding-left: 2em;
|
||||
}
|
||||
|
||||
&.table-rsp .action-col {
|
||||
min-width: 12em;
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
<!--
|
||||
Table-batch-actions:
|
||||
This is where batch actions like searching, creating, and deleting.
|
||||
-->
|
||||
|
||||
<th colspan="100" class="search-header">
|
||||
<hz-search-bar group-classes="input-group-sm" icon-classes="fa-search">
|
||||
|
||||
</hz-search-bar>
|
||||
</th>
|
@ -0,0 +1,10 @@
|
||||
<!--
|
||||
Table-footer:
|
||||
This is where we display number of items and pagination controls.
|
||||
Ensure colspan is greater or equal to number of column-headers.
|
||||
-->
|
||||
|
||||
<td colspan="100">
|
||||
<span class="display">{$ table.images.length|itemCount $}</span>
|
||||
<div st-pagination="" st-items-by-page="10" st-displayed-pages="10"></div>
|
||||
</td>
|
@ -0,0 +1,41 @@
|
||||
<!--
|
||||
Table-column-headers:
|
||||
This is where we declaratively define the table column headers.
|
||||
Include select-col if you want to select all.
|
||||
Include expander if you want to inline details.
|
||||
Include action-col if you want to perform actions.
|
||||
-->
|
||||
|
||||
<th class="select-col">
|
||||
<input type="checkbox" hz-select-all="table.images">
|
||||
</th>
|
||||
|
||||
<th class="expander"></th>
|
||||
|
||||
<th class="rsp-p1" st-sort="name" st-sort-default="name">
|
||||
<translate>Image Name</translate>
|
||||
</th>
|
||||
|
||||
<th class="rsp-p1" st-sort="type">
|
||||
<translate>Type</translate>
|
||||
</th>
|
||||
|
||||
<th class="rsp-p1" st-sort="status">
|
||||
<translate>Status</translate>
|
||||
</th>
|
||||
|
||||
<th class="rsp-p2" st-sort="is_public">
|
||||
<translate>Public</translate>
|
||||
</th>
|
||||
|
||||
<th class="rsp-p2" st-sort="protected">
|
||||
<translate>Protected</translate>
|
||||
</th>
|
||||
|
||||
<th class="rsp-p2" st-sort="disk_format">
|
||||
<translate>Format</translate>
|
||||
</th>
|
||||
|
||||
<th class="rsp-p2" st-sort="size">
|
||||
<translate>Size</translate>
|
||||
</th>
|
@ -0,0 +1,7 @@
|
||||
<!--
|
||||
Table-row-action-column:
|
||||
Actions taken here applies to a single item/row.
|
||||
-->
|
||||
|
||||
<action-list dropdown>
|
||||
</action-list>
|
@ -0,0 +1,55 @@
|
||||
<!--
|
||||
Detail-row:
|
||||
Contains detailed information on this item.
|
||||
Can be toggled using the chevron button.
|
||||
Ensure colspan is greater or equal to number of column-headers.
|
||||
-->
|
||||
|
||||
<td class="detail" colspan="100">
|
||||
|
||||
<div class="row">
|
||||
<span class="rsp-alt-p2">
|
||||
<dl class="col-sm-2">
|
||||
<dt translate>Public</dt>
|
||||
<dd>
|
||||
{$ image.is_public | yesno $}
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="col-sm-2">
|
||||
<dt translate>Protected</dt>
|
||||
<dd>
|
||||
{$ image.protected | yesno $}
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="col-sm-2">
|
||||
<dt translate>Format</dt>
|
||||
<dd>
|
||||
{$ image.disk_format || '--' $}
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="col-sm-2">
|
||||
<dt translate>Size</dt>
|
||||
<dd>
|
||||
{$ image.size | bytes $}
|
||||
</dd>
|
||||
</dl>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<dl class="col-sm-2">
|
||||
<dt translate>Min Disk (GB)</dt>
|
||||
<dd>
|
||||
{$ image.min_disk || '--' $}
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="col-sm-2">
|
||||
<dt translate>Min RAM (MB)</dt>
|
||||
<dd>
|
||||
{$ image.min_ram || '--' $}
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<!-- TODO Add in metadata defs from launch instance image details -->
|
||||
</td>
|
@ -0,0 +1,38 @@
|
||||
<!--
|
||||
Table-rows:
|
||||
This is where we declaratively define the table columns.
|
||||
Include select-col if you want to select all.
|
||||
Include expander if you want to inline details.
|
||||
Include action-col if you want to perform actions.
|
||||
rsp-p1 rsp-p2 are responsive priority as user resizes window.
|
||||
-->
|
||||
|
||||
<tr ng-repeat-start="image in table.images track by image.id"
|
||||
ng-class="{'st-selected': checked[image.id]}">
|
||||
|
||||
<td class="select-col">
|
||||
<input type="checkbox"
|
||||
ng-model="selected[image.id].checked"
|
||||
hz-select="image">
|
||||
</td>
|
||||
|
||||
<td class="expander">
|
||||
<i class="fa fa-chevron-right"
|
||||
hz-expand-detail
|
||||
duration="200">
|
||||
</i>
|
||||
</td>
|
||||
|
||||
<td class="rsp-p1">{$ image.name $}</td>
|
||||
<td class="rsp-p1">{$ image | imageType $}</td>
|
||||
<td class="rsp-p1">{$ image.status | imageStatus $}</td>
|
||||
<td class="rsp-p2">{$ image.is_public | yesno $}</td>
|
||||
<td class="rsp-p2">{$ image.protected | yesno $}</td>
|
||||
<td class="rsp-p2">{$ image.disk_format || '--' $}</td>
|
||||
<td class="rsp-p2">{$ image.size | bytes $}</td>
|
||||
|
||||
</tr>
|
||||
|
||||
<tr ng-repeat-end class="detail-row"
|
||||
ng-include="table.path + 'images-table-row-details.html'">
|
||||
</tr>
|
@ -0,0 +1,61 @@
|
||||
/**
|
||||
* (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';
|
||||
|
||||
/**
|
||||
* @ngdoc controller
|
||||
* @name ImagesTableController
|
||||
*
|
||||
* @description
|
||||
* Controller for the images table.
|
||||
* Serves as the focal point for table actions.
|
||||
*/
|
||||
angular
|
||||
.module('horizon.app.core.images')
|
||||
.controller('imagesTableController', ImagesTableController);
|
||||
|
||||
ImagesTableController.$inject = [
|
||||
'horizon.app.core.images.basePath',
|
||||
'horizon.openstack-service-api.glance'
|
||||
];
|
||||
|
||||
function ImagesTableController(basepath, glance) {
|
||||
|
||||
var ctrl = this;
|
||||
ctrl.images = [];
|
||||
ctrl.imagesSrc = [];
|
||||
ctrl.checked = {};
|
||||
ctrl.path = basepath + 'table/';
|
||||
|
||||
init();
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
function init() {
|
||||
// if user has permission
|
||||
// fetch table data and populate it
|
||||
glance.getImages().success(onGetImages);
|
||||
}
|
||||
|
||||
function onGetImages(response) {
|
||||
ctrl.imagesSrc = response.items;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
})();
|
@ -0,0 +1,68 @@
|
||||
/**
|
||||
* (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 table controller', function() {
|
||||
|
||||
function fakeGlance() {
|
||||
return {
|
||||
success: function(callback) {
|
||||
callback({
|
||||
items : []
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
var controller, glanceAPI, staticUrl;
|
||||
|
||||
///////////////////////
|
||||
|
||||
beforeEach(module('horizon.framework.util.http'));
|
||||
beforeEach(module('horizon.framework.widgets.toast'));
|
||||
beforeEach(module('horizon.openstack-service-api'));
|
||||
|
||||
beforeEach(module('horizon.app.core'));
|
||||
beforeEach(module('horizon.app.core.images'));
|
||||
beforeEach(inject(function($injector) {
|
||||
|
||||
glanceAPI = $injector.get('horizon.openstack-service-api.glance');
|
||||
controller = $injector.get('$controller');
|
||||
staticUrl = $injector.get('$window').STATIC_URL;
|
||||
|
||||
spyOn(glanceAPI, 'getImages').and.callFake(fakeGlance);
|
||||
}));
|
||||
|
||||
function createController() {
|
||||
return controller('imagesTableController', {
|
||||
glanceAPI: glanceAPI
|
||||
});
|
||||
}
|
||||
|
||||
it('should set path properly', function() {
|
||||
var path = staticUrl + 'app/core/images/table/';
|
||||
expect(createController().path).toEqual(path);
|
||||
});
|
||||
|
||||
it('should invoke glance apis', function() {
|
||||
createController();
|
||||
expect(glanceAPI.getImages).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
});
|
||||
})();
|
@ -0,0 +1,18 @@
|
||||
<table ng-controller="imagesTableController as table"
|
||||
hz-table ng-cloak
|
||||
st-table="table.images"
|
||||
st-safe-src="table.imagesSrc"
|
||||
default-sort="name"
|
||||
default-sort-reverse="false"
|
||||
class="table-striped table-rsp table-detail modern">
|
||||
|
||||
<thead>
|
||||
<tr ng-include="table.path + 'images-table-batch-actions.html'"></tr>
|
||||
<tr ng-include="table.path + 'images-table-header.html'"></tr>
|
||||
</thead>
|
||||
<tbody ng-include="table.path + 'images-table-rows.html'"></tbody>
|
||||
<tfoot>
|
||||
<tr ng-include="table.path + 'images-table-footer.html'"></tr>
|
||||
</tfoot>
|
||||
|
||||
</table>
|
@ -3,6 +3,7 @@
|
||||
|
||||
@import "scss/variables";
|
||||
@import "launch-instance/launch-instance";
|
||||
@import "/app/core/core";
|
||||
|
||||
// Custom Style Variables
|
||||
@import "/custom/styles";
|
||||
|
Loading…
Reference in New Issue
Block a user