Добавил информацию о типе объекта. Просто фиксы
This commit is contained in:
@@ -42,7 +42,7 @@
|
||||
<!-- Search bar -->
|
||||
<div style="min-width: 200px; flex-grow: 1; max-width: 400px;">
|
||||
<div class="input-group">
|
||||
<input type="text" id="toolbar-search" class="form-control" placeholder="Поиск по ID..."
|
||||
<input type="text" id="toolbar-search" class="form-control" placeholder="Поиск по ID или имени..."
|
||||
value="{{ search_query|default:'' }}">
|
||||
<button type="button" class="btn btn-outline-primary"
|
||||
onclick="performSearch()">Найти</button>
|
||||
@@ -67,6 +67,12 @@
|
||||
|
||||
<!-- Action buttons -->
|
||||
<div class="d-flex gap-2">
|
||||
<a href="{% url 'mainapp:load_excel_data' %}" class="btn btn-primary btn-sm" title="Загрузка данных из Excel">
|
||||
<i class="bi bi-file-earmark-excel"></i> Excel
|
||||
</a>
|
||||
<a href="{% url 'mainapp:load_csv_data' %}" class="btn btn-success btn-sm" title="Загрузка данных из CSV">
|
||||
<i class="bi bi-file-earmark-text"></i> CSV
|
||||
</a>
|
||||
{% if user.customuser.role == 'admin' or user.customuser.role == 'moderator' %}
|
||||
<button type="button" class="btn btn-danger btn-sm" title="Удалить"
|
||||
onclick="deleteSelectedSources()">
|
||||
@@ -194,7 +200,7 @@
|
||||
|
||||
<!-- LyngSat Filter -->
|
||||
<div class="mb-2">
|
||||
<label class="form-label">Тип объекта (ТВ):</label>
|
||||
<label class="form-label">ТВ или нет:</label>
|
||||
<div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="checkbox" name="has_lyngsat" id="has_lyngsat_1"
|
||||
@@ -209,6 +215,24 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ObjectInfo Filter -->
|
||||
<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('info_id', true)">Выбрать</button>
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary"
|
||||
onclick="selectAllOptions('info_id', false)">Снять</button>
|
||||
</div>
|
||||
<select name="info_id" class="form-select form-select-sm mb-2" multiple size="4">
|
||||
{% for info in object_infos %}
|
||||
<option value="{{ info.id }}" {% if info.id in selected_info %}selected{% endif %}>
|
||||
{{ info.name }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Point Count Filter -->
|
||||
<div class="mb-2">
|
||||
<label class="form-label">Количество точек:</label>
|
||||
@@ -227,6 +251,35 @@
|
||||
placeholder="До" value="{{ date_to|default:'' }}">
|
||||
</div>
|
||||
|
||||
<!-- Signal Mark Filter -->
|
||||
<div class="mb-2">
|
||||
<label class="form-label">Наличие сигнала:</label>
|
||||
<div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="checkbox" name="has_signal_mark" id="has_signal_mark_1"
|
||||
value="1" {% if has_signal_mark == '1' %}checked{% endif %}>
|
||||
<label class="form-check-label" for="has_signal_mark_1">Есть</label>
|
||||
</div>
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="checkbox" name="has_signal_mark" id="has_signal_mark_0"
|
||||
value="0" {% if has_signal_mark == '0' %}checked{% endif %}>
|
||||
<label class="form-check-label" for="has_signal_mark_0">Нет</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Mark Date Filter -->
|
||||
<div class="mb-2">
|
||||
<label class="form-label">Дата отметки сигнала:</label>
|
||||
<input type="date" name="mark_date_from" id="mark_date_from" class="form-control form-control-sm mb-1"
|
||||
placeholder="От" value="{{ mark_date_from|default:'' }}">
|
||||
<input type="date" name="mark_date_to" id="mark_date_to" class="form-control form-control-sm"
|
||||
placeholder="До" value="{{ mark_date_to|default:'' }}">
|
||||
</div>
|
||||
|
||||
<hr class="my-3">
|
||||
<h6 class="text-muted mb-2"><i class="bi bi-sliders"></i> Фильтры по параметрам точек</h6>
|
||||
|
||||
<!-- Geo Timestamp Filter -->
|
||||
<div class="mb-2">
|
||||
<label class="form-label">Дата ГЛ:</label>
|
||||
@@ -236,6 +289,96 @@
|
||||
placeholder="До" value="{{ geo_date_to|default:'' }}">
|
||||
</div>
|
||||
|
||||
<!-- Polarization 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('polarization_id', true)">Выбрать</button>
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary"
|
||||
onclick="selectAllOptions('polarization_id', false)">Снять</button>
|
||||
</div>
|
||||
<select name="polarization_id" class="form-select form-select-sm mb-2" multiple size="4">
|
||||
{% for polarization in polarizations %}
|
||||
<option value="{{ polarization.id }}" {% if polarization.id in selected_polarizations %}selected{% endif %}>
|
||||
{{ polarization.name }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Modulation 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('modulation_id', true)">Выбрать</button>
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary"
|
||||
onclick="selectAllOptions('modulation_id', false)">Снять</button>
|
||||
</div>
|
||||
<select name="modulation_id" class="form-select form-select-sm mb-2" multiple size="4">
|
||||
{% for modulation in modulations %}
|
||||
<option value="{{ modulation.id }}" {% if modulation.id in selected_modulations %}selected{% endif %}>
|
||||
{{ modulation.name }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Frequency Filter -->
|
||||
<div class="mb-2">
|
||||
<label class="form-label">Частота, МГц:</label>
|
||||
<input type="number" step="0.001" name="freq_min" class="form-control form-control-sm mb-1"
|
||||
placeholder="От" value="{{ freq_min|default:'' }}">
|
||||
<input type="number" step="0.001" name="freq_max" class="form-control form-control-sm"
|
||||
placeholder="До" value="{{ freq_max|default:'' }}">
|
||||
</div>
|
||||
|
||||
<!-- Frequency Range (Bandwidth) Filter -->
|
||||
<div class="mb-2">
|
||||
<label class="form-label">Полоса, МГц:</label>
|
||||
<input type="number" step="0.001" name="freq_range_min" class="form-control form-control-sm mb-1"
|
||||
placeholder="От" value="{{ freq_range_min|default:'' }}">
|
||||
<input type="number" step="0.001" name="freq_range_max" class="form-control form-control-sm"
|
||||
placeholder="До" value="{{ freq_range_max|default:'' }}">
|
||||
</div>
|
||||
|
||||
<!-- Symbol Rate Filter -->
|
||||
<div class="mb-2">
|
||||
<label class="form-label">Символьная скорость, БОД:</label>
|
||||
<input type="number" step="0.001" name="bod_velocity_min" class="form-control form-control-sm mb-1"
|
||||
placeholder="От" value="{{ bod_velocity_min|default:'' }}">
|
||||
<input type="number" step="0.001" name="bod_velocity_max" class="form-control form-control-sm"
|
||||
placeholder="До" value="{{ bod_velocity_max|default:'' }}">
|
||||
</div>
|
||||
|
||||
<!-- SNR Filter -->
|
||||
<div class="mb-2">
|
||||
<label class="form-label">ОСШ, дБ:</label>
|
||||
<input type="number" step="0.1" name="snr_min" class="form-control form-control-sm mb-1"
|
||||
placeholder="От" value="{{ snr_min|default:'' }}">
|
||||
<input type="number" step="0.1" name="snr_max" class="form-control form-control-sm"
|
||||
placeholder="До" value="{{ snr_max|default:'' }}">
|
||||
</div>
|
||||
|
||||
<!-- Mirrors 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('mirror_id', true)">Выбрать</button>
|
||||
<button type="button" class="btn btn-sm btn-outline-secondary"
|
||||
onclick="selectAllOptions('mirror_id', false)">Снять</button>
|
||||
</div>
|
||||
<select name="mirror_id" class="form-select form-select-sm mb-2" multiple size="4">
|
||||
{% for mirror in mirrors %}
|
||||
<option value="{{ mirror.id }}" {% if mirror.id in selected_mirrors %}selected{% endif %}>
|
||||
{{ mirror.name }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Apply Filters and Reset Buttons -->
|
||||
<div class="d-grid gap-2 mt-2">
|
||||
<button type="submit" class="btn btn-primary btn-sm">Применить</button>
|
||||
@@ -267,15 +410,15 @@
|
||||
{% endif %}
|
||||
</a>
|
||||
</th>
|
||||
<th scope="col" style="min-width: 150px;">Имя</th>
|
||||
<th scope="col" style="min-width: 120px;">Спутник</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" style="min-width: 180px;">Наличие сигнала</th>
|
||||
{% if has_any_lyngsat %}
|
||||
<th scope="col" class="text-center" style="min-width: 80px;">Тип объекта</th>
|
||||
{% endif %}
|
||||
<th scope="col" class="text-center" style="min-width: 80px;">ТВ или нет</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">
|
||||
Кол-во точек
|
||||
@@ -317,7 +460,18 @@
|
||||
value="{{ source.id }}">
|
||||
</td>
|
||||
<td class="text-center">{{ source.id }}</td>
|
||||
<td>{{ source.satellite }}</td>
|
||||
<td>{{ source.name }}</td>
|
||||
<td>
|
||||
{% if source.satellite_id %}
|
||||
<a href="#" class="text-decoration-underline"
|
||||
onclick="showSatelliteModal({{ source.satellite_id }}); return false;">
|
||||
{{ source.satellite }}
|
||||
</a>
|
||||
{% else %}
|
||||
{{ source.satellite }}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{{ source.info }}</td>
|
||||
<td>{{ source.coords_average }}</td>
|
||||
<td>{{ source.coords_kupsat }}</td>
|
||||
<td>{{ source.coords_valid }}</td>
|
||||
@@ -345,7 +499,6 @@
|
||||
<span class="text-muted">-</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
{% if has_any_lyngsat %}
|
||||
<td class="text-center">
|
||||
{% if source.has_lyngsat %}
|
||||
<a href="#" class="text-primary text-decoration-none"
|
||||
@@ -356,7 +509,6 @@
|
||||
-
|
||||
{% endif %}
|
||||
</td>
|
||||
{% endif %}
|
||||
<td class="text-center">{{ source.objitem_count }}</td>
|
||||
<td>{{ source.created_at|date:"d.m.Y H:i" }}</td>
|
||||
<td>{{ source.updated_at|date:"d.m.Y H:i" }}</td>
|
||||
@@ -411,7 +563,7 @@
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr>
|
||||
<td colspan="12" class="text-center text-muted">Нет данных для отображения</td>
|
||||
<td colspan="14" class="text-center text-muted">Нет данных для отображения</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
@@ -775,6 +927,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
setupRadioLikeCheckboxes('has_coords_valid');
|
||||
setupRadioLikeCheckboxes('has_coords_reference');
|
||||
setupRadioLikeCheckboxes('has_lyngsat');
|
||||
setupRadioLikeCheckboxes('has_signal_mark');
|
||||
|
||||
// Update filter counter on page load
|
||||
updateFilterCounter();
|
||||
@@ -896,10 +1049,10 @@ function showSourceDetails(sourceId) {
|
||||
// Build transponder cell
|
||||
let transponderCell = '-';
|
||||
if (objitem.has_transponder) {
|
||||
transponderCell = '<a href="#" class="text-success text-decoration-none" ' +
|
||||
transponderCell = '<a href="#" class="text-decoration-underline" ' +
|
||||
'onclick="showTransponderModal(' + objitem.transponder_id + '); return false;" ' +
|
||||
'title="Показать данные транспондера">' +
|
||||
'<i class="bi bi-broadcast"></i> ' + objitem.transponder_info +
|
||||
objitem.transponder_info +
|
||||
'</a>';
|
||||
}
|
||||
|
||||
@@ -922,12 +1075,21 @@ function showSourceDetails(sourceId) {
|
||||
'</a>';
|
||||
}
|
||||
|
||||
// Build satellite cell with link
|
||||
let satelliteCell = objitem.satellite_name;
|
||||
if (objitem.satellite_id) {
|
||||
satelliteCell = '<a href="#" class="text-decoration-underline" ' +
|
||||
'onclick="showSatelliteModal(' + objitem.satellite_id + '); return false;">' +
|
||||
objitem.satellite_name +
|
||||
'</a>';
|
||||
}
|
||||
|
||||
row.innerHTML = '<td class="text-center">' +
|
||||
'<input type="checkbox" class="form-check-input modal-item-checkbox" value="' + objitem.id + '">' +
|
||||
'</td>' +
|
||||
'<td class="text-center">' + objitem.id + '</td>' +
|
||||
'<td>' + objitem.name + '</td>' +
|
||||
'<td>' + objitem.satellite_name + '</td>' +
|
||||
'<td>' + satelliteCell + '</td>' +
|
||||
'<td>' + transponderCell + '</td>' +
|
||||
'<td>' + objitem.frequency + '</td>' +
|
||||
'<td>' + objitem.freq_range + '</td>' +
|
||||
@@ -954,8 +1116,13 @@ function showSourceDetails(sourceId) {
|
||||
// Setup modal select-all checkbox
|
||||
setupModalSelectAll();
|
||||
|
||||
// Initialize column visibility
|
||||
initModalColumnVisibility();
|
||||
// Initialize column visibility after DOM update
|
||||
// Use requestAnimationFrame to ensure DOM is rendered
|
||||
requestAnimationFrame(() => {
|
||||
setTimeout(() => {
|
||||
initModalColumnVisibility();
|
||||
}, 50);
|
||||
});
|
||||
} else {
|
||||
// Show no data message
|
||||
document.getElementById('modalNoData').style.display = 'block';
|
||||
@@ -1002,21 +1169,27 @@ function setupModalSelectAll() {
|
||||
// Function to toggle modal column visibility
|
||||
function toggleModalColumn(checkbox) {
|
||||
const columnIndex = parseInt(checkbox.getAttribute('data-column'));
|
||||
const modal = document.getElementById('sourceDetailsModal');
|
||||
const table = modal.querySelector('.table');
|
||||
|
||||
// Get the specific tbody for objitems
|
||||
const tbody = document.getElementById('objitemTableBody');
|
||||
if (!tbody) return;
|
||||
|
||||
// Get the parent table
|
||||
const table = tbody.closest('table');
|
||||
if (!table) return;
|
||||
|
||||
const cells = table.querySelectorAll('td:nth-child(' + (columnIndex + 1) + '), th:nth-child(' + (columnIndex + 1) + ')');
|
||||
|
||||
if (checkbox.checked) {
|
||||
cells.forEach(cell => {
|
||||
cell.style.display = '';
|
||||
});
|
||||
} else {
|
||||
cells.forEach(cell => {
|
||||
cell.style.display = 'none';
|
||||
});
|
||||
}
|
||||
// Get all rows and toggle specific cell in each
|
||||
const rows = table.querySelectorAll('tr');
|
||||
rows.forEach(row => {
|
||||
const cells = row.children;
|
||||
if (cells[columnIndex]) {
|
||||
if (checkbox.checked) {
|
||||
cells[columnIndex].style.removeProperty('display');
|
||||
} else {
|
||||
cells[columnIndex].style.setProperty('display', 'none', 'important');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Function to toggle all modal columns
|
||||
@@ -1032,11 +1205,31 @@ function toggleAllModalColumns(selectAllCheckbox) {
|
||||
function initModalColumnVisibility() {
|
||||
// Hide columns by default: Создано (16), Кем(созд) (17), Комментарий (18), Усреднённое (19), Стандарт (20), Sigma (22)
|
||||
const columnsToHide = [16, 17, 18, 19, 20, 22];
|
||||
|
||||
// Get the specific tbody for objitems
|
||||
const tbody = document.getElementById('objitemTableBody');
|
||||
if (!tbody) {
|
||||
console.log('objitemTableBody not found');
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the parent table
|
||||
const table = tbody.closest('table');
|
||||
if (!table) {
|
||||
console.log('Table not found');
|
||||
return;
|
||||
}
|
||||
|
||||
// Hide columns that should be hidden by default
|
||||
columnsToHide.forEach(columnIndex => {
|
||||
const checkbox = document.querySelector('.modal-column-toggle[data-column="' + columnIndex + '"]');
|
||||
if (checkbox && !checkbox.checked) {
|
||||
toggleModalColumn(checkbox);
|
||||
}
|
||||
// Get all rows in the table (including thead and tbody)
|
||||
const rows = table.querySelectorAll('tr');
|
||||
rows.forEach(row => {
|
||||
const cells = row.children;
|
||||
if (cells[columnIndex]) {
|
||||
cells[columnIndex].style.setProperty('display', 'none', 'important');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1190,4 +1383,7 @@ function showTransponderModal(transponderId) {
|
||||
<!-- Include the sigma parameter modal component -->
|
||||
{% include 'mainapp/components/_sigma_parameter_modal.html' %}
|
||||
|
||||
<!-- Include the satellite modal component -->
|
||||
{% include 'mainapp/components/_satellite_modal.html' %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user