diff --git a/dbapp/mainapp/forms.py b/dbapp/mainapp/forms.py index 34003fb..43015bf 100644 --- a/dbapp/mainapp/forms.py +++ b/dbapp/mainapp/forms.py @@ -40,6 +40,13 @@ class LoadExcelData(forms.Form): min_value=0, widget=forms.NumberInput(attrs={"class": "form-control"}), ) + is_automatic = forms.BooleanField( + label="Автоматическая загрузка", + required=False, + initial=False, + widget=forms.CheckboxInput(attrs={"class": "form-check-input"}), + help_text="Если отмечено, точки не будут добавляться к объектам (Source)", + ) class LoadCsvData(forms.Form): @@ -47,6 +54,13 @@ class LoadCsvData(forms.Form): label="Выберите CSV файл", widget=forms.FileInput(attrs={"class": "form-control", "accept": ".csv"}), ) + is_automatic = forms.BooleanField( + label="Автоматическая загрузка", + required=False, + initial=False, + widget=forms.CheckboxInput(attrs={"class": "form-check-input"}), + help_text="Если отмечено, точки не будут добавляться к объектам (Source)", + ) class UploadVchLoad(UploadFileForm): diff --git a/dbapp/mainapp/migrations/0013_add_is_automatic_to_objitem.py b/dbapp/mainapp/migrations/0013_add_is_automatic_to_objitem.py new file mode 100644 index 0000000..28a0087 --- /dev/null +++ b/dbapp/mainapp/migrations/0013_add_is_automatic_to_objitem.py @@ -0,0 +1,28 @@ +# Generated by Django 5.2.7 on 2025-11-24 19:11 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('mainapp', '0012_source_confirm_at_source_last_signal_at'), + ] + + operations = [ + migrations.DeleteModel( + name='Mirror', + ), + migrations.RemoveField( + model_name='sigmaparameter', + name='mark', + ), + migrations.AddField( + model_name='objitem', + name='is_automatic', + field=models.BooleanField(db_index=True, default=False, help_text='Если True, точка не добавляется к объектам (Source), а хранится отдельно', verbose_name='Автоматическая'), + ), + migrations.DeleteModel( + name='SigmaParMark', + ), + ] diff --git a/dbapp/mainapp/models.py b/dbapp/mainapp/models.py index f36dddb..0429932 100644 --- a/dbapp/mainapp/models.py +++ b/dbapp/mainapp/models.py @@ -728,6 +728,12 @@ class ObjItem(models.Model): verbose_name="Транспондер", help_text="Транспондер, с помощью которого была получена точка", ) + is_automatic = models.BooleanField( + default=False, + verbose_name="Автоматическая", + db_index=True, + help_text="Если True, точка не добавляется к объектам (Source), а хранится отдельно", + ) # Метаданные created_at = models.DateTimeField( diff --git a/dbapp/mainapp/signals.py b/dbapp/mainapp/signals.py index b41d8b6..00bf42c 100644 --- a/dbapp/mainapp/signals.py +++ b/dbapp/mainapp/signals.py @@ -1,14 +1,17 @@ -# Django imports -from django.contrib.auth.models import User -from django.db.models.signals import post_save -from django.dispatch import receiver - -# Local imports -from .models import CustomUser - - -@receiver(post_save, sender=User) -def create_or_update_user_profile(sender, instance, created, **kwargs): - if created: - CustomUser.objects.create(user=instance) - instance.customuser.save() \ No newline at end of file +# Django imports +# from django.contrib.auth.models import User +# from django.db.models.signals import post_save +# from django.dispatch import receiver + +# # Local imports +# from .models import CustomUser + + +# @receiver(post_save, sender=User) +# def create_or_update_user_profile(sender, instance, created, **kwargs): +# if created: +# CustomUser.objects.get_or_create(user=instance) +# else: +# # Only save if customuser exists (avoid error if it doesn't) +# if hasattr(instance, 'customuser'): +# instance.customuser.save() \ No newline at end of file diff --git a/dbapp/mainapp/templates/mainapp/actions.html b/dbapp/mainapp/templates/mainapp/actions.html index b59487a..9d0349f 100644 --- a/dbapp/mainapp/templates/mainapp/actions.html +++ b/dbapp/mainapp/templates/mainapp/actions.html @@ -79,26 +79,7 @@ - -
-
-
-
-
- - - - -
-

