From 06eed29be1acb86c9c20404cbafdc4da8dccc3e8 Mon Sep 17 00:00:00 2001 From: Oak McIlwain Date: Wed, 16 Oct 2024 16:55:31 +0800 Subject: [PATCH 1/4] Add default option for is_emailuser_column when adding new column. --- .../src/components/internal/occurrence/bulk_import_schema.vue | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/boranga/frontend/boranga/src/components/internal/occurrence/bulk_import_schema.vue b/boranga/frontend/boranga/src/components/internal/occurrence/bulk_import_schema.vue index 4cb1e333..f82d9e11 100644 --- a/boranga/frontend/boranga/src/components/internal/occurrence/bulk_import_schema.vue +++ b/boranga/frontend/boranga/src/components/internal/occurrence/bulk_import_schema.vue @@ -754,7 +754,8 @@ export default { default_value: null, import_validations: [], lookup_filters: [], - is_editable_by_user: true + is_editable_by_user: true, + is_emailuser_column: false } }, addSingleColumn() { From 690902bb70f9833933b945f451fdf3f3af27eda7 Mon Sep 17 00:00:00 2001 From: Oak McIlwain Date: Thu, 17 Oct 2024 10:30:15 +0800 Subject: [PATCH 2/4] Add error handling that can cover exceptions of different formats (list of strings vs list of objects) that may be returned in response.data or response.body. --- .../internal/occurrence/bulk_import_schema.vue | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/boranga/frontend/boranga/src/components/internal/occurrence/bulk_import_schema.vue b/boranga/frontend/boranga/src/components/internal/occurrence/bulk_import_schema.vue index f82d9e11..023f1c7e 100644 --- a/boranga/frontend/boranga/src/components/internal/occurrence/bulk_import_schema.vue +++ b/boranga/frontend/boranga/src/components/internal/occurrence/bulk_import_schema.vue @@ -972,16 +972,21 @@ export default { } else if (Object.hasOwn(error, 'body')) { errors = error.body } - let error_message = 'Something went wrong :-(' - if (errors instanceof Array) { - error_message = '' + let error_message_string = 'Something went wrong :-(' + if (errors instanceof Object) { + error_message_string = '' for (let i = 0; i < errors.length; i++) { - error_message += `
  • ${errors[i].error_message}
  • ` + let error_message = errors[i].error_message ? errors[i].error_message : errors[i] + error_message_string += `
  • ${error_message}
  • ` } + console.log(error_message_string) + } else if (typeof errors === 'string') { + error_message_string = errors } + console.error(error_message_string) swal.fire({ title: 'Schema Validation Failed', - html: error_message, + html: error_message_string, icon: 'error', confirmButtonText: 'OK', customClass: { From d10bf52868c6e39a6791eb5bb66f52b55b3502d8 Mon Sep 17 00:00:00 2001 From: Oak McIlwain Date: Thu, 17 Oct 2024 10:33:09 +0800 Subject: [PATCH 3/4] Add code to make sure when validating a schema that only species or communities that have occurrences are used as a sample value (Otherwise the validation can easily fail when attempting to validate a linked occurrence). --- boranga/components/occurrence/models.py | 48 +++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/boranga/components/occurrence/models.py b/boranga/components/occurrence/models.py index 2d1e7411..f6f5c919 100644 --- a/boranga/components/occurrence/models.py +++ b/boranga/components/occurrence/models.py @@ -31,7 +31,16 @@ from django.core.files.uploadedfile import InMemoryUploadedFile from django.core.validators import MaxValueValidator, MinValueValidator from django.db import IntegrityError, models, transaction -from django.db.models import CharField, Count, Func, ManyToManyField, Max, Q +from django.db.models import ( + CharField, + Count, + Func, + ManyToManyField, + Max, + OuterRef, + Q, + Subquery, +) from django.db.models.functions import Cast, Length from django.utils import timezone from django.utils.functional import cached_property @@ -6872,11 +6881,34 @@ def get_sample_value(self, errors, species_or_community_identifier=None): if isinstance(field, models.ForeignKey): related_model_qs = self.filtered_related_model_qs + # Special case for species or community + # Ensure only species or communities that have occurrences are selected + # in case the schema includes the occurrence model (quite likely) + if field.name == "species": + related_model_qs = related_model_qs.annotate( + occurrence_count=Subquery( + Occurrence.objects.filter(species__pk=OuterRef("pk")) + .values("species") + .annotate(count=Count("id")) + .values("count") + ) + ).filter(occurrence_count__gt=0) + if field.name == "community": + related_model_qs = related_model_qs.annotate( + occurrence_count=Subquery( + Occurrence.objects.filter(community__pk=OuterRef("pk")) + .values("species") + .annotate(count=Count("id")) + .values("count") + ) + ).filter(occurrence_count__gt=0) + if not related_model_qs.exists(): + error_message = f"No records found for foreign key field {field.related_model._meta.model_name}" errors.append( { "error_type": "no_records", - "error_message": f"No records found for foreign key {field.related_model._meta.model_name}", + "error_message": error_message, } ) @@ -6987,6 +7019,18 @@ def get_sample_value(self, errors, species_or_community_identifier=None): filter_field = { "community__taxonomy__community_migrated_id": species_or_community_identifier } + if not random_occurrence.exists(): + error_message = ( + f"No occurrences found where species or community identifier = " + f"{species_or_community_identifier}" + ) + errors.append( + { + "error_type": "no_occurrences", + "error_message": error_message, + } + ) + return None return ( random_occurrence.filter(**filter_field) .order_by("?") From 95a6bf5fa24a034f713c130f245da8b224a38af2 Mon Sep 17 00:00:00 2001 From: Oak McIlwain Date: Thu, 17 Oct 2024 10:36:29 +0800 Subject: [PATCH 4/4] Add loading spinner while schema is loading. Large schemas can take around 3 seconds to load. --- .../internal/occurrence/bulk_import_schema.vue | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/boranga/frontend/boranga/src/components/internal/occurrence/bulk_import_schema.vue b/boranga/frontend/boranga/src/components/internal/occurrence/bulk_import_schema.vue index 023f1c7e..3402e261 100644 --- a/boranga/frontend/boranga/src/components/internal/occurrence/bulk_import_schema.vue +++ b/boranga/frontend/boranga/src/components/internal/occurrence/bulk_import_schema.vue @@ -44,7 +44,8 @@ class="spinner-border spinner-border-sm me-1" role="status" aria-hidden="true"> - Validat + Validat Preview @@ -453,8 +454,8 @@