Plan editing form
Put back the form for selecting the numbers of instances. It will be later replaced with angular machinery. A the moment there is no way to update plan parameters on submit. Change-Id: I5bd345f38b1f630c384858f405d767e0003d3354
This commit is contained in:
parent
3d814c9b97
commit
8cdb60cb94
@ -12,12 +12,42 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import django.forms
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
import horizon.exceptions
|
||||
import horizon.forms
|
||||
import horizon.messages
|
||||
|
||||
from tuskar_ui import api
|
||||
import tuskar_ui.forms
|
||||
|
||||
|
||||
def _get_role_count(plan, role):
|
||||
return plan.parameter_value(role.node_count_parameter_name, 0)
|
||||
|
||||
|
||||
class EditPlan(horizon.forms.SelfHandlingForm):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(EditPlan, self).__init__(*args, **kwargs)
|
||||
self.plan = api.tuskar.OvercloudPlan.get_the_plan(self.request)
|
||||
self.fields.update(self._role_count_fields(self.plan))
|
||||
|
||||
def _role_count_fields(self, plan):
|
||||
fields = {}
|
||||
for role in plan.role_list:
|
||||
field = django.forms.IntegerField(
|
||||
label=role.name,
|
||||
widget=tuskar_ui.forms.NumberPickerInput,
|
||||
initial=_get_role_count(plan, role),
|
||||
# XXX Dirty hack for requiring a controller node.
|
||||
required=(role.name == 'Controller'),
|
||||
)
|
||||
fields['%s-count' % role.id] = field
|
||||
return fields
|
||||
|
||||
def handle(self, request, data):
|
||||
# XXX Update the plan.
|
||||
return True
|
||||
|
||||
|
||||
class DeployOvercloud(horizon.forms.SelfHandlingForm):
|
||||
|
@ -64,28 +64,22 @@
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<br />
|
||||
<div class="actions page-actions pull-left">
|
||||
<hr>
|
||||
<a href="{% url 'horizon:infrastructure:overview:undeploy_confirmation' %}"
|
||||
class="btn btn-danger ajax-modal">
|
||||
<i class="icon-fire icon-white"></i>
|
||||
<i class="glyphicon glyphicon-fire"></i>
|
||||
{% trans "Undeploy" %}
|
||||
</a>
|
||||
</div>
|
||||
{% else %}
|
||||
Ready to get deployed
|
||||
<ul>
|
||||
{% for role in roles %}
|
||||
{% if role.planned_node_count > 0 %}
|
||||
<li>{{ role.planned_node_count }} x {{ role.name }} </li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<div class="actions page-actions pull-left">
|
||||
<a href="{% url 'horizon:infrastructure:overview:deploy_confirmation' %}"
|
||||
class="btn btn-danger ajax-modal">
|
||||
<i class="icon-fire icon-white"></i>
|
||||
{% trans "Deploy" %}
|
||||
</a>
|
||||
</div>
|
||||
<h4>
|
||||
<span class="text-success" style="font-size: x-large; vertical-align:middle">
|
||||
<i class="glyphicon glyphicon-ok-circle"></i>
|
||||
</span>
|
||||
{% trans "Ready to get deployed" %}
|
||||
</h4>
|
||||
<a href="{% url 'horizon:infrastructure:overview:deploy_confirmation' %}"
|
||||
class="btn btn-danger ajax-modal">
|
||||
<i class="glyphicon glyphicon-cloud-upload"></i>
|
||||
{% trans "Deploy" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
|
@ -1,25 +1,32 @@
|
||||
{% load i18n %}
|
||||
{% load url from future %}
|
||||
{% load form_helpers %}
|
||||
|
||||
<h4>{% trans "Deployment Roles" %}</h4>
|
||||
<form method="POST" action="." class="deployment-roles-form">
|
||||
{% csrf_token %}
|
||||
{% include 'horizon/common/_form_errors.html' with form=form %}
|
||||
Deployment Roles
|
||||
<table class="table">
|
||||
{% for role in roles %}
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
{% if stack %}
|
||||
{% if role.total_node_count != role.deployed_node_count %}
|
||||
{{ role.deployed_node_count }} / {{ role.total_node_count }}
|
||||
{% else %}
|
||||
{{ role.total_node_count }}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{{ role.planned_node_count }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{{ role.name }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% for field in form.visible_fields %}
|
||||
<div class="form-group well well-sm clearfix{% if field.errors %} error{% endif %} {{ field.css_classes }}">
|
||||
<div class="col-sm-2">
|
||||
{{ field|add_bootstrap_class }}
|
||||
</div>
|
||||
<div class="col-sm-10">
|
||||
<label class="control-label" for="{{ field.id_for_label }}">
|
||||
{{ field.label }}
|
||||
</label>
|
||||
{% for error in field.errors %}
|
||||
<span class="help-block"><span class="text-danger">
|
||||
{{ error }}
|
||||
</span></span>
|
||||
{% empty %}
|
||||
{% if field.help_text %}
|
||||
<span class="help-block">{{ field.help_text }}</span>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<hr>
|
||||
<button type="submit" class="btn btn-default">{% trans "Update" %}</button>
|
||||
</form>
|
||||
|
@ -78,7 +78,11 @@ class OverviewTests(test.BaseAdminViewTests):
|
||||
call_args_list[0][0][0]
|
||||
self.assertListEqual(
|
||||
api.tuskar.OvercloudPlan.get_the_plan.call_args_list,
|
||||
[call(request), call(request)])
|
||||
[
|
||||
call(request),
|
||||
call(request),
|
||||
call(request),
|
||||
])
|
||||
self.assertTemplateUsed(
|
||||
res, 'infrastructure/overview/index.html')
|
||||
self.assertTemplateUsed(
|
||||
@ -96,8 +100,13 @@ class OverviewTests(test.BaseAdminViewTests):
|
||||
) as (OvercloudPlan, stack_get_mock, stack_events_mock):
|
||||
res = self.client.get(INDEX_URL)
|
||||
request = OvercloudPlan.get_the_plan.call_args_list[0][0][0]
|
||||
self.assertListEqual(OvercloudPlan.get_the_plan.call_args_list,
|
||||
[call(request), call(request)])
|
||||
self.assertListEqual(
|
||||
OvercloudPlan.get_the_plan.call_args_list,
|
||||
[
|
||||
call(request),
|
||||
call(request),
|
||||
call(request),
|
||||
])
|
||||
|
||||
self.assertTemplateUsed(
|
||||
res, 'infrastructure/overview/index.html')
|
||||
|
@ -12,12 +12,11 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
from django.core.urlresolvers import reverse
|
||||
|
||||
from django.core.urlresolvers import reverse_lazy
|
||||
import django.views.generic
|
||||
import heatclient
|
||||
|
||||
import horizon.forms
|
||||
from horizon.utils import memoized
|
||||
from horizon import views as horizon_views
|
||||
|
||||
from tuskar_ui import api
|
||||
from tuskar_ui.infrastructure.overview import forms
|
||||
@ -82,8 +81,18 @@ class StackMixin(object):
|
||||
return stack
|
||||
|
||||
|
||||
class IndexView(horizon_views.APIView, StackMixin):
|
||||
class IndexView(django.views.generic.FormView, StackMixin):
|
||||
template_name = 'infrastructure/overview/index.html'
|
||||
form_class = forms.EditPlan
|
||||
success_url = reverse_lazy(INDEX_URL)
|
||||
|
||||
def get_form(self, form_class):
|
||||
return form_class(self.request, **self.get_form_kwargs())
|
||||
|
||||
def get_context_data(self, *args, **kwargs):
|
||||
context = super(IndexView, self).get_context_data(*args, **kwargs)
|
||||
context.update(self.get_data(self.request, context))
|
||||
return context
|
||||
|
||||
def get_data(self, request, context, *args, **kwargs):
|
||||
plan = api.tuskar.OvercloudPlan.get_the_plan(request)
|
||||
|
@ -1,5 +1,17 @@
|
||||
<div class="number_picker unselectable">
|
||||
<a ng-click="decrementValue()" class="btn btn-link" ng-class="{disabled: disabledInput || disableArrow()}"><i ng-hide="disabledInput" class="icon-chevron-left"></i></a>
|
||||
<a
|
||||
ng-click="decrementValue()"
|
||||
class="arrow-left"
|
||||
ng-class="{disabled: disabledInput || disableArrow()}"
|
||||
>
|
||||
<i ng-hide="disabledInput" class="glyphicon glyphicon-chevron-left"></i>
|
||||
</a>
|
||||
<input type="text" value="{$value$}" ng-model="value">
|
||||
<a ng-click="incrementValue()" class="btn btn-link" ng-class="{disabled: disabledInput}"><i ng-hide="disabledInput" class="icon-chevron-right"></i></a>
|
||||
<a
|
||||
ng-click="incrementValue()"
|
||||
class="arrow-right"
|
||||
ng-class="{disabled: disabledInput}"
|
||||
>
|
||||
<i ng-hide="disabledInput" class="glyphicon glyphicon-chevron-right"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
@ -1,16 +1,34 @@
|
||||
// Number picker widget
|
||||
div.number_picker {
|
||||
margin: 5px 0;
|
||||
margin: 5px 14px;
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
padding: 0;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
vertical-align: middle;
|
||||
input {
|
||||
width: 35px;
|
||||
height: 30px;
|
||||
margin-bottom: 0;
|
||||
text-align: center;
|
||||
border: 0;
|
||||
width: 20px;
|
||||
display: block;
|
||||
margin: 8px auto;
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
}
|
||||
a {
|
||||
display: block;
|
||||
width: 14px;
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
cursor: default;
|
||||
&.disabled {
|
||||
cursor: default;
|
||||
}
|
||||
&.arrow-left {
|
||||
left: -14px;
|
||||
}
|
||||
&.arrow-right {
|
||||
right: -14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,10 @@
|
||||
{% load form_helpers %}
|
||||
|
||||
<div class="control-group{% if field.errors %} error{% endif %} {{ field.css_classes }}">
|
||||
<label class="control-label" for="{{ field.id_for_label }}">{{ field.label }}</label>
|
||||
<div class="controls">
|
||||
<div class="form-group{% if field.errors %} error{% endif %} {{ field.css_classes }}">
|
||||
<label class="control-label col-sm-3" for="{{ field.id_for_label }}">
|
||||
{{ field.label }}
|
||||
</label>
|
||||
<div class="col-sm-9">
|
||||
{{ field|add_bootstrap_class }}
|
||||
{% for error in field.errors %}
|
||||
<span class="help-inline text-error">{{ error }}</span>
|
||||
|
Loading…
x
Reference in New Issue
Block a user