Skip to content

Commit

Permalink
Merge pull request #615 from dbca-wa/v2.1.0prod
Browse files Browse the repository at this point in the history
V2.1.0prod
  • Loading branch information
RickWangPerth authored Oct 24, 2024
2 parents abc6b48 + fb01ac5 commit 2c0014d
Show file tree
Hide file tree
Showing 25 changed files with 991 additions and 339 deletions.
3 changes: 2 additions & 1 deletion kustomize/overlays/prod/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ patches:
- path: service_patch.yaml
images:
- name: ghcr.io/dbca-wa/wastd
newTag: 2.0.8
newTag: 2.1.0

9 changes: 9 additions & 0 deletions marine_mammal_incidents/decorators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from django.contrib.auth.decorators import user_passes_test
from django.core.exceptions import PermissionDenied

def superuser_or_data_curator_required(view_func):
def check_perms(user):
if user.is_superuser or user.groups.filter(name='data curator').exists():
return True
raise PermissionDenied
return user_passes_test(check_perms)(view_func)
79 changes: 74 additions & 5 deletions marine_mammal_incidents/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,70 @@
from mapwidgets.widgets import MapboxPointFieldWidget

class IncidentForm(forms.ModelForm):
comments = forms.CharField(
widget=forms.Textarea(attrs={'cols': '100', 'rows': '10'}),
required=False
)

class Meta:
model = Incident
fields = '__all__'
fields = [
'incident_date',
'incident_time',
'species',
'species_confirmed_genetically',
'location_name',
'geo_location',
'number_of_animals',
'mass_incident',
'incident_type',
'sex',
'age_class',
'length',
'weight',
'weight_is_estimated',
'carcass_location_fate',
'entanglement_gear',
'DBCA_staff_attended',
'condition_when_found',
'outcome',
'cause_of_death',
'photos_taken',
'samples_taken',
'post_mortem',
'comments'
]
widgets = {
'geo_location': MapboxPointFieldWidget(),
'comments': forms.Textarea(attrs={'cols': '100', 'rows': '10'}),
}

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

required_fields = [
'incident_date', 'species', 'location_name', 'number_of_animals',
'incident_type', 'sex', 'age_class', 'condition_when_found', 'outcome'
]

for field in required_fields:
self.fields[field].required = True

# class UploadedFileForm(forms.ModelForm):
# class Meta:
# model = Uploaded_file
# fields = ['title', 'file']
# labels = {
# 'title': 'Attachment name',
# 'file': 'File'
# }

# def clean(self):
# cleaned_data = super().clean()
# title = cleaned_data.get('title')
# file = cleaned_data.get('file')

# if file and not title:
# raise forms.ValidationError("The attachment name is required.")

# return cleaned_data


class UploadedFileForm(forms.ModelForm):
class Meta:
Expand All @@ -23,3 +76,19 @@ class Meta:
'title': 'Attachment name',
'file': 'File'
}

def clean(self):
cleaned_data = super().clean()
title = cleaned_data.get('title')
file = cleaned_data.get('file')

if file and not title:
raise forms.ValidationError("The attachment name is required when a file is uploaded.")

return cleaned_data

def save(self, commit=True):
instance = super().save(commit=False)
if commit:
instance.save()
return instance
8 changes: 4 additions & 4 deletions marine_mammal_incidents/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class Incident(models.Model):
]
entanglement_gear = models.CharField(max_length=50, blank=True, choices=ENTANGLEMENT_GEAR_CHOICES)

DBCA_staff_attended = models.BooleanField()
DBCA_staff_attended = models.BooleanField(default=False)

