diff --git a/.vscode/launch.json b/.vscode/launch.json index 6915fe51..478a2fdd 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -19,7 +19,7 @@ "config.settings.local" ], "django": true, - "justMyCode": true + "justMyCode": false }, { "name": "shell_plus", @@ -52,9 +52,10 @@ //"args": ["--notes", "-v", "1"], //"args": ["--mbinfo", "-v", "2", "--skipuntil", "2021/20210326m1"], //"args": ["--mbinfo", "-v", "1", "--limit", "1", "--skipuntil", "2019/20190628d1/lidar"], - // The next two lines for nice OctopusGarden compilation and spreadsheets testing + // The next two lines for nice OctopusGarden compilation and spreadsheets testing, interrupt first one during link_compilation_to_missions() //"args": [ "-v", "1", "--skipuntil_regex", "--regex", "2022/20220206m2/ZTopo.grd$", "--limit", "3", "--clobber" ], //"args": ["--compilation", "-v", "1", "--filter", "2022/OctopusGarden/Figures/", "--no_compilation_thumbnails", "--log_file", "compilation.txt"], + "args": ["--spreadsheets", "-v", "1"], //"args": [ "-v", "1", "--skipuntil_regex", "--regex", "2023/20230402m1/ZTopo.grd$", "--limit", "1" ], //"args": [ "--fnv", "-v", "1", "--skipuntil", "2019/20190927d1/lidar", "--limit", "1" ], //"args": ["--fnv", "-v", "1", "--limit", "2", "--skipuntil", "MappingAUVOps2011/20110718m1"], @@ -81,7 +82,7 @@ //"args": ["--compilation", "-v", "1", "--skipuntil", "2022/AxialSeamount/FiguresCaress", "--limit", "10", "--log_file", "compilation.txt"], //"args": ["--compilation", "-v", "1"], //"args": ["--spreadsheets", "-v", "1"], - "args": ["-v", "1", "--last_n_days", "0.5"], + //"args": ["-v", "1", "--last_n_days", "0.5"], //"args": ["-v", "1", "--spreadsheets", "--last_n_days", "0.5"], //"args": ["-v", "1", "--compilation", "--last_n_days", "30"], "justMyCode": false diff --git a/smdb/config/settings/base.py b/smdb/config/settings/base.py index 77fb190e..61b91e19 100644 --- a/smdb/config/settings/base.py +++ b/smdb/config/settings/base.py @@ -73,6 +73,7 @@ ] THIRD_PARTY_APPS = [ "crispy_forms", + "crispy_bootstrap4", "allauth", "allauth.account", "allauth.socialaccount", diff --git a/smdb/requirements/base.txt b/smdb/requirements/base.txt index 79668e34..cf4955b3 100644 --- a/smdb/requirements/base.txt +++ b/smdb/requirements/base.txt @@ -15,7 +15,8 @@ django-bleach==3.0.1 # https://pypi.org/project/django-bleach/ django-environ==0.9.0 # https://github.com/joke2k/django-environ django-model-utils==4.3.1 # https://github.com/jazzband/django-model-utils django-allauth==0.51.0 # https://github.com/pennersr/django-allauth -django-crispy-forms==1.14.0 # https://github.com/django-crispy-forms/django-crispy-forms +django-crispy-forms==2.1 # https://github.com/django-crispy-forms/django-crispy-forms +crispy-bootstrap4==2024.1 # https://pypi.org/project/crispy-bootstrap4/ django-compressor==4.4 # https://github.com/django-compressor/django-compressor django-redis==5.2.0 # https://github.com/jazzband/django-redis # Django REST Framework @@ -43,6 +44,6 @@ pytest-drf==1.1.3 # https://pypi.org/project/pytest-drf/ snapshottest==0.6.0 # https://docs.graphene-python.org/en/latest/testing/ uritemplate==4.1.1 # For python manage.py generateschema django-tables2==2.4.1 # https://github.com/jieter/django-tables2 -django-filter==22.1 # https://youtu.be/G-Rct7Na0UQ +django-filter==24.2 # https://youtu.be/G-Rct7Na0UQ tzdata==2023.4 # https://stackoverflow.com/a/71064180 openpyxl==3.1.2 # https://openpyxl.readthedocs.io/en/stable/ diff --git a/smdb/smdb/filters.py b/smdb/smdb/filters.py index 1f9b7d9e..38ba3137 100644 --- a/smdb/smdb/filters.py +++ b/smdb/smdb/filters.py @@ -1,17 +1,40 @@ from django import forms -from django_filters import FilterSet, CharFilter, BooleanFilter, ChoiceFilter +from django_filters import ( + FilterSet, + CharFilter, + BooleanFilter, + ChoiceFilter, + ModelChoiceFilter, +) from smdb.models import Mission, Expedition, Compilation +from django.forms.widgets import TextInput + class MissionFilter(FilterSet): - name = CharFilter(field_name="name", lookup_expr="icontains") + name = CharFilter( + field_name="name", + lookup_expr="icontains", + label="", + widget=TextInput(attrs={"placeholder": "Name contains..."}), + ) expedition__name = CharFilter( - field_name="expedition__name", lookup_expr="icontains" + field_name="expedition__name", + lookup_expr="icontains", + label="", + widget=TextInput(attrs={"placeholder": "Expedition name contains..."}), + ) + status = ChoiceFilter( + field_name="status", + choices=Mission.STATUS_CHOICES, + label="", + empty_label="--- status ---", + widget=forms.Select(attrs={"class": "form-control"}), ) class Meta: model = Mission - fields = ["name", "expedition__name"] + fields = ["name", "expedition__name", "status"] class ExpeditionFilter(FilterSet): diff --git a/smdb/smdb/forms.py b/smdb/smdb/forms.py new file mode 100644 index 00000000..b85b14d0 --- /dev/null +++ b/smdb/smdb/forms.py @@ -0,0 +1,14 @@ +from crispy_forms.helper import FormHelper +from crispy_forms.layout import Layout, Submit, Row, Column + + +class MissionFilterFormHelper(FormHelper): + form_method = "GET" + layout = Layout( + Row( + Column("name", css_class="form-group col-md-2 mb-0"), + Column("expedition__name", css_class="form-group col-md-2 mb-0"), + Column("status", css_class="form-group col-md-2 mb-0"), + Column(Submit("submit", "Filter", css_class="col-md-2 mb-0 btn-primary")), + ), + ) diff --git a/smdb/smdb/migrations/0052_alter_mission_status.py b/smdb/smdb/migrations/0052_alter_mission_status.py new file mode 100644 index 00000000..473bc401 --- /dev/null +++ b/smdb/smdb/migrations/0052_alter_mission_status.py @@ -0,0 +1,30 @@ +# Generated by Django 4.2.9 on 2024-05-16 21:18 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("smdb", "0051_alter_mission_start_depth_alter_mission_track_length"), + ] + + operations = [ + migrations.AlterField( + model_name="mission", + name="status", + field=models.CharField( + blank=True, + choices=[ + ("PS", "production_survey"), + ("FS", "failed_survey"), + ("TS", "test_survey"), + ("RS", "repeat_survey"), + ("DNU", "do_not_use_survey"), + ("UWC", "use_with_caution"), + ], + max_length=128, + null=True, + ), + ), + ] diff --git a/smdb/smdb/models.py b/smdb/smdb/models.py index 4c6166a0..e39ab8a6 100644 --- a/smdb/smdb/models.py +++ b/smdb/smdb/models.py @@ -152,6 +152,20 @@ def get_absolute_url(self): class Mission(models.Model): + # PS: if all went well and data should be used in gridding + # FS: if it was a failure; any data should not be used in gridding + # TS: if it was a test survey; data should not be used in gridding + # RS: if all went well and this repeats other surveys for gridding purposes + # DNU: if data should not be used in gridding for other reasons + # UWC: if data can be used in gridding but at lower priority + STATUS_CHOICES = ( + ("PS", "production_survey"), + ("FS", "failed_survey"), + ("TS", "test_survey"), + ("RS", "repeat_survey"), + ("DNU", "do_not_use_survey"), + ("UWC", "use_with_caution"), + ) uuid = models.UUIDField(db_index=True, default=uuid_lib.uuid4, editable=False) name = models.CharField(max_length=256, db_index=True) slug = models.SlugField(max_length=256) @@ -185,7 +199,9 @@ class Mission(models.Model): ) auv = models.BooleanField(blank=True, null=True) lass = models.BooleanField(blank=True, null=True) - status = models.CharField(max_length=128, blank=True, null=True) + status = models.CharField( + max_length=128, blank=True, null=True, choices=STATUS_CHOICES + ) mgds_compilation = models.CharField(max_length=128, blank=True, null=True) quality_comment = models.TextField(blank=True, null=True) repeat_survey = models.BooleanField(blank=True, null=True) diff --git a/smdb/smdb/static/css/project.css b/smdb/smdb/static/css/project.css index 64632076..93bf89e0 100644 --- a/smdb/smdb/static/css/project.css +++ b/smdb/smdb/static/css/project.css @@ -245,18 +245,6 @@ div.width_fixed { /* width: fit-content; */ } -#searchBar, -.form-control { - margin-left: 5px; - margin-top: 5px; - margin-bottom: 5px; - margin-right: 5px; - height: 30px; - padding-bottom: 3px; - text-align: left; - width: 200px; - /* padding-left: 15px; */ -} #searchbtn { font-size: 14px !important; @@ -274,7 +262,7 @@ div.width_fixed { ::placeholder { overflow: visible; font-size: small; - text-align: center; + text-align: left; } .form-control:focus, diff --git a/smdb/smdb/templates/base.html b/smdb/smdb/templates/base.html index 2508374f..e7e2bfbd 100644 --- a/smdb/smdb/templates/base.html +++ b/smdb/smdb/templates/base.html @@ -21,9 +21,10 @@ {% block css %} - {# Latest compiled and minified Bootstrap CSS #} - + {# Other Django packages depend on Bootstrap 4 #} + + {# Add leaflet CSS #} @@ -49,8 +50,8 @@ integrity="sha384-7+zCNj/IqJ95wo16oMtfsKbZ9ccEh31eOz1HGyDuCQ6wgnyJNSYdrPa03rtR1zdB" crossorigin="anonymous"> - {# Your stuff: Third-party javascript libraries go here #} diff --git a/smdb/smdb/templates/smdb/mission_filter.html b/smdb/smdb/templates/smdb/mission_filter.html index 6304000b..c6fa4e8e 100644 --- a/smdb/smdb/templates/smdb/mission_filter.html +++ b/smdb/smdb/templates/smdb/mission_filter.html @@ -1,6 +1,7 @@ {% extends "base.html" %} {% load django_tables2 %} {% load static %} +{% load crispy_forms_tags %} {% block css %} {{ block.super }} @@ -29,10 +30,7 @@ {% block content %}