Виджет с усреднёнными точками на карте
This commit is contained in:
@@ -67,6 +67,12 @@
|
||||
|
||||
<!-- Action buttons -->
|
||||
<div class="d-flex gap-2">
|
||||
{% if user.customuser.role == 'admin' or user.customuser.role == 'moderator' %}
|
||||
<button type="button" class="btn btn-danger btn-sm" title="Удалить"
|
||||
onclick="deleteSelectedSources()">
|
||||
<i class="bi bi-trash"></i> Удалить
|
||||
</button>
|
||||
{% endif %}
|
||||
<button type="button" class="btn btn-outline-primary btn-sm" title="Показать на карте"
|
||||
onclick="showSelectedOnMap()">
|
||||
<i class="bi bi-map"></i> Карта
|
||||
@@ -100,6 +106,24 @@
|
||||
</div>
|
||||
<div class="offcanvas-body">
|
||||
<form method="get" id="filter-form">
|
||||
<!-- Satellite Selection - Multi-select -->
|
||||
<div class="mb-2">
|
||||
<label class="form-label">Спутник:</label>
|
||||
<div class="d-flex justify-content-between mb-1">
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary"
|
||||
onclick="selectAllOptions('satellite_id', true)">Выбрать</button>
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary"
|
||||
onclick="selectAllOptions('satellite_id', false)">Снять</button>
|
||||
</div>
|
||||
<select name="satellite_id" class="form-select form-select-sm mb-2" multiple size="6">
|
||||
{% for satellite in satellites %}
|
||||
<option value="{{ satellite.id }}" {% if satellite.id in selected_satellites %}selected{% endif %}>
|
||||
{{ satellite.name }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Coordinates Average Filter -->
|
||||
<div class="mb-2">
|
||||
<label class="form-label">Усредненные координаты:</label>
|
||||
@@ -168,9 +192,9 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ObjItem Count Filter -->
|
||||
<!-- Point Count Filter -->
|
||||
<div class="mb-2">
|
||||
<label class="form-label">Количество ObjItem:</label>
|
||||
<label class="form-label">Количество точек:</label>
|
||||
<input type="number" name="objitem_count_min" class="form-control form-control-sm mb-1"
|
||||
placeholder="От" value="{{ objitem_count_min|default:'' }}">
|
||||
<input type="number" name="objitem_count_max" class="form-control form-control-sm"
|
||||
@@ -217,13 +241,14 @@
|
||||
{% endif %}
|
||||
</a>
|
||||
</th>
|
||||
<th scope="col" style="min-width: 120px;">Спутник</th>
|
||||
<th scope="col" style="min-width: 150px;">Усредненные координаты</th>
|
||||
<th scope="col" style="min-width: 150px;">Координаты Кубсата</th>
|
||||
<th scope="col" style="min-width: 150px;">Координаты оперативников</th>
|
||||
<th scope="col" style="min-width: 150px;">Координаты справочные</th>
|
||||
<th scope="col" class="text-center" style="min-width: 100px;">
|
||||
<a href="javascript:void(0)" onclick="updateSort('objitem_count')" class="text-white text-decoration-none">
|
||||
Кол-во ObjItem
|
||||
Кол-во точек
|
||||
{% if sort == 'objitem_count' %}
|
||||
<i class="bi bi-arrow-up"></i>
|
||||
{% elif sort == '-objitem_count' %}
|
||||
@@ -262,6 +287,7 @@
|
||||
value="{{ source.id }}">
|
||||
</td>
|
||||
<td class="text-center">{{ source.id }}</td>
|
||||
<td>{{ source.satellite }}</td>
|
||||
<td>{{ source.coords_average }}</td>
|
||||
<td>{{ source.coords_kupsat }}</td>
|
||||
<td>{{ source.coords_valid }}</td>
|
||||
@@ -285,6 +311,19 @@
|
||||
</button>
|
||||
{% endif %}
|
||||
|
||||
{% if source.objitem_count > 1 %}
|
||||
<a href="{% url 'mainapp:show_source_averaging_map' source.id %}"
|
||||
target="_blank"
|
||||
class="btn btn-sm btn-outline-info"
|
||||
title="Визуализация усреднения">
|
||||
<i class="bi bi-diagram-3"></i>
|
||||
</a>
|
||||
{% else %}
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary" disabled title="Недостаточно точек для усреднения">
|
||||
<i class="bi bi-diagram-3"></i>
|
||||
</button>
|
||||
{% endif %}
|
||||
|
||||
<button type="button" class="btn btn-sm btn-outline-primary"
|
||||
onclick="showSourceDetails({{ source.id }})"
|
||||
title="Показать детали">
|
||||
@@ -307,7 +346,7 @@
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr>
|
||||
<td colspan="10" class="text-center text-muted">Нет данных для отображения</td>
|
||||
<td colspan="11" class="text-center text-muted">Нет данных для отображения</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
@@ -335,7 +374,7 @@
|
||||
</div>
|
||||
<div id="modalErrorMessage" class="alert alert-danger" style="display: none;"></div>
|
||||
<div id="modalContent" style="display: none;">
|
||||
<h6>Связанные объекты (<span id="objitemCount">0</span>):</h6>
|
||||
<h6>Связанные точки (<span id="objitemCount">0</span>):</h6>
|
||||
<div class="table-responsive" style="max-height: 60vh; overflow-y: auto;">
|
||||
<table class="table table-striped table-hover table-sm">
|
||||
<thead class="table-light sticky-top">
|
||||
@@ -364,7 +403,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id="modalNoData" class="text-center text-muted py-4" style="display: none;">
|
||||
Нет связанных объектов
|
||||
Нет связанных точек
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
@@ -427,6 +466,27 @@ function showSelectedOnMap() {
|
||||
window.open(url, '_blank'); // Open in a new tab
|
||||
}
|
||||
|
||||
// Function to delete selected sources
|
||||
function deleteSelectedSources() {
|
||||
// Get all checked checkboxes
|
||||
const checkedCheckboxes = document.querySelectorAll('.item-checkbox:checked');
|
||||
|
||||
if (checkedCheckboxes.length === 0) {
|
||||
alert('Пожалуйста, выберите хотя бы один источник для удаления');
|
||||
return;
|
||||
}
|
||||
|
||||
// Extract IDs from checked checkboxes
|
||||
const selectedIds = [];
|
||||
checkedCheckboxes.forEach(checkbox => {
|
||||
selectedIds.push(checkbox.value);
|
||||
});
|
||||
|
||||
// Redirect to confirmation page
|
||||
const url = '{% url "mainapp:delete_selected_sources" %}' + '?ids=' + selectedIds.join(',');
|
||||
window.location.href = url;
|
||||
}
|
||||
|
||||
// Search functionality
|
||||
function performSearch() {
|
||||
const searchValue = document.getElementById('toolbar-search').value.trim();
|
||||
@@ -501,6 +561,16 @@ function setupRadioLikeCheckboxes(name) {
|
||||
});
|
||||
}
|
||||
|
||||
// Function to select/deselect all options in a select element
|
||||
function selectAllOptions(selectName, selectAll) {
|
||||
const selectElement = document.querySelector(`select[name="${selectName}"]`);
|
||||
if (selectElement) {
|
||||
for (let i = 0; i < selectElement.options.length; i++) {
|
||||
selectElement.options[i].selected = selectAll;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Filter counter functionality
|
||||
function updateFilterCounter() {
|
||||
const form = document.getElementById('filter-form');
|
||||
@@ -510,6 +580,19 @@ function updateFilterCounter() {
|
||||
// Count non-empty form fields
|
||||
for (const [key, value] of formData.entries()) {
|
||||
if (value && value.trim() !== '') {
|
||||
// For multi-select fields, skip counting individual selections
|
||||
if (key === 'satellite_id') {
|
||||
continue;
|
||||
}
|
||||
filterCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// Count selected options in satellite multi-select field
|
||||
const satelliteSelect = document.querySelector('select[name="satellite_id"]');
|
||||
if (satelliteSelect) {
|
||||
const selectedOptions = Array.from(satelliteSelect.selectedOptions).filter(opt => opt.selected);
|
||||
if (selectedOptions.length > 0) {
|
||||
filterCount++;
|
||||
}
|
||||
}
|
||||
@@ -569,6 +652,11 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
input.addEventListener('change', updateFilterCounter);
|
||||
});
|
||||
|
||||
const selectFields = form.querySelectorAll('select');
|
||||
selectFields.forEach(select => {
|
||||
select.addEventListener('change', updateFilterCounter);
|
||||
});
|
||||
|
||||
const checkboxFields = form.querySelectorAll('input[type="checkbox"]');
|
||||
checkboxFields.forEach(checkbox => {
|
||||
checkbox.addEventListener('change', updateFilterCounter);
|
||||
|
||||
Reference in New Issue
Block a user