Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#1817] Show errors for selected documents #839

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 16 additions & 9 deletions src/open_inwoner/cms/cases/forms.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
import os

from django import forms
from django.core.exceptions import ValidationError
from django.core.exceptions import ObjectDoesNotExist, ValidationError
from django.utils.translation import gettext_lazy as _

from open_inwoner.openzaak.models import (
OpenZaakConfig,
ZaakTypeConfig,
ZaakTypeInformatieObjectTypeConfig,
)
from open_inwoner.utils.validators import CharFieldValidator


class CaseUploadForm(forms.Form):
title = forms.CharField(
label=_("Titel bestand"), max_length=255, validators=[CharFieldValidator()]
)
type = forms.ModelChoiceField(
ZaakTypeInformatieObjectTypeConfig.objects.none(),
empty_label=None,
Expand All @@ -23,8 +20,19 @@ class CaseUploadForm(forms.Form):
file = forms.FileField(label=_("Bestand"))

def __init__(self, case, **kwargs):
self.oz_config = OpenZaakConfig.get_solo()
super().__init__(**kwargs)

help_text = f"Grootte max. { self.oz_config.max_upload_size } MB, toegestane document formaten: { ', '.join(self.oz_config.allowed_file_extensions) }."

try:
ztc = ZaakTypeConfig.objects.filter_case_type(case.zaaktype).get()
help_text = ztc.description or help_text
except (AttributeError, ObjectDoesNotExist):
pass

self.fields["file"].help_text = help_text

if case:
self.fields[
"type"
Expand All @@ -41,14 +49,13 @@ def __init__(self, case, **kwargs):
def clean_file(self):
file = self.cleaned_data["file"]

config = OpenZaakConfig.get_solo()
max_allowed_size = 1024**2 * config.max_upload_size
allowed_extensions = sorted(config.allowed_file_extensions)
max_allowed_size = 1024**2 * self.oz_config.max_upload_size
allowed_extensions = sorted(self.oz_config.allowed_file_extensions)
filename, file_extension = os.path.splitext(file.name)

if file.size > max_allowed_size:
raise ValidationError(
f"Een aangeleverd bestand dient maximaal {config.max_upload_size} MB te zijn, uw bestand is te groot."
f"Een aangeleverd bestand dient maximaal {self.oz_config.max_upload_size} MB te zijn, uw bestand is te groot."
)

if file_extension.lower().replace(".", "") not in allowed_extensions:
Expand Down
9 changes: 3 additions & 6 deletions src/open_inwoner/cms/cases/tests/test_htmx.py
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,8 @@ def test_cases(self, m):
upload_form = page.locator("#document-upload")
expect(upload_form).to_be_visible()

upload_form.get_by_label(_("Document selecteren")).set_input_files(
file_input = upload_form.get_by_text(_("Sleep of selecteer bestand"))
file_input.set_input_files(
files=[
{
"name": "uploaded_test_file.txt",
Expand All @@ -441,13 +442,9 @@ def test_cases(self, m):
}
],
)
submit_button = upload_form.get_by_role("button", name=_("Document uploaden"))
submit_button = upload_form.get_by_role("button", name=_("Upload documenten"))
expect(submit_button).to_be_visible()

title_input = upload_form.get_by_label(_("Titel bestand"))
expect(title_input).to_be_visible()
title_input.fill("uploaded document")

submit_button.click()

# check for new file
Expand Down
2 changes: 1 addition & 1 deletion src/open_inwoner/cms/cases/views/status.py
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ def handle_document_upload(self, request, form):
cleaned_data = form.cleaned_data

file = cleaned_data["file"]
title = cleaned_data["title"]
title = file.name
document_type = cleaned_data["type"]
source_organization = self.case.bronorganisatie

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
{% endif %}
</a>
{% else %}
<button
<{{ tag }}
class="{{ classes }}"
type="{{type}}"
name="{{ name }}"
Expand All @@ -42,5 +42,5 @@
{% else %}
{% if not hide_text %}{{text}}{% endif %}
{% endif %}
</button>
</{{ tag }}>
{% endif %}
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
{% load i18n form_tags icon_tags %}

<div class="form__control {{ extra_classes|default:"upload" }}">
<div class="inputfile-group">
<label class="label">
<span class="input-file">
{{ field|addclass:"inputfile" }}
{% load i18n button_tags card_tags form_tags icon_tags %}

<span class="label__label" for="{{ field.auto_id }}">
{% icon icon="cloud_upload" icon_position="before" outlined=True %}
{{ text }}
<div class="form__control file-input">
{% render_card direction="vertical" %}
{% icon icon="upload" icon_position="before" outlined=True %}
<input class="file-input__input" id="{{ field.auto_id }}" name="file" type="file">
{% button primary=True tag='label' text=text|default:_('Sleep of selecteer bestand') extra_attributes='for='|add:field.auto_id %}
{% endrender_card %}

</span>{% if field.field.required %}<span class="label__label--required"> * </span>{% endif %}
</span>
{% if field.help_text %}<p class="p p--muted p--small">{{ field.help_text }}</p>{% endif %}
{% if field.errors %}{% errors errors=field.errors %}{% endif %}

{% if field.errors %}
{% errors errors=field.errors %}
{% endif %}
</label>
<div class="file-list" aria-live="polite">
<h4 class="h4">{% trans 'Geselecteerd bestand'%}</h4>
<ul class="file-list__list" aria-live="polite" data-label-delete="{% trans 'Verwijderen' %}"></ul>
</div>
</div>
2 changes: 2 additions & 0 deletions src/open_inwoner/components/templatetags/button_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ def button(text, **kwargs):
- icon: string | the icon that you want to display.
- icon_position: enum[before, after] | where the icon should be positioned to the text.
- icon_outlined: bool | if the outlined icons should be used.
- tag: string | The tag to use (if not a link, defaults to button)
- text_icon: string | An additional icon to show before the (current value) text.
- type: string | the type of button that should be used.
- title: string | The HTML title attribute if different than the text.
Expand Down Expand Up @@ -129,4 +130,5 @@ def get_classes():

kwargs["classes"] = get_classes()
kwargs["text"] = text
kwargs["tag"] = kwargs.get("tag", "button")
return {**kwargs}
4 changes: 2 additions & 2 deletions src/open_inwoner/components/templatetags/form_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,12 +277,12 @@ def input(field, **kwargs):


@register.inclusion_tag("components/Form/FileInput.html")
def file_input(file, text, **kwargs):
def file_input(file, text="", **kwargs):
"""
Displaying a file upload interface.

Usage:
{% file_input form.field text=_('Document selecteren') %}
{% file_input form.field text=_('Selecteer bestanden') %}

Variables:
+ field: Field | The field that needs to be rendered.
Expand Down
5 changes: 4 additions & 1 deletion src/open_inwoner/components/templatetags/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,7 @@ def get_product_url(context, product):
def as_attributes(attribute_dict):
if not attribute_dict:
return ""
return format_html_join(" ", '{}="{}"', attribute_dict.items())
try:
return format_html_join(" ", '{}="{}"', attribute_dict.items())
except AttributeError:
return attribute_dict
4 changes: 4 additions & 0 deletions src/open_inwoner/conf/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@
}
}

# Geospatial libraries
GEOS_LIBRARY_PATH = config("GEOS_LIBRARY_PATH", None)
GDAL_LIBRARY_PATH = config("GDAL_LIBRARY_PATH", None)

CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
Expand Down
23 changes: 23 additions & 0 deletions src/open_inwoner/js/components/abstract/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export class Component {

this.setState(initialState)
this.bindEvents()
this.setupMutationObserver()
}

/**
Expand All @@ -28,6 +29,28 @@ export class Component {
*/
bindEvents() {}

/**
* Unbinds events from callbacks.
* Callbacks functions should be strict equal between `bindEvents()` and `unbindEvents`.
* Use this to call `removeEventListener()` for every `addEventListener`()` called.
*/
unbindEvents() {}

/**
* Sets up the mutation observer managing §this.unbindEvents()`.
*/
setupMutationObserver() {
this.mutationObserver = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.type === 'childList' && !document.contains(this.node)) {
// Element has been removed from the DOM
this.unbindEvents()
this.mutationObserver.disconnect() // Stop observing once the element is removed
}
})
})
}

/**
* Mutates state, then re-renders.
* @param {Object} changes Object containing (only) changes to state.
Expand Down
Loading