diff options
Diffstat (limited to 'ogcp/templates/disk_inspector.html')
-rw-r--r-- | ogcp/templates/disk_inspector.html | 306 |
1 files changed, 306 insertions, 0 deletions
diff --git a/ogcp/templates/disk_inspector.html b/ogcp/templates/disk_inspector.html new file mode 100644 index 0000000..90a8996 --- /dev/null +++ b/ogcp/templates/disk_inspector.html @@ -0,0 +1,306 @@ +{% if selected_disk is defined and setup_data is defined %} + +<form class="form-inline" method="POST" id="setupForm"> + {{ disk_form.hidden_tag() }} + {{ disk_form.ips() }} + + <table class="table"> + <thead class="text-center"> + <tr> + <th>{{ _('Disk') }}</th> + <th>{{ _('Partition Table Type') }}</th> + <th>{{ _('Total Disk Size') }} (MiB)</th> + </tr> + </thead> + + <tbody data-target="partitons-fieldset" id="diskTable" class="text-center"> + <tr> + <td> + {{ disk_form.disk(class_="form-control", onchange="handleDiskChange(this)") }} + </td> + {{ disk_form.hidden_tag() }} + <td> + {% if readonly_disk_inspector is defined %} + {{ disk_form.disk_type(class_="form-control", id="diskType", readonly="readonly") }} + {% else %} + {{ disk_form.disk_type(class_="form-control", id="diskType") }} + {% endif %} + </td> + <td id="diskSize">{{ disk_size }}</td> + </tr> +</tbody> + </table> + <table class="table"> + <thead class="text-center"> + <tr> + <th>{{ _('Partition') }}</th> + <th>{{ _('Type') }}</th> + <th>{{ _('Filesystem') }}</th> + <th>{{ _('Size') }} (MiB)</th> + {% if show_part_images is defined %} + <th>{{ _('Image') }}</th> + {% endif %} + <th colspan="2"></th> + </tr> + </thead> + + <tbody data-target="partitons-fieldset" id="partitionsTable" class="text-center"> + {% for partition in disk_form.partitions %} + <tr data-toggle="fieldset-entry"> + {{ partition.hidden_tag() }} + <td>{{ partition.partition.data }}</td> + <td> + {% if readonly_disk_inspector is defined %} + {{ partition.part_type(class_="form-control", readonly="readonly") }} + {% else %} + {{ partition.part_type(class_="form-control") }} + {% endif %} + </td> + <td> + {% if readonly_disk_inspector is defined %} + {{ partition.fs(class_="form-control", readonly="readonly") }} + {% else %} + {{ partition.fs(class_="form-control") }} + {% endif %} + </td> + <td> + {% if readonly_disk_inspector is defined %} + {{ partition.size(class_="form-control", oninput="handleEdit(this)", readonly="readonly") }} + {% else %} + {{ partition.size(class_="form-control", oninput="handleEdit(this)") }} + {% endif %} + </td> + {% if show_part_images is defined %} + <td></td> + {% endif %} + <td> + <button class="btn btn-danger" type="button" onclick="RemovePartition(this, true)" + {% if readonly_disk_inspector is defined %}style="display: none;"{% endif %}> + {{ _('Remove') }} + </button> + </td> + </tr> + {% endfor %} + </tbody> + </table> +</form> + +<button class="btn btn-primary" data-target="#partitionsTable" id="addPartButton" onclick="AddPartition(this, true)" +{% if readonly_disk_inspector is defined %}style="display: none;"{% endif %}> + {{ _('Add a new partition') }} +</button> + +{% if not readonly_disk_inspector is defined %} + <button class="btn btn-success" form="setupForm"> + {{ _('Submit') }} + </button> +{% endif %} + +<div class="card text-center"> + <div class="card-header"> + {{ _('Partition graph') }} + </div> + <div class="card-body mx-auto col-7"> + <canvas id="partitionChart" class="mb-2"></canvas> + </div> +</div> + +<!-- jQuery --> +<script src="{{ url_for('static', filename='AdminLTE/plugins/jquery/jquery.min.js') }}"></script> +<!-- ChartJS --> +<script src="{{ url_for('static', filename='AdminLTE/plugins/chart.js/Chart.min.js') }}"></script> +<script> + const usedColor = 'rgb(255, 99, 132)'; + const freeColor = 'rgb(54, 162, 235)'; + + let selectedDisk = {{selected_disk}}; + let setupData = {{setup_data|tojson|safe}} + let diskSize = 0; + + let chartConfig = { + type: 'doughnut', + data: { + labels: [], + datasets: [ + { + label: 'Partitions', + data: [], + backgroundColor: [], + }, + ], + }, + options: { + responsive: true, + plugins: { + legend: { + position: 'top', + }, + title: { + display: true, + text: 'Chart.js Doughnut Chart' + }, + }, + }, + }; + + let partitionChart = new Chart( + document.getElementById('partitionChart'), + chartConfig, + ); + + function addPartitionToChart(chart, label, value, bgColor) { + chart.data.labels.push(label) + chart.data.datasets[0].data.push(value); + chart.data.datasets[0].backgroundColor.push(bgColor); + } + + function resetChart() { + partitionChart.data.labels = []; + partitionChart.data.datasets[0].data = []; + partitionChart.data.datasets[0].backgroundColor = []; + } + + function updatePartitionChart() { + resetChart(); + + let freeSpace = diskSize; + let partNum = 1; + $('#partitionsTable tr').each(function() { + let partitionSize = parseInt($(this).find('td').eq(3).find('input').val().trim()); + if (isNaN(partitionSize)) { + partitionSize = 0; + } + freeSpace -= partitionSize; + addPartitionToChart(partitionChart, 'Partition ' + partNum, partitionSize, usedColor); + partNum++; + }); + + addPartitionToChart(partitionChart, 'Free', Math.max(freeSpace, 0), freeColor); + partitionChart.update(); + } + + function handleEdit(element) { + const numericValue = parseInt(element.value); + + if (isNaN(numericValue)) { + updatePartitionChart(); + return; + } + + let freeSpace = diskSize; + $('#partitionsTable tr').each(function() { + let partitionSize = parseInt($(this).find('td').eq(3).find('input').val().trim()); + if (isNaN(partitionSize)) { + partitionSize = 0; + } + freeSpace -= partitionSize; + }); + + if (freeSpace < 0) { + element.value = numericValue + freeSpace; + } + + updatePartitionChart(); + } + + function AddPartition(evt, updateChart) { + const target = $($(evt).data("target")); + const oldrow = target.find("[data-toggle=fieldset-entry]:last"); + const row = oldrow.clone(true, true); + const elem_id = row.find(".form-control")[0].id; + const elem_num = parseInt(elem_id.replace(/(.*)-(\d{1,4})/m, '$2')) + 1; + // Increment WTForms unique identifiers + row.find('.form-control').each(function() { + const id = $(this).attr('id').replace(/(.*)-(\d{1,4})-(.*)/, `$1-${elem_num}-$3`); + $(this).attr('name', id).attr('id', id).val('').removeAttr("checked"); + }); + let part_field = row.find('td').filter(':first')[0]; + part_field.innerText = elem_num + 1; + row.show(); + oldrow.after(row); + + if (updateChart) { + updatePartitionChart(); + } + } + + function RemovePartition(evt, updateChart) { + const target = $(evt).parent().parent(); + const table = target.parent(); + + if (table[0].children.length > 1) { + target.remove(); + // Reassign rows ids + table.find('tr').each(function(index) { + function update_references() { + const id = $(this).attr('id').replace(/(.*)-(\d{1,4})-(.*)/, `$1-${index}-$3`); + $(this).attr('name', id).attr('id', id); + } + + let part_field = $(this).find('td').filter(':first')[0]; + part_field.innerText = index + 1; + $(this).find('input').filter(':first').each(update_references); + $(this).find('.form-control').each(update_references); + }); + } else { + table.find('tr').each(function(index) { + $(this).find('.form-control').each(function() { + $(this).val('').removeAttr("checked"); + }); + }); + } + if (updateChart) { + updatePartitionChart(); + } + } + + function setDiskData(diskNumber) { + selectedDisk = diskNumber; + let partitions = setupData[selectedDisk]; + diskSize = Math.floor(partitions[0].size / 1024); + + $('#diskSize').text(diskSize); + $('#diskType').val(partitions[0].code); + + const partitionsTable = $('#partitionsTable'); + let partNumber = partitionsTable.find('tr').length; + const targetPartNumber = partitions.length - 1; + + while (partNumber < targetPartNumber) { + AddPartition($('#addPartButton'), false); + partNumber++; + } + + while (partNumber > targetPartNumber) { + RemovePartition(partitionsTable.find('tr:last').find('button'), false); + partNumber--; + } + + for (let i = 1; i < partitions.length; i++) { + let p = partitions[i]; + + let row = partitionsTable.find('tr').eq(i - 1); + + row.find('td').eq(0).text(p.partition); + row.find('td').eq(1).find('select').val(p.code); + row.find('td').eq(2).find('select').val(p.filesystem); + row.find('td').eq(3).find('input').val(Math.floor(p.size / 1024)); + {% if show_part_images is defined %} + row.find('td').eq(4).text(p.image); + {% endif %} + } + + updatePartitionChart(); + } + + function handleDiskChange(selectElement) { + setDiskData(selectElement.value); + } + + $(document).ready(function() { + setDiskData(selectedDisk); + }); + +</script> + +{% endif %} |