From 12da76bd2d112a756b0b31cd689b774600411602 Mon Sep 17 00:00:00 2001 From: Shu Muto Date: Wed, 13 Jun 2018 17:16:20 +0900 Subject: [PATCH] Add details view for capsule This patch adds details view for capsule. Change-Id: Ia6a46b88aeedaea3642c1d424fedaae65f485655 Partial-Implements: blueprint capsule --- zun_ui/api/client.py | 4 ++ zun_ui/api/rest_api.py | 11 ++++ .../container/capsules/capsules.module.js | 22 ++++---- .../container/capsules/capsules.service.js | 34 +++++++++++-- .../capsules/details/details.module.js | 51 +++++++++++++++++++ .../capsules/details/overview.controller.js | 37 ++++++++++++++ .../container/capsules/details/overview.html | 50 ++++++++++++++++++ .../container/capsules/drawer.controller.js | 36 +++++++++++++ .../dashboard/container/capsules/drawer.html | 3 +- .../static/dashboard/container/zun.service.js | 6 +++ 10 files changed, 239 insertions(+), 15 deletions(-) create mode 100644 zun_ui/static/dashboard/container/capsules/details/details.module.js create mode 100644 zun_ui/static/dashboard/container/capsules/details/overview.controller.js create mode 100644 zun_ui/static/dashboard/container/capsules/details/overview.html create mode 100644 zun_ui/static/dashboard/container/capsules/drawer.controller.js diff --git a/zun_ui/api/client.py b/zun_ui/api/client.py index baa0e1e..545c9ec 100644 --- a/zun_ui/api/client.py +++ b/zun_ui/api/client.py @@ -272,6 +272,10 @@ def capsule_list(request, limit=None, marker=None, sort_key=None, sort_dir) +def capsule_show(request, id): + return zunclient(request).capsules.get(id) + + def image_list(request, limit=None, marker=None, sort_key=None, sort_dir=None, detail=False): # FIXME(shu-mutou): change "detail" param to True, if it enabled. diff --git a/zun_ui/api/rest_api.py b/zun_ui/api/rest_api.py index e2d05f4..1224ba4 100644 --- a/zun_ui/api/rest_api.py +++ b/zun_ui/api/rest_api.py @@ -179,6 +179,17 @@ class Capsules(generic.View): return {'items': [i.to_dict() for i in result]} +@urls.register +class Capsule(generic.View): + """API for retrieving a single capsule""" + url_regex = r'zun/capsules/(?P[^/]+)$' + + @rest_utils.ajax() + def get(self, request, id): + """Get a specific capsule""" + return change_to_id(client.capsule_show(request, id).to_dict()) + + @urls.register class Images(generic.View): """API for Zun Images""" diff --git a/zun_ui/static/dashboard/container/capsules/capsules.module.js b/zun_ui/static/dashboard/container/capsules/capsules.module.js index e2bb326..7785d5d 100644 --- a/zun_ui/static/dashboard/container/capsules/capsules.module.js +++ b/zun_ui/static/dashboard/container/capsules/capsules.module.js @@ -26,7 +26,8 @@ angular .module('horizon.dashboard.container.capsules', [ 'ngRoute', - 'horizon.dashboard.container.capsules.actions' + 'horizon.dashboard.container.capsules.actions', + 'horizon.dashboard.container.capsules.details' ]) .constant('horizon.dashboard.container.capsules.events', events()) .constant('horizon.dashboard.container.capsules.resourceType', 'OS::Zun::Capsule') @@ -47,6 +48,7 @@ } run.$inject = [ + '$filter', 'horizon.framework.conf.resource-type-registry.service', 'horizon.app.core.openstack-service-api.zun', 'horizon.dashboard.container.capsules.basePath', @@ -54,19 +56,19 @@ 'horizon.dashboard.container.capsules.service' ]; - function run(registry, zun, basePath, resourceType, capsuleService) { + function run($filter, registry, zun, basePath, resourceType, capsuleService) { registry.getResourceType(resourceType) .setNames(gettext('Capsule'), gettext('Capsules')) - // for detail summary view on table row. .setSummaryTemplateUrl(basePath + 'drawer.html') - // for table row items and detail summary view. + .setDefaultIndexUrl('/project/container/capsules/') .setProperties(capsuleProperties()) .setListFunction(capsuleService.getCapsulesPromise) .tableColumns .append({ - id: 'meta_name', + id: 'name', priority: 1, - sortDefault: true + sortDefault: true, + urlFunction: capsuleService.getDetailsPath }) .append({ id: 'id', @@ -87,13 +89,13 @@ // for magic-search registry.getResourceType(resourceType).filterFacets .append({ - 'label': gettext('ID'), - 'name': 'id', + 'label': gettext('Capsule ID'), + 'name': 'capsule_id', 'singleton': true }) .append({ 'label': gettext('Name'), - 'name': 'meta_name', + 'name': 'name', 'singleton': true }) .append({ @@ -115,7 +117,7 @@ 'links': {label: gettext('Links'), filters: ['noValue', 'json'] }, 'memory': { label: gettext('Memory'), filters: ['noValue'] }, 'meta_labels': {label: gettext('Labels'), filters: ['noValue', 'json'] }, - 'meta_name': { label: gettext('Name'), filters: ['noName'] }, + 'name': { label: gettext('Name'), filters: ['noName'] }, 'project_id': { label: gettext('Project ID'), filters: ['noValue'] }, 'restart_policy': { label: gettext('Restart Policy'), filters: ['noValue'] }, 'status': { label: gettext('Status'), filters: ['noValue'] }, diff --git a/zun_ui/static/dashboard/container/capsules/capsules.service.js b/zun_ui/static/dashboard/container/capsules/capsules.service.js index 9c18278..0fbec86 100644 --- a/zun_ui/static/dashboard/container/capsules/capsules.service.js +++ b/zun_ui/static/dashboard/container/capsules/capsules.service.js @@ -33,9 +33,36 @@ */ function capsulesService(detailRoute, zun) { return { + getDetailsPath: getDetailsPath, + getCapsulePromise: getCapsulePromise, getCapsulesPromise: getCapsulesPromise }; + /* + * @ngdoc function + * @name getDetailsPath + * @param item {Object} - The capsule object + * @description + * Returns the relative path to the details view. + */ + function getDetailsPath(item) { + return detailRoute + 'OS::Zun::Capsule/' + item.id; + } + + /* + * @ngdoc function + * @name getCapsulePromise + * @description + * Given an id, returns a promise for the capsule data. + */ + function getCapsulePromise(identifier) { + return zun.getCapsule(identifier).then(modifyDetails); + } + + function modifyDetails(response) { + return {data: modifyItem(response.data)}; + } + /* * @ngdoc function * @name getCapsulesPromise @@ -52,9 +79,10 @@ } function modifyItem(item) { - item.id = item.uuid; - item.trackBy = item.uuid; - item.trackBy = item.trackBy.concat(item.updated_at); + item.name = item.meta_name; + item.capsule_id = item.id; + item.id = item.uuid ? item.uuid : item.capsule_id; + item.trackBy = item.id.concat(item.updated_at); return item; } } diff --git a/zun_ui/static/dashboard/container/capsules/details/details.module.js b/zun_ui/static/dashboard/container/capsules/details/details.module.js new file mode 100644 index 0000000..6b03457 --- /dev/null +++ b/zun_ui/static/dashboard/container/capsules/details/details.module.js @@ -0,0 +1,51 @@ +/** + * 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.container.capsules.details + * + * @description + * Provides details features for capsule. + */ + angular.module('horizon.dashboard.container.capsules.details', + ['horizon.framework.conf', 'horizon.app.core']) + .run(registerDetails); + + registerDetails.$inject = [ + 'horizon.dashboard.container.capsules.basePath', + 'horizon.dashboard.container.capsules.resourceType', + 'horizon.dashboard.container.capsules.service', + 'horizon.framework.conf.resource-type-registry.service' + ]; + + function registerDetails( + basePath, + resourceType, + capsuleService, + registry + ) { + registry.getResourceType(resourceType) + .setLoadFunction(capsuleService.getCapsulePromise) + .detailsViews + .append({ + id: 'capsuleDetailsOverview', + name: gettext('Overview'), + template: basePath + 'details/overview.html' + }); + } +})(); diff --git a/zun_ui/static/dashboard/container/capsules/details/overview.controller.js b/zun_ui/static/dashboard/container/capsules/details/overview.controller.js new file mode 100644 index 0000000..b2fbb26 --- /dev/null +++ b/zun_ui/static/dashboard/container/capsules/details/overview.controller.js @@ -0,0 +1,37 @@ +/* + * 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.container.capsules') + .controller('horizon.dashboard.container.capsules.OverviewController', controller); + + controller.$inject = [ + '$scope', '$window' + ]; + + function controller( + $scope, $window + ) { + var ctrl = this; + ctrl.webRoot = $window.WEBROOT; + + $scope.context.loadPromise.then(onGetCapsule); + + function onGetCapsule(capsule) { + ctrl.capsule = capsule.data; + } + } +})(); diff --git a/zun_ui/static/dashboard/container/capsules/details/overview.html b/zun_ui/static/dashboard/container/capsules/details/overview.html new file mode 100644 index 0000000..37eab2b --- /dev/null +++ b/zun_ui/static/dashboard/container/capsules/details/overview.html @@ -0,0 +1,50 @@ +
+
+
+

