Create/edit flavors directly in the resource class form.
The formset in the resource class create/edit form now starts empty, and allows the user to create or edit the flavors of that class directly. Flavor templates are no longer used. The formset starts with a single empty row at the end, for adding a new flavor, and a "Delete" column with checkboxes for deleting existing flavors. If javascript is available, there is a link for adding more empty rows and the empty line from the end is removed, and the checkboxes are replaced with a cross icon, for deleting the rows instantly. All traces of flavor templates have been removed from tuskar-ui. The Max VMs field has been temporarily removed -- it will be added in further iterations. Change-Id: I1ff4c9f90657c62e7c5f45a4b7874524b9df204c Implements: blueprint remove-flavor-templates
This commit is contained in:
@@ -131,7 +131,7 @@
|
||||
<tr>
|
||||
{% for flavor in resource_class.list_flavors %}
|
||||
<td class="flavor_usage_label">
|
||||
<a href="{% url 'horizon:infrastructure:resource_management:flavor_templates:detail' flavor.id %}">{{ flavor.name }}</a>
|
||||
{{ flavor.name }}
|
||||
</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
{% load i18n %}
|
||||
|
||||
{{ formset.management_form }}
|
||||
{% if formset.non_field_errors %}
|
||||
<div class="alert alert-error">
|
||||
{{ formset.non_field_errors }}
|
||||
</div>
|
||||
{% endif %}
|
||||
<table class="table table-bordered formset-table" id="{{ formset.prefix }}-formset-table">
|
||||
<thead>
|
||||
<tr class="table_caption"></tr>
|
||||
<tr>
|
||||
{% for field in flavors_formset.0.visible_fields %}
|
||||
<th class="normal_column head-{{ field.name }} {% if field.field.required %} required{% endif %}">
|
||||
<span>{{ field.field.label }}</span>
|
||||
</th>
|
||||
{% endfor %}
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
{% for form in formset %}
|
||||
<tr>
|
||||
{% for field in form.visible_fields %}
|
||||
<td class="control-group
|
||||
{% if field.errors %} error{% endif %}
|
||||
field-{{ field.name }}">
|
||||
{{ field }}
|
||||
{% for error in field.errors %}
|
||||
<span class="help-inline">{{ error }}</span>
|
||||
{% endfor %}
|
||||
{% if forloop.first %}
|
||||
{% for field in form.hidden_fields %}
|
||||
{{ field }}
|
||||
{% for error in field.errors %}
|
||||
<span class="help-inline">{{ field.name }}: {{ error }}</span>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% if form.non_field_errors %}
|
||||
<div class="alert alert-error">
|
||||
{{ form.non_field_errors }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr><td colspan="{{ flavors_formset.0.visible_fields|length }}">
|
||||
</td></tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
(function () {
|
||||
// prepares the js-enabled parts of the formset table
|
||||
var init_formset = function () {
|
||||
var prefix = '{{ formset.prefix|escapejs }}';
|
||||
var input_name_re = new RegExp('^' + prefix + '-\\d+-');
|
||||
var input_id_re = new RegExp('^id_' + prefix + '-\\d+-');
|
||||
var table = $('#' + prefix + '-formset-table');
|
||||
var empty_row = table.find('tbody tr:last').clone();
|
||||
|
||||
// go through the whole table and fix the numbering of rows
|
||||
var reenumerate_rows = function () {
|
||||
var count = 0;
|
||||
table.find('tbody tr').each(function () {
|
||||
$(this).find('input').each(function () {
|
||||
var input = $(this);
|
||||
input.attr('name', input.attr('name').replace(
|
||||
input_name_re,
|
||||
prefix + '-' + count + '-'));
|
||||
input.attr('id', input.attr('id').replace(
|
||||
input_id_re,
|
||||
'id_' + prefix + '-' + count + '-'));
|
||||
});
|
||||
count += 1;
|
||||
});
|
||||
$('#id_' + prefix + '-TOTAL_FORMS').val(count);
|
||||
$('#id_' + prefix + '-INITIAL_FORMS').val(count);
|
||||
};
|
||||
|
||||
// replace the "Delete" checkboxes with × for deleting rows
|
||||
var del_row = function () {
|
||||
$(this).closest('tr').remove();
|
||||
reenumerate_rows();
|
||||
};
|
||||
|
||||
$('<a href="#" class="close">×</a>').replaceAll(
|
||||
table.find('input[name$="-DELETE"]')
|
||||
).click(del_row);
|
||||
|
||||
// add more empty rows in the flavors table
|
||||
var add_row = function () {
|
||||
var new_row = empty_row.clone();
|
||||
// connect signals and clean up
|
||||
$('<a href="#" class="close">×</a>').replaceAll(
|
||||
new_row.find('input[name$="-DELETE"]')
|
||||
).click(del_row);
|
||||
new_row.find('input').val(null);
|
||||
new_row.find('td').removeClass('error')
|
||||
new_row.find('span.help-inline').remove();
|
||||
table.find('tbody').append(new_row);
|
||||
reenumerate_rows();
|
||||
};
|
||||
|
||||
$('#{{ formset.prefix }}-formset-table tfoot td').append(
|
||||
'<a href="#" class="btn">{% filter escapejs %}{% trans "Add a row" %}{% endfilter %}</a>'
|
||||
).click(add_row);
|
||||
|
||||
// if the formset is not empty, and is not being redisplayed,
|
||||
// delete the empty row from the end
|
||||
if (table.find('tbody tr').length > 1 &&
|
||||
$('#id_' + prefix + '-TOTAL_FORMS').val() >
|
||||
$('#id_' + prefix + '-INITIAL_FORMS').val()) {
|
||||
table.find('tbody tr:last').remove();
|
||||
reenumerate_rows();
|
||||
}
|
||||
};
|
||||
|
||||
if (typeof($) !== 'undefined') {
|
||||
$(init_formset);
|
||||
} else {
|
||||
addHorizonLoadEvent(init_formset);
|
||||
}
|
||||
} ());
|
||||
</script>
|
||||
@@ -1,4 +1,4 @@
|
||||
<noscript><h3>{{ step }}</h3>xx</noscript>
|
||||
<noscript><h3>{{ step }}</h3></noscript>
|
||||
<table class="table-fixed">
|
||||
<tbody>
|
||||
<tr>
|
||||
@@ -13,82 +13,31 @@
|
||||
</table>
|
||||
|
||||
<div id="id_resource_class_flavors_table">
|
||||
{{ flavors_formset.management_form }}
|
||||
{% if flavors_formset.non_field_errors %}
|
||||
<div class="alert alert-error">
|
||||
{{ flavors_formset.non_field_errors }}
|
||||
</div>
|
||||
{% endif %}
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr class="table_caption"></tr>
|
||||
<tr>
|
||||
{% for field in flavors_formset.0.visible_fields %}
|
||||
<th class="normal_column">{{ field.field.label }}</th>
|
||||
{% endfor %}
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
{% for form in flavors_formset %}
|
||||
<tr>
|
||||
{% for field in form.visible_fields %}
|
||||
<td class="control-group{% if field.errors %} error{% endif %}">
|
||||
{{ field }}
|
||||
{% for error in field.errors %}
|
||||
<span class="help-inline">{{ error }}</span>
|
||||
{% endfor %}
|
||||
{% if forloop.first %}
|
||||
{% for field in form.hidden_fields %}
|
||||
{{ field }}
|
||||
{% endfor %}
|
||||
{% if form.non_field_errors %}
|
||||
<div class="alert alert-error">
|
||||
{{ form.non_field_errors }}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr><td colspan="{{ flavors_formset.0.visible_fields|length }}"></tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
{% include 'infrastructure/resource_management/resource_classes/_formset.html' with formset=flavors_formset %}
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
(function () {
|
||||
// show the flavors table only when service_type is compute
|
||||
var toggle_table = function(value){
|
||||
if (value == 'compute'){
|
||||
$('#id_resource_class_flavors_table').show();
|
||||
}
|
||||
else{
|
||||
$('#id_resource_class_flavors_table').hide();
|
||||
}
|
||||
};
|
||||
toggle_table($('#id_service_type').val())
|
||||
var init_table = function () {
|
||||
var toggle_table = function (value) {
|
||||
if (value === 'compute') {
|
||||
$('#id_resource_class_flavors_table').show();
|
||||
} else {
|
||||
$('#id_resource_class_flavors_table').hide();
|
||||
}
|
||||
};
|
||||
|
||||
$('#id_service_type').change(function(){
|
||||
toggle_table($('#id_service_type').val())
|
||||
});
|
||||
|
||||
var toggle_max_vms = function(check_box){
|
||||
var checked = check_box.prop('checked');
|
||||
var id = check_box.val();
|
||||
|
||||
if (checked){
|
||||
$('input[name=flavors_object_ids__max_vms__' + id + "]").show();
|
||||
}
|
||||
else{
|
||||
$('input[name=flavors_object_ids__max_vms__' + id + "]").hide();
|
||||
}
|
||||
toggle_table($('#id_service_type').val())
|
||||
$('#id_service_type').change(function () {
|
||||
toggle_table($('#id_service_type').val());
|
||||
});
|
||||
};
|
||||
|
||||
$(".modal #flavors input[type=checkbox]").each(function() {
|
||||
toggle_max_vms($(this));
|
||||
});
|
||||
$(".modal #flavors input[type=checkbox]").bind('click', function() {
|
||||
toggle_max_vms($(this));
|
||||
});
|
||||
if (typeof($) !== 'undefined') {
|
||||
$(init_table);
|
||||
} else {
|
||||
addHorizonLoadEvent(init_table);
|
||||
}
|
||||
} ());
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user