Добавление транспондеров

-
-

Добавьте список транспондеров в базу данных.

- - Добавить транспондеры - -
-
-
+
diff --git a/dbapp/mainapp/templates/mainapp/add_data_from_csv.html b/dbapp/mainapp/templates/mainapp/add_data_from_csv.html index 6503599..c684aa4 100644 --- a/dbapp/mainapp/templates/mainapp/add_data_from_csv.html +++ b/dbapp/mainapp/templates/mainapp/add_data_from_csv.html @@ -19,6 +19,19 @@ {% include 'mainapp/components/_form_field.html' with field=form.file %} + +
+
+ {{ form.is_automatic }} + + {% if form.is_automatic.help_text %} +
{{ form.is_automatic.help_text }}
+ {% endif %} +
+
+
Назад diff --git a/dbapp/mainapp/templates/mainapp/add_data_from_excel.html b/dbapp/mainapp/templates/mainapp/add_data_from_excel.html index d87d8cf..86923cd 100644 --- a/dbapp/mainapp/templates/mainapp/add_data_from_excel.html +++ b/dbapp/mainapp/templates/mainapp/add_data_from_excel.html @@ -21,6 +21,19 @@ {% include 'mainapp/components/_form_field.html' with field=form.sat_choice %} {% include 'mainapp/components/_form_field.html' with field=form.number_input %} + +
+
+ {{ form.is_automatic }} + + {% if form.is_automatic.help_text %} +
{{ form.is_automatic.help_text }}
+ {% endif %} +
+
+
Назад diff --git a/dbapp/mainapp/templates/mainapp/objitem_form.html b/dbapp/mainapp/templates/mainapp/objitem_form.html index 0d6f609..704ddcf 100644 --- a/dbapp/mainapp/templates/mainapp/objitem_form.html +++ b/dbapp/mainapp/templates/mainapp/objitem_form.html @@ -3,7 +3,7 @@ {% load static leaflet_tags %} {% load l10n %} -{% block title %}{% if object %}Редактировать объект: {{ object.name }}{% else %}Создать объект{% endif %}{% endblock %} +{% block title %}{% if object %}Редактировать объект: {{ object.name }}{% else %}Создать новый объект{% endif %}{% endblock %} {% block extra_css %} @@ -144,7 +144,7 @@
-

{% if object %}Редактировать объект: {{ object.name }}{% else %}Создать объект{% endif %}

+

{% if object %}Редактировать объект: {{ object.name }}{% else %}Создать новый объект{% endif %}

{% if user.customuser.role == 'admin' or user.customuser.role == 'moderator' %} @@ -248,6 +248,7 @@
+ {% if object %}
@@ -339,6 +340,7 @@
{% endif %}
+ {% endif %}
diff --git a/dbapp/mainapp/templates/mainapp/objitem_list.html b/dbapp/mainapp/templates/mainapp/objitem_list.html index 1f5c280..e90456b 100644 --- a/dbapp/mainapp/templates/mainapp/objitem_list.html +++ b/dbapp/mainapp/templates/mainapp/objitem_list.html @@ -40,13 +40,10 @@
- {% comment %} - {% endcomment %} {% if user.customuser.role == 'admin' or user.customuser.role == 'moderator' %} + + Создать +
+ +
+ +
+
+ + +
+
+ + +
+
+
+
@@ -309,6 +323,7 @@ {% include 'mainapp/components/_table_header.html' with label="Тип точки" field="" sortable=False %} {% include 'mainapp/components/_table_header.html' with label="Sigma" field="" sortable=False %} {% include 'mainapp/components/_table_header.html' with label="Зеркала" field="" sortable=False %} + {% include 'mainapp/components/_table_header.html' with label="Автоматическая?" field="is_automatic" sort=sort %} @@ -378,10 +393,11 @@ {% endif %} {{ item.mirrors }} + {{ item.is_automatic }} {% empty %} - + {% if selected_satellite_id %} Нет данных для выбранных фильтров {% else %} @@ -612,6 +628,7 @@ setupRadioLikeCheckboxes('has_valid'); setupRadioLikeCheckboxes('has_source_type'); setupRadioLikeCheckboxes('has_sigma'); + setupRadioLikeCheckboxes('is_automatic'); // Date range quick selection functions window.setDateRange = function (period) { diff --git a/dbapp/mainapp/templates/mainapp/satellite_form.html b/dbapp/mainapp/templates/mainapp/satellite_form.html index 28a38d8..c305781 100644 --- a/dbapp/mainapp/templates/mainapp/satellite_form.html +++ b/dbapp/mainapp/templates/mainapp/satellite_form.html @@ -212,7 +212,7 @@

