Restyle the service configuration
* Roll it back into a single page * Style the table like it's not a table * Have several tables on a single page * With vertical tabs * With arrow-like selected tab * Hide passwords Change-Id: Idead718e40f9b5efa5a37a6f87604a3f498577fc
This commit is contained in:
@@ -11,18 +11,50 @@
|
||||
# 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.html import escape # noqa
|
||||
from django.utils.safestring import mark_safe # noqa
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from horizon import tables
|
||||
|
||||
|
||||
def name_with_tooltip(parameter):
|
||||
if not parameter.description:
|
||||
return parameter.stripped_name
|
||||
return mark_safe(
|
||||
u'%s <a class="help-icon fa fa-question-circle" '
|
||||
u'data-content="%s" tabindex="0" href="#" '
|
||||
u'title="%s"></a>' % (
|
||||
escape(parameter.stripped_name),
|
||||
escape(parameter.description),
|
||||
escape(parameter.stripped_name),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def value_or_hidden(parameter):
|
||||
if parameter.hidden:
|
||||
return mark_safe(
|
||||
u'<span class="btn btn-xs btn-default password-button" '
|
||||
u'data-content="%s"'
|
||||
u'><i class="fa fa-eye"></i> %s</span>' % (
|
||||
escape(parameter.value),
|
||||
escape(_(u"Reveal")),
|
||||
),
|
||||
)
|
||||
return parameter.value
|
||||
|
||||
|
||||
class ParametersTable(tables.DataTable):
|
||||
name = tables.Column('stripped_name',
|
||||
verbose_name=_("Parameter Name"))
|
||||
value = tables.Column('value',
|
||||
verbose_name=_("Value"))
|
||||
description = tables.Column('description',
|
||||
verbose_name=_("Detailed Description"))
|
||||
name = tables.Column(
|
||||
name_with_tooltip,
|
||||
verbose_name=_("Parameter Name"),
|
||||
classes=['data-table-config-label'],
|
||||
)
|
||||
value = tables.Column(
|
||||
value_or_hidden,
|
||||
verbose_name=_("Value"),
|
||||
classes=['data-table-config-value'],
|
||||
)
|
||||
|
||||
def get_object_id(self, datum):
|
||||
return datum.name
|
||||
@@ -32,4 +64,34 @@ class ParametersTable(tables.DataTable):
|
||||
verbose_name = _("Service Configuration")
|
||||
table_actions = ()
|
||||
row_actions = ()
|
||||
template = "horizon/common/_enhanced_data_table.html"
|
||||
template = "horizon/common/_definition_list_data_table.html"
|
||||
|
||||
|
||||
class GlobalParametersTable(ParametersTable):
|
||||
class Meta(ParametersTable.Meta):
|
||||
name = "global_parameters"
|
||||
verbose_name = _("Global")
|
||||
|
||||
|
||||
class ControllerParametersTable(ParametersTable):
|
||||
class Meta(ParametersTable.Meta):
|
||||
name = "controller_parameters"
|
||||
verbose_name = _("Controller")
|
||||
|
||||
|
||||
class ComputeParametersTable(ParametersTable):
|
||||
class Meta(ParametersTable.Meta):
|
||||
name = "compute_parameters"
|
||||
verbose_name = _("Compute")
|
||||
|
||||
|
||||
class BlockStorageParametersTable(ParametersTable):
|
||||
class Meta(ParametersTable.Meta):
|
||||
name = "block_storage_parameters"
|
||||
verbose_name = _("Block Storage")
|
||||
|
||||
|
||||
class ObjectStorageParametersTable(ParametersTable):
|
||||
class Meta(ParametersTable.Meta):
|
||||
name = "object_storage_parameters"
|
||||
verbose_name = _("Object Storage")
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
# 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.datastructures import SortedDict
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from horizon import tabs
|
||||
|
||||
from tuskar_ui import api
|
||||
from tuskar_ui.infrastructure.parameters import tables
|
||||
|
||||
|
||||
class ParametersTab(tabs.TableTab):
|
||||
table_classes = (tables.ParametersTable,)
|
||||
template_name = "horizon/common/_detail_table.html"
|
||||
|
||||
def __init__(self, group, request, name, slug, parameters):
|
||||
self.name = name
|
||||
self.slug = slug
|
||||
self.parameters = parameters
|
||||
super(ParametersTab, self).__init__(group, request)
|
||||
|
||||
def get_parameters_data(self):
|
||||
return self.parameters
|
||||
|
||||
|
||||
class ParametersTabs(tabs.TabGroup):
|
||||
slug = "parameters"
|
||||
tabs = ()
|
||||
sticky = True
|
||||
template_name = "horizon/common/_items_count_tab_group.html"
|
||||
|
||||
def __init__(self, request, **kwargs):
|
||||
super(ParametersTabs, self).__init__(request, **kwargs)
|
||||
plan = api.tuskar.Plan.get_the_plan(request)
|
||||
params = plan.parameter_list(include_key_parameters=False)
|
||||
tab_instances = []
|
||||
general_params = [p for p in params if p.role is None]
|
||||
if general_params:
|
||||
tab_instances.append((
|
||||
'global',
|
||||
ParametersTab(self, request,
|
||||
_('Global'), 'global', general_params),
|
||||
))
|
||||
for role in plan.role_list:
|
||||
role_params = [p for p in params
|
||||
if p.role and p.role.uuid == role.uuid]
|
||||
if role_params:
|
||||
tab_instances.append((
|
||||
role.name,
|
||||
ParametersTab(self, request,
|
||||
role.name.title(), role.name, role_params),
|
||||
))
|
||||
self._tabs = SortedDict(tab_instances)
|
||||
@@ -9,9 +9,46 @@
|
||||
|
||||
{% block main %}
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
{{ tab_group.render }}
|
||||
<div class="col-xs-2">
|
||||
<ul class="nav nav-pills nav-stacked nav-arrow" role="tablist">
|
||||
<li class="active"><a href="#global" role="tab" data-toggle="tab">{% trans "Global" %}</a></li>
|
||||
<li><a href="#controller" role="tab" data-toggle="tab">{% trans "Controller" %}</a></li>
|
||||
<li><a href="#compute" role="tab" data-toggle="tab">{% trans "Compute" %}</a></li>
|
||||
<li><a href="#block-storage" role="tab" data-toggle="tab">{% trans "Block Storage" %}</a></li>
|
||||
<li><a href="#object-storage" role="tab" data-toggle="tab">{% trans "Object Storage" %}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-xs-10">
|
||||
<div class="tab-content panel panel-default configuration-panel">
|
||||
<div class="tab-pane active" id="global">
|
||||
{{ global_parameters_table.render }}
|
||||
</div>
|
||||
<div class="tab-pane" id="controller">
|
||||
{{ controller_parameters_table.render }}
|
||||
</div>
|
||||
<div class="tab-pane" id="compute">
|
||||
{{ compute_parameters_table.render }}
|
||||
</div>
|
||||
<div class="tab-pane" id="block-storage">
|
||||
{{ block_storage_parameters_table.render }}
|
||||
</div>
|
||||
<div class="tab-pane" id="object-storage">
|
||||
{{ object_storage_parameters_table.render }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
(window.$ || window.addHorizonLoadEvent)(function () {
|
||||
$('a.help-icon').popover({
|
||||
trigger: 'focus',
|
||||
placement: 'right'
|
||||
});
|
||||
$('span.password-button').popover({
|
||||
trigger: 'click',
|
||||
placement: 'top'
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -16,11 +16,11 @@ from django.core.urlresolvers import reverse
|
||||
from django.core.urlresolvers import reverse_lazy
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
import horizon.forms
|
||||
from horizon import tabs as horizon_tabs
|
||||
import horizon.tables
|
||||
|
||||
from tuskar_ui import api
|
||||
from tuskar_ui.infrastructure.parameters import forms
|
||||
from tuskar_ui.infrastructure.parameters import tabs
|
||||
from tuskar_ui.infrastructure.parameters import tables
|
||||
|
||||
|
||||
class ServiceConfigView(horizon.forms.ModalFormView):
|
||||
@@ -60,10 +60,43 @@ class ServiceConfigView(horizon.forms.ModalFormView):
|
||||
'virt_type': virt_type}
|
||||
|
||||
|
||||
class IndexView(horizon_tabs.TabbedTableView):
|
||||
tab_group_class = tabs.ParametersTabs
|
||||
class IndexView(horizon.tables.MultiTableView):
|
||||
table_classes = (
|
||||
tables.GlobalParametersTable,
|
||||
tables.ControllerParametersTable,
|
||||
tables.ComputeParametersTable,
|
||||
tables.BlockStorageParametersTable,
|
||||
tables.ObjectStorageParametersTable,
|
||||
)
|
||||
template_name = "infrastructure/parameters/index.html"
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
self.plan = api.tuskar.Plan.get_the_plan(request)
|
||||
self.parameters = self.plan.parameter_list(
|
||||
include_key_parameters=False)
|
||||
return super(IndexView, self).get(request, *args, **kwargs)
|
||||
|
||||
def _get_parameters(self, role_name=None):
|
||||
if not role_name:
|
||||
return [p for p in self.parameters if p.role is None]
|
||||
return [p for p in self.parameters
|
||||
if p.role and p.role.name == role_name]
|
||||
|
||||
def get_global_parameters_data(self):
|
||||
return self._get_parameters(None)
|
||||
|
||||
def get_controller_parameters_data(self):
|
||||
return self._get_parameters('controller')
|
||||
|
||||
def get_compute_parameters_data(self):
|
||||
return self._get_parameters('compute')
|
||||
|
||||
def get_block_storage_parameters_data(self):
|
||||
return self._get_parameters('cinder-storage')
|
||||
|
||||
def get_object_storage_parameters_data(self):
|
||||
return self._get_parameters('swift-storage')
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(IndexView, self).get_context_data(**kwargs)
|
||||
edit_action = {
|
||||
|
||||
@@ -194,3 +194,44 @@ $link-color: #428bca;
|
||||
#suggested-flavors-header {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
/* Configuration parameters */
|
||||
table .data-table-config-label {
|
||||
width: 20em;
|
||||
vertical-align: top;
|
||||
}
|
||||
table .data-table-config-value {
|
||||
font-weight: bold;
|
||||
}
|
||||
table.definition-list-table > thead {
|
||||
display: none;
|
||||
}
|
||||
table.definition-list-table > tbody > tr > td {
|
||||
border: 0;
|
||||
}
|
||||
ul.nav-arrow {
|
||||
& > li {
|
||||
z-index: 1000;
|
||||
position: relative;
|
||||
margin-right: -32px;
|
||||
}
|
||||
& > li.active:after {
|
||||
display: block;
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 1px;
|
||||
right: -7px;
|
||||
border-top: 18px solid transparent;
|
||||
border-bottom: 18px solid transparent;
|
||||
border-left: 8px solid $link-color;
|
||||
}
|
||||
}
|
||||
|
||||
.configuration-panel {
|
||||
min-height: 40em;
|
||||
}
|
||||
|
||||
.password-button + div.popover {
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
{% extends "horizon/common/_enhanced_data_table.html" %}
|
||||
|
||||
{% block table_css_classes %}table table-condensed definition-list-table {{ table.css_classes }}{% endblock %}
|
||||
|
||||
{% block table_footer %}{% endblock %}
|
||||
Reference in New Issue
Block a user