CONDITION_FOUND_CHOICES = [
('Stage 1 = alive','Stage 1 = alive'),
Expand All @@ -107,11 +107,11 @@ class Incident(models.Model):
outcome = models.CharField(max_length=30, choices=OUTCOME_CHOICES)

cause_of_death = models.CharField(max_length=100, blank=True)
photos_taken = models.BooleanField()
photos_taken = models.BooleanField(default=False)

samples_taken = models.BooleanField()
samples_taken = models.BooleanField(default=False)

post_mortem = models.BooleanField()
post_mortem = models.BooleanField(default=False)
comments = models.TextField(blank=True)


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
{% extends "base_wastd.html" %}
{% load static bootstrap4 %}

{% block extra_style %}
{{ block.super }}
{{ form.media.css }}
<link rel="stylesheet" type="text/css" href="{% static 'css/loading_spinner.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'css/loading_overlay.css' %}">
<style>
.select2 {
width: 100% !important;
}
.step-container {
border: 1px solid #ddd;
border-radius: 5px;
padding: 15px;
margin-bottom: 20px;
}
.step-header {
background-color: #f8f9fa;
padding: 10px;
margin: -15px -15px 15px -15px;
border-bottom: 1px solid #ddd;
font-weight: bold;
}
.btn-block {
display: block;
width: 100%;
}
</style>
{% endblock %}

{% block breadcrumbs %}
<nav aria-label="breadcrumb" class="d-none d-md-block">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{% url 'home' %}">Home</a></li>
<li class="breadcrumb-item"><a href="{% url 'marine_mammal_incidents:incident_list' %}">Incident List</a></li>
<li class="breadcrumb-item active">Export Incidents</li>
</ol>
</nav>
{% endblock %}

{% block page_content_inner %}
<div class="container">
<h2>Export Marine Mammal Incidents</h2>

<form id="exportForm" method="get" action="{% url 'marine_mammal_incidents:export_data' %}" target="_blank">
{% csrf_token %}

<!-- Step 1: Select Date Range -->
<div class="step-container">
<div class="step-header">Step 1: Select Date Range</div>
<div class="form-group">
<label for="incident_date_from">Start Date</label>
<input type="date" id="incident_date_from" name="incident_date_from" class="form-control">
</div>
<div class="form-group">
<label for="incident_date_to">End Date</label>
<input type="date" id="incident_date_to" name="incident_date_to" class="form-control">
</div>
</div>

<!-- Step 2: Select Filters -->
<div class="step-container">
<div class="step-header">Step 2: Select Filter</div>
<div class="form-group">
<label for="species">Species</label>
<select id="species" name="species" class="form-control select2">
<option value="">All Species</option>
{% for species in species_list %}
<option value="{{ species.id }}">{{ species }}</option>
{% endfor %}
</select>
</div>
<div class="form-group">
<label for="location_name">Location<small class="text-muted">(Loads after selecting time range)</small></label>
<select id="location_name" name="location_name" class="form-control">
<option value="">All Locations</option>
</select>
</div>
</div>

<!-- Step 3: Select File Format -->
<div class="step-container">
<div class="step-header">Step 3: Select File Format</div>
<div class="form-group">
<label for="format">File Format</label>
<select id="format" name="format" class="form-control">
<option value="csv">CSV</option>
<option value="xls">XLS</option>
<option value="xlsx">XLSX</option>
</select>
</div>
</div>

<button type="submit" id="submitBtn" class="btn btn-success btn-block">Export</button>
</form>

<div class="loading-spinner" style="display: none;">
<div class="spinner-border text-primary" role="status">
<span class="sr-only">Loading...</span>
</div>
</div>

<div class="loading-overlay" style="display: none;"></div>
</div>
{% endblock %}

{% block extra_js %}
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>

function showLoadingSpinner() {
$('.loading-spinner, .loading-overlay').show();
}

function hideLoadingSpinner() {
$('.loading-spinner, .loading-overlay').hide();
}

$(document).ready(function() {
$('#species').select2({
minimumResultsForSearch: Infinity,
dropdownCssClass: 'select2-dropdown-custom'
});

function validateForm() {
var startDate = new Date($('#incident_date_from').val());
var endDate = new Date($('#incident_date_to').val());

if (startDate > endDate) {
$('#incident_date_to').addClass('is-invalid');
$('#submitBtn').prop('disabled', true);
return false;
} else {
$('#incident_date_to').removeClass('is-invalid');
$('#submitBtn').prop('disabled', false);
return true;
}
}

function loadLocations() {
var startDate = $('#incident_date_from').val();
var endDate = $('#incident_date_to').val();

if (!startDate || !endDate) {
return;
}

showLoadingSpinner()

$.ajax({
url: '{% url "marine_mammal_incidents:get_locations" %}',
data: {
start_date: startDate,
end_date: endDate
},
success: function(locations) {
var locationSelect = $('#location_name');
locationSelect.empty();
locationSelect.append($('<option>', {
value: '',
text: 'All Locations'
}));

$.each(locations, function(index, location) {
locationSelect.append($('<option>', {
value: location,
text: location
}));
});
},
error: function() {
alert('Error loading locations');
},
complete: function() {
hideLoadingSpinner();
}
});
}

$('#exportForm').on('submit', function(e) {
if (!validateForm()) {
e.preventDefault();
}
});

$('#incident_date_from, #incident_date_to').change(function() {
loadLocations();
validateForm();
});
});
</script>
{% endblock %}
Loading

0 comments on commit 2c0014d

Please sign in to comment.