Info

+
+ + +
+
+

Spec

+
+ + +
+
+
+
+

Containers

+
+
+
+
Name
+
{$ container.name $}
+
Container ID
+
{$ container.uuid $}
+
+
+
+
+

Volumes

+
+ + +
+
+
\ No newline at end of file diff --git a/zun_ui/static/dashboard/container/capsules/drawer.controller.js b/zun_ui/static/dashboard/container/capsules/drawer.controller.js new file mode 100644 index 0000000..8c6c05e --- /dev/null +++ b/zun_ui/static/dashboard/container/capsules/drawer.controller.js @@ -0,0 +1,36 @@ +/** + * 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 horizon.dashboard.container.capsules.DrawerController + * @description + * This is the controller for the drawer (summary) view. + * Its primary purpose is to provide the metadata definitions to + * the template via the ctrl.metadataDefs member. + */ + angular + .module('horizon.dashboard.container.capsules') + .controller('horizon.dashboard.container.capsules.DrawerController', controller); + + controller.$inject = [ + ]; + + function controller() { + } + +})(); diff --git a/zun_ui/static/dashboard/container/capsules/drawer.html b/zun_ui/static/dashboard/container/capsules/drawer.html index 4e0e9e9..3bd5dcd 100644 --- a/zun_ui/static/dashboard/container/capsules/drawer.html +++ b/zun_ui/static/dashboard/container/capsules/drawer.html @@ -2,6 +2,5 @@ resource-type-name="OS::Zun::Capsule" item="item" property-groups="[['id', 'cpu', 'memory', 'capsule_versionid'], - ['meta_labels', 'created_at', 'updated_at'], - ['addresses', 'volumes_info', 'status_reason']]"> + ['meta_labels', 'created_at', 'updated_at', 'status_reason']]"> diff --git a/zun_ui/static/dashboard/container/zun.service.js b/zun_ui/static/dashboard/container/zun.service.js index 6bbd8e5..7385648 100644 --- a/zun_ui/static/dashboard/container/zun.service.js +++ b/zun_ui/static/dashboard/container/zun.service.js @@ -54,6 +54,7 @@ updatePortSecurityGroup: updatePortSecurityGroup, getZunAvailabilityZones: getZunAvailabilityZones, getCapsules: getCapsules, + getCapsule: getCapsule, pullImage: pullImage, getImages: getImages, deleteImage: deleteImage, @@ -208,6 +209,11 @@ return apiService.get(capsulesPath).error(error(msg)); } + function getCapsule(id) { + var msg = gettext('Unable to retrieve the Capsule.'); + return apiService.get(capsulesPath + id).error(error(msg)); + } + //////////// // Images // ////////////