Частотный план

-

Визуализация транспондеров спутника по частотам. Downlink (синий), Uplink (оранжевый). Используйте колесико мыши для масштабирования, наведите курсор на полосу для подробной информации.

+

Визуализация транспондеров спутника по частотам. Downlink (синий), Uplink (оранжевый). Используйте колесико мыши для масштабирования, наведите курсор на полосу для подробной информации и связи с парным каналом.

@@ -272,19 +272,6 @@ // Transponder data from Django const transpondersData = {{ transponders|safe }}; -// Color mapping for polarizations -const polarizationColors = { - 'H': '#0d6efd', - 'V': '#198754', - 'L': '#dc3545', - 'R': '#ffc107', - 'default': '#6c757d' -}; - -function getColor(polarization) { - return polarizationColors[polarization] || polarizationColors['default']; -} - // Chart state let canvas, ctx, container; let zoomLevel = 1; @@ -505,19 +492,21 @@ function renderChart() { if (barWidth < 1) return; + const isHovered = hoveredTransponder && hoveredTransponder.transponder.name === t.name; + // Draw downlink bar ctx.fillStyle = downlinkColor; ctx.fillRect(x1, downlinkBarY, barWidth, downlinkBarHeight); - // Draw border - ctx.strokeStyle = '#fff'; - ctx.lineWidth = 1; + // Draw border (thicker if hovered) + ctx.strokeStyle = isHovered ? '#000' : '#fff'; + ctx.lineWidth = isHovered ? 3 : 1; ctx.strokeRect(x1, downlinkBarY, barWidth, downlinkBarHeight); // Draw name if there's space if (barWidth > 40) { - ctx.fillStyle = (pol === 'R') ? '#000' : '#fff'; - ctx.font = '9px sans-serif'; + ctx.fillStyle = '#fff'; + ctx.font = isHovered ? 'bold 10px sans-serif' : '9px sans-serif'; ctx.textAlign = 'center'; ctx.fillText(t.name, x1 + barWidth / 2, downlinkBarY + downlinkBarHeight / 2 + 3); } @@ -529,7 +518,8 @@ function renderChart() { width: barWidth, height: downlinkBarHeight, transponder: t, - type: 'downlink' + type: 'downlink', + centerX: x1 + barWidth / 2 }); }); @@ -553,19 +543,21 @@ function renderChart() { // Skip if too small if (barWidth < 1) return; + const isHovered = hoveredTransponder && hoveredTransponder.transponder.name === t.name; + // Draw uplink bar ctx.fillStyle = uplinkColor; ctx.fillRect(x1, uplinkBarY, barWidth, uplinkBarHeight); - // Draw border - ctx.strokeStyle = '#fff'; - ctx.lineWidth = 1; + // Draw border (thicker if hovered) + ctx.strokeStyle = isHovered ? '#000' : '#fff'; + ctx.lineWidth = isHovered ? 3 : 1; ctx.strokeRect(x1, uplinkBarY, barWidth, uplinkBarHeight); // Draw name if there's space if (barWidth > 40) { ctx.fillStyle = '#fff'; - ctx.font = '9px sans-serif'; + ctx.font = isHovered ? 'bold 10px sans-serif' : '9px sans-serif'; ctx.textAlign = 'center'; ctx.fillText(t.name, x1 + barWidth / 2, uplinkBarY + uplinkBarHeight / 2 + 3); } @@ -577,7 +569,8 @@ function renderChart() { width: barWidth, height: uplinkBarHeight, transponder: t, - type: 'uplink' + type: 'uplink', + centerX: x1 + barWidth / 2 }); }); @@ -593,12 +586,43 @@ function renderChart() { } }); - // Draw hover tooltip + // Draw connection line between downlink and uplink when hovering if (hoveredTransponder) { + drawConnectionLine(hoveredTransponder); drawTooltip(hoveredTransponder); } } +function drawConnectionLine(rectInfo) { + const t = rectInfo.transponder; + if (!t.uplink) return; // No uplink to connect + + // Find both downlink and uplink rects for this transponder + const downlinkRect = transponderRects.find(r => r.transponder.name === t.name && r.type === 'downlink'); + const uplinkRect = transponderRects.find(r => r.transponder.name === t.name && r.type === 'uplink'); + + if (!downlinkRect || !uplinkRect) return; + + // Draw connecting line + const x1 = downlinkRect.centerX; + const y1 = downlinkRect.y + downlinkRect.height; + const x2 = uplinkRect.centerX; + const y2 = uplinkRect.y; + + ctx.save(); + ctx.strokeStyle = '#ffc107'; + ctx.lineWidth = 2; + ctx.setLineDash([5, 3]); + ctx.globalAlpha = 0.8; + + ctx.beginPath(); + ctx.moveTo(x1, y1); + ctx.lineTo(x2, y2); + ctx.stroke(); + + ctx.restore(); +} + function drawTooltip(rectInfo) { const t = rectInfo.transponder; const isUplink = rectInfo.type === 'uplink'; @@ -639,14 +663,16 @@ function drawTooltip(rectInfo) { const mouseX = rectInfo._mouseX || canvas.width / 2; const mouseY = rectInfo._mouseY || canvas.height / 2; let tooltipX = mouseX + 15; - let tooltipY = mouseY + 15; + let tooltipY = mouseY - tooltipHeight - 15; // Always show above cursor - // Keep tooltip in bounds + // Keep tooltip in bounds horizontally if (tooltipX + tooltipWidth > canvas.width) { tooltipX = mouseX - tooltipWidth - 15; } - if (tooltipY + tooltipHeight > canvas.height) { - tooltipY = mouseY - tooltipHeight - 15; + + // If tooltip goes above canvas, show below cursor instead + if (tooltipY < 0) { + tooltipY = mouseY + 15; } // Draw tooltip background diff --git a/dbapp/mainapp/templates/mainapp/source_form.html b/dbapp/mainapp/templates/mainapp/source_form.html index c459fcd..a75045e 100644 --- a/dbapp/mainapp/templates/mainapp/source_form.html +++ b/dbapp/mainapp/templates/mainapp/source_form.html @@ -129,13 +129,15 @@
-

