From 93f2fc750919433892e97916a8326a9ec87997db Mon Sep 17 00:00:00 2001 From: Richard Jones Date: Wed, 16 Mar 2016 09:33:09 +1100 Subject: [PATCH] Make ngcontainers the default Swift UI Replace the old Swift UI with the new AngularJS implementation by default. Use setting in the enabled file to switch routing between the two, allowing HEAT interface to seamlessly work with both. Updated the release note with the new configuration information. Removed the unnecessary additional "ngcontainers" panel. Hard-coded the test suite to use the legacy panel - since they are all testing the legacy panel and those tests will be removed (or altered in the case of the stacks MappingTests) when the legacy panel is removed. Finally, I had to add a copyright notice to the enabled file because flake8 noticed because I touched it or something. Very random. Change-Id: Ie4325185f57654522f9331d617f142687effb70b Partially-Implements: blueprint angularize-swift Co-Author: Travis Tripp Co-Authored-By: Matt Borland --- .../templates/containers/ngindex.html} | 0 .../dashboards/project/containers/urls.py | 81 +++++++++++-------- .../dashboards/project/containers/views.py | 4 + .../project/ngcontainers/__init__.py | 0 .../dashboards/project/ngcontainers/panel.py | 23 ------ .../dashboards/project/ngcontainers/urls.py | 22 ----- .../dashboards/project/ngcontainers/views.py | 19 ----- .../project/containers/containers.module.js | 8 +- .../containers/objects-row-actions.service.js | 4 +- .../enabled/_1920_project_containers_panel.py | 27 +++++++ .../_1921_project_ng_containers_panel.py | 30 ------- .../openstack-service-api/swift.service.js | 2 +- .../swift.service.spec.js | 6 ++ openstack_dashboard/test/settings.py | 4 + .../bg-angularize-swift-9a1b44aa3646bc8c.yaml | 5 -- .../bp-angularize-swift-9a1b44aa3646bc8c.yaml | 9 +++ 16 files changed, 104 insertions(+), 140 deletions(-) rename openstack_dashboard/dashboards/project/{ngcontainers/templates/ngcontainers/index.html => containers/templates/containers/ngindex.html} (100%) delete mode 100644 openstack_dashboard/dashboards/project/ngcontainers/__init__.py delete mode 100644 openstack_dashboard/dashboards/project/ngcontainers/panel.py delete mode 100644 openstack_dashboard/dashboards/project/ngcontainers/urls.py delete mode 100644 openstack_dashboard/dashboards/project/ngcontainers/views.py delete mode 100644 openstack_dashboard/enabled/_1921_project_ng_containers_panel.py delete mode 100644 releasenotes/notes/bg-angularize-swift-9a1b44aa3646bc8c.yaml create mode 100644 releasenotes/notes/bp-angularize-swift-9a1b44aa3646bc8c.yaml diff --git a/openstack_dashboard/dashboards/project/ngcontainers/templates/ngcontainers/index.html b/openstack_dashboard/dashboards/project/containers/templates/containers/ngindex.html similarity index 100% rename from openstack_dashboard/dashboards/project/ngcontainers/templates/ngcontainers/index.html rename to openstack_dashboard/dashboards/project/containers/templates/containers/ngindex.html diff --git a/openstack_dashboard/dashboards/project/containers/urls.py b/openstack_dashboard/dashboards/project/containers/urls.py index d2e1f231b8..ff390c8787 100644 --- a/openstack_dashboard/dashboards/project/containers/urls.py +++ b/openstack_dashboard/dashboards/project/containers/urls.py @@ -16,6 +16,7 @@ # License for the specific language governing permissions and limitations # under the License. +from django.conf import settings from django.conf.urls import patterns from django.conf.urls import url @@ -24,46 +25,56 @@ from openstack_dashboard.dashboards.project.containers import views VIEW_MOD = 'openstack_dashboard.dashboards.project.containers.views' -# Swift containers and objects. -urlpatterns = patterns( - VIEW_MOD, - url(r'^((?P.+?)/)?(?P(.+/)+)?$', - views.ContainerView.as_view(), name='index'), +if settings.HORIZON_CONFIG['swift_panel'] == 'angular': + # New angular containers and objects + urlpatterns = [ + url(r'^container/((?P.+?)/)?' + '(?P(.+/)+)?$', + views.NgIndexView.as_view(), name='index'), + url(r'^$', + views.NgIndexView.as_view(), name='index') + ] +else: + # Legacy swift containers and objects + urlpatterns = patterns( + VIEW_MOD, + url(r'^((?P.+?)/)?(?P(.+/)+)?$', + views.ContainerView.as_view(), name='index'), - url(r'^(?P(.+/)+)?create$', - views.CreateView.as_view(), - name='create'), + url(r'^(?P(.+/)+)?create$', + views.CreateView.as_view(), + name='create'), - url(r'^(?P.+?)/(?P(.+/)+)' - '?container_detail$', - views.ContainerDetailView.as_view(), - name='container_detail'), + url(r'^(?P.+?)/(?P(.+/)+)' + '?container_detail$', + views.ContainerDetailView.as_view(), + name='container_detail'), - url(r'^(?P[^/]+)/(?P.+)/object_detail$', - views.ObjectDetailView.as_view(), - name='object_detail'), + url(r'^(?P[^/]+)/(?P.+)/object_detail$', + views.ObjectDetailView.as_view(), + name='object_detail'), - url(r'^(?P[^/]+)/(?P(.+/)+)?' - '(?P.+)/update$', - views.UpdateObjectView.as_view(), - name='object_update'), + url(r'^(?P[^/]+)/(?P(.+/)+)?' + '(?P.+)/update$', + views.UpdateObjectView.as_view(), + name='object_update'), - url(r'^(?P.+?)/(?P(.+/)+)?upload$', - views.UploadView.as_view(), - name='object_upload'), + url(r'^(?P.+?)/(?P(.+/)+)?upload$', + views.UploadView.as_view(), + name='object_upload'), - url(r'^(?P.+?)/(?P(.+/)+)' - '?create_pseudo_folder', - views.CreatePseudoFolderView.as_view(), - name='create_pseudo_folder'), + url(r'^(?P.+?)/(?P(.+/)+)' + '?create_pseudo_folder', + views.CreatePseudoFolderView.as_view(), + name='create_pseudo_folder'), - url(r'^(?P[^/]+)/' - r'(?P(.+/)+)?' - r'(?P.+)/copy$', - views.CopyView.as_view(), - name='object_copy'), + url(r'^(?P[^/]+)/' + r'(?P(.+/)+)?' + r'(?P.+)/copy$', + views.CopyView.as_view(), + name='object_copy'), - url(r'^(?P[^/]+)/(?P.+)/download$', - 'object_download', - name='object_download'), -) + url(r'^(?P[^/]+)/(?P.+)/download$', + 'object_download', + name='object_download'), + ) diff --git a/openstack_dashboard/dashboards/project/containers/views.py b/openstack_dashboard/dashboards/project/containers/views.py index 158600eeae..0b82701bfa 100644 --- a/openstack_dashboard/dashboards/project/containers/views.py +++ b/openstack_dashboard/dashboards/project/containers/views.py @@ -43,6 +43,10 @@ from openstack_dashboard.dashboards.project.containers \ from openstack_dashboard.dashboards.project.containers import utils +class NgIndexView(generic.TemplateView): + template_name = 'project/containers/ngindex.html' + + class ContainerView(browsers.ResourceBrowserView): browser_class = project_browsers.ContainerBrowser template_name = "project/containers/index.html" diff --git a/openstack_dashboard/dashboards/project/ngcontainers/__init__.py b/openstack_dashboard/dashboards/project/ngcontainers/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/openstack_dashboard/dashboards/project/ngcontainers/panel.py b/openstack_dashboard/dashboards/project/ngcontainers/panel.py deleted file mode 100644 index 1462ed300d..0000000000 --- a/openstack_dashboard/dashboards/project/ngcontainers/panel.py +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright 2015, Rackspace, US, Inc. -# -# 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. - -from django.utils.translation import ugettext_lazy as _ - -import horizon - - -class NGContainers(horizon.Panel): - name = _("Containers") - slug = 'ngcontainers' - permissions = ('openstack.services.object-store',) diff --git a/openstack_dashboard/dashboards/project/ngcontainers/urls.py b/openstack_dashboard/dashboards/project/ngcontainers/urls.py deleted file mode 100644 index 743d359386..0000000000 --- a/openstack_dashboard/dashboards/project/ngcontainers/urls.py +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright 2015, Rackspace, US, Inc. -# -# 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. - -from django.conf.urls import url - -from openstack_dashboard.dashboards.project.ngcontainers import views - -urlpatterns = [ - url(r'^(container/(?P.+?)/(?P(.+/)+)?)?$', - views.IndexView.as_view(), name='index') -] diff --git a/openstack_dashboard/dashboards/project/ngcontainers/views.py b/openstack_dashboard/dashboards/project/ngcontainers/views.py deleted file mode 100644 index 87d0e0c45a..0000000000 --- a/openstack_dashboard/dashboards/project/ngcontainers/views.py +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright 2015, Rackspace, US, Inc. -# -# 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. - -from django.views import generic - - -class IndexView(generic.TemplateView): - template_name = 'project/ngcontainers/index.html' diff --git a/openstack_dashboard/dashboards/project/static/dashboard/project/containers/containers.module.js b/openstack_dashboard/dashboards/project/static/dashboard/project/containers/containers.module.js index 9fc83974a1..bc28395a0b 100644 --- a/openstack_dashboard/dashboards/project/static/dashboard/project/containers/containers.module.js +++ b/openstack_dashboard/dashboards/project/static/dashboard/project/containers/containers.module.js @@ -43,20 +43,20 @@ var path = $windowProvider.$get().STATIC_URL + 'dashboard/project/containers/'; $provide.constant('horizon.dashboard.project.containers.basePath', path); - var baseRoute = $windowProvider.$get().WEBROOT + 'project/ngcontainers/'; + var baseRoute = 'project/containers/'; $provide.constant('horizon.dashboard.project.containers.baseRoute', baseRoute); var containerRoute = baseRoute + 'container/'; $provide.constant('horizon.dashboard.project.containers.containerRoute', containerRoute); $routeProvider - .when(baseRoute, { + .when('/' + baseRoute, { templateUrl: path + 'select-container.html' }) - .when(containerRoute + ':container', { + .when('/' + containerRoute + ':container', { templateUrl: path + 'objects.html' }) - .when(containerRoute + ':container/:folder*', { + .when('/' + containerRoute + ':container/:folder*', { templateUrl: path + 'objects.html' }); } diff --git a/openstack_dashboard/dashboards/project/static/dashboard/project/containers/objects-row-actions.service.js b/openstack_dashboard/dashboards/project/static/dashboard/project/containers/objects-row-actions.service.js index 754ade9410..65dde32dad 100644 --- a/openstack_dashboard/dashboards/project/static/dashboard/project/containers/objects-row-actions.service.js +++ b/openstack_dashboard/dashboards/project/static/dashboard/project/containers/objects-row-actions.service.js @@ -75,7 +75,9 @@ function downloadService($qExtensions) { return { allowed: function allowed(file) { return $qExtensions.booleanAsPromise(file.is_object); }, - perform: function perform(file) { return file.url; } + // remove leading url slash to ensure uses relative link/base path + // thus using webroot. + perform: function perform(file) { return file.url.replace(/^\//, ''); } }; } diff --git a/openstack_dashboard/enabled/_1920_project_containers_panel.py b/openstack_dashboard/enabled/_1920_project_containers_panel.py index 1332b1d4c5..305bdf3c64 100644 --- a/openstack_dashboard/enabled/_1920_project_containers_panel.py +++ b/openstack_dashboard/enabled/_1920_project_containers_panel.py @@ -1,3 +1,17 @@ +# Copyright 2016, Rackspace, US, Inc. +# +# 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. + # The slug of the panel to be added to HORIZON_CONFIG. Required. PANEL = 'containers' # The slug of the dashboard the PANEL associated with. Required. @@ -8,3 +22,16 @@ PANEL_GROUP = 'object_store' # Python panel class of the PANEL to be added. ADD_PANEL = ('openstack_dashboard.dashboards.project.' 'containers.panel.Containers') + +DISABLED = False + +# Which implementation of the panel should we use? Valid options +# here are 'angular' (new implementation) and 'legacy' (old +# implementation.) +UPDATE_HORIZON_CONFIG = { + 'swift_panel': 'angular' +} + +ADD_SCSS_FILES = [ + 'dashboard/project/containers/_containers.scss', +] diff --git a/openstack_dashboard/enabled/_1921_project_ng_containers_panel.py b/openstack_dashboard/enabled/_1921_project_ng_containers_panel.py deleted file mode 100644 index b77245da98..0000000000 --- a/openstack_dashboard/enabled/_1921_project_ng_containers_panel.py +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright 2016, Rackspace, US, Inc. -# -# 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. -# -# The slug of the panel to be added to HORIZON_CONFIG. Required. -PANEL = 'ngcontainers' -# The slug of the dashboard the PANEL associated with. Required. -PANEL_DASHBOARD = 'project' -# The slug of the panel group the PANEL is associated with. -PANEL_GROUP = 'object_store' - -# Python panel class of the PANEL to be added. -ADD_PANEL = ('openstack_dashboard.dashboards.project.' - 'ngcontainers.panel.NGContainers') - -DISABLED = True - -ADD_SCSS_FILES = [ - 'dashboard/project/containers/_containers.scss', -] diff --git a/openstack_dashboard/static/app/core/openstack-service-api/swift.service.js b/openstack_dashboard/static/app/core/openstack-service-api/swift.service.js index 8ee70bc588..c772b622f5 100644 --- a/openstack_dashboard/static/app/core/openstack-service-api/swift.service.js +++ b/openstack_dashboard/static/app/core/openstack-service-api/swift.service.js @@ -69,7 +69,7 @@ */ function getObjectURL(container, object, type) { var urlType = type || 'object'; - var objectUrl = encodeURIComponent(object).replace('%2F', '/'); + var objectUrl = encodeURIComponent(object).replace(/%2F/g, '/'); return getContainerURL(container) + '/' + urlType + '/' + objectUrl; } diff --git a/openstack_dashboard/static/app/core/openstack-service-api/swift.service.spec.js b/openstack_dashboard/static/app/core/openstack-service-api/swift.service.spec.js index 7ab0176d7d..d1a91fd09e 100644 --- a/openstack_dashboard/static/app/core/openstack-service-api/swift.service.spec.js +++ b/openstack_dashboard/static/app/core/openstack-service-api/swift.service.spec.js @@ -204,6 +204,12 @@ ); }); + it('constructs object URLs without munging any slashes', function test() { + expect(service.getObjectURL('spam', 'ham/sam/i/am')).toEqual( + '/api/swift/containers/spam/object/ham/sam/i/am' + ); + }); + it('constructs object URLs for different functions', function test() { expect(service.getObjectURL('spam', 'ham', 'blah')).toEqual( '/api/swift/containers/spam/blah/ham' diff --git a/openstack_dashboard/test/settings.py b/openstack_dashboard/test/settings.py index 20fbfa4209..949fa79017 100644 --- a/openstack_dashboard/test/settings.py +++ b/openstack_dashboard/test/settings.py @@ -91,6 +91,10 @@ settings.update_dashboards( ) INSTALLED_APPS[0:0] = [] +# Remove this when the legacy panel is removed, along with its tests and +# the stacks MappingsTests are updated with the new URL path. +HORIZON_CONFIG['swift_panel'] = 'legacy' + find_static_files(HORIZON_CONFIG) # Set to True to allow users to upload images to glance via Horizon server. diff --git a/releasenotes/notes/bg-angularize-swift-9a1b44aa3646bc8c.yaml b/releasenotes/notes/bg-angularize-swift-9a1b44aa3646bc8c.yaml deleted file mode 100644 index dae8373ee9..0000000000 --- a/releasenotes/notes/bg-angularize-swift-9a1b44aa3646bc8c.yaml +++ /dev/null @@ -1,5 +0,0 @@ ---- -features: - - Move OpenStack Dashboard Swift panel rendering logic to client-side - using AngularJS for significant usability improvements. Set ``DISABLED=False`` in - ``enabled/_1921_project_ng_containers_panel.py`` to enable. diff --git a/releasenotes/notes/bp-angularize-swift-9a1b44aa3646bc8c.yaml b/releasenotes/notes/bp-angularize-swift-9a1b44aa3646bc8c.yaml new file mode 100644 index 0000000000..515384e525 --- /dev/null +++ b/releasenotes/notes/bp-angularize-swift-9a1b44aa3646bc8c.yaml @@ -0,0 +1,9 @@ +--- +features: + - Move OpenStack Dashboard Swift panel rendering logic to client-side + using AngularJS for significant usability improvements. +deprecations: + - The Python Swift panel has been deprecated and no longer displays + by default. To use the old interface edit + ``enabled/_1920_project_containers_panel.py`` to change + ``swift_panel`` to ``'legacy'``.