Merge "Make ngcontainers the default Swift UI"

This commit is contained in:
Jenkins 2016-03-17 21:17:12 +00:00 committed by Gerrit Code Review
commit c45166c3fa
16 changed files with 104 additions and 140 deletions

View File

@ -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<container_name>.+?)/)?(?P<subfolder_path>(.+/)+)?$',
views.ContainerView.as_view(), name='index'),
if settings.HORIZON_CONFIG['swift_panel'] == 'angular':
# New angular containers and objects
urlpatterns = [
url(r'^container/((?P<container_name>.+?)/)?'
'(?P<subfolder_path>(.+/)+)?$',
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<container_name>.+?)/)?(?P<subfolder_path>(.+/)+)?$',
views.ContainerView.as_view(), name='index'),
url(r'^(?P<container_name>(.+/)+)?create$',
views.CreateView.as_view(),
name='create'),
url(r'^(?P<container_name>(.+/)+)?create$',
views.CreateView.as_view(),
name='create'),
url(r'^(?P<container_name>.+?)/(?P<subfolder_path>(.+/)+)'
'?container_detail$',
views.ContainerDetailView.as_view(),
name='container_detail'),
url(r'^(?P<container_name>.+?)/(?P<subfolder_path>(.+/)+)'
'?container_detail$',
views.ContainerDetailView.as_view(),
name='container_detail'),
url(r'^(?P<container_name>[^/]+)/(?P<object_path>.+)/object_detail$',
views.ObjectDetailView.as_view(),
name='object_detail'),
url(r'^(?P<container_name>[^/]+)/(?P<object_path>.+)/object_detail$',
views.ObjectDetailView.as_view(),
name='object_detail'),
url(r'^(?P<container_name>[^/]+)/(?P<subfolder_path>(.+/)+)?'
'(?P<object_name>.+)/update$',
views.UpdateObjectView.as_view(),
name='object_update'),
url(r'^(?P<container_name>[^/]+)/(?P<subfolder_path>(.+/)+)?'
'(?P<object_name>.+)/update$',
views.UpdateObjectView.as_view(),
name='object_update'),
url(r'^(?P<container_name>.+?)/(?P<subfolder_path>(.+/)+)?upload$',
views.UploadView.as_view(),
name='object_upload'),
url(r'^(?P<container_name>.+?)/(?P<subfolder_path>(.+/)+)?upload$',
views.UploadView.as_view(),
name='object_upload'),
url(r'^(?P<container_name>.+?)/(?P<subfolder_path>(.+/)+)'
'?create_pseudo_folder',
views.CreatePseudoFolderView.as_view(),
name='create_pseudo_folder'),
url(r'^(?P<container_name>.+?)/(?P<subfolder_path>(.+/)+)'
'?create_pseudo_folder',
views.CreatePseudoFolderView.as_view(),
name='create_pseudo_folder'),
url(r'^(?P<container_name>[^/]+)/'
r'(?P<subfolder_path>(.+/)+)?'
r'(?P<object_name>.+)/copy$',
views.CopyView.as_view(),
name='object_copy'),
url(r'^(?P<container_name>[^/]+)/'
r'(?P<subfolder_path>(.+/)+)?'
r'(?P<object_name>.+)/copy$',
views.CopyView.as_view(),
name='object_copy'),
url(r'^(?P<container_name>[^/]+)/(?P<object_path>.+)/download$',
'object_download',
name='object_download'),
)
url(r'^(?P<container_name>[^/]+)/(?P<object_path>.+)/download$',
'object_download',
name='object_download'),
)

View File

@ -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"

View File

@ -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',)

View File

@ -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<container_name>.+?)/(?P<subfolder_path>(.+/)+)?)?$',
views.IndexView.as_view(), name='index')
]

View File

@ -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'

View File

@ -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'
});
}

View File

@ -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(/^\//, ''); }
};
}

View File

@ -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',
]

View File

@ -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',
]

View File

@ -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;
}

View File

@ -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'

View File

@ -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.

View File

@ -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.

View File

@ -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'``.