Редактировать объект #{{ object.id }}

+

{% if object %}Редактировать объект #{{ object.id }}{% else %}Создать новый источник{% endif %}

{% if user.customuser.role == 'admin' or user.customuser.role == 'moderator' %} + {% if object %} Удалить {% endif %} + {% endif %} Назад
@@ -331,6 +333,7 @@
+ {% if object %}
@@ -416,6 +419,7 @@

Нет привязанных объектов

{% endif %}
+ {% endif %}
{% endblock %} diff --git a/dbapp/mainapp/templates/mainapp/source_list.html b/dbapp/mainapp/templates/mainapp/source_list.html index 3cb2fe7..f63cf53 100644 --- a/dbapp/mainapp/templates/mainapp/source_list.html +++ b/dbapp/mainapp/templates/mainapp/source_list.html @@ -74,6 +74,11 @@
+ {% if user.customuser.role == 'admin' or user.customuser.role == 'moderator' %} + + Создать + + {% endif %} Excel diff --git a/dbapp/mainapp/templates/mainapp/transponder_list.html b/dbapp/mainapp/templates/mainapp/transponder_list.html index 1e81480..18cfe60 100644 --- a/dbapp/mainapp/templates/mainapp/transponder_list.html +++ b/dbapp/mainapp/templates/mainapp/transponder_list.html @@ -61,6 +61,9 @@ Создать + + Загрузить XML +