diff --git a/src/open_inwoner/cms/cases/forms.py b/src/open_inwoner/cms/cases/forms.py index 8db8e84767..2e9d4fb0d5 100644 --- a/src/open_inwoner/cms/cases/forms.py +++ b/src/open_inwoner/cms/cases/forms.py @@ -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, @@ -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" @@ -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: diff --git a/src/open_inwoner/cms/cases/tests/test_htmx.py b/src/open_inwoner/cms/cases/tests/test_htmx.py index ff67b3cdcd..00a6220fa1 100644 --- a/src/open_inwoner/cms/cases/tests/test_htmx.py +++ b/src/open_inwoner/cms/cases/tests/test_htmx.py @@ -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", @@ -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 diff --git a/src/open_inwoner/cms/cases/views/status.py b/src/open_inwoner/cms/cases/views/status.py index 7d18eba55c..2b182ffc10 100644 --- a/src/open_inwoner/cms/cases/views/status.py +++ b/src/open_inwoner/cms/cases/views/status.py @@ -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 diff --git a/src/open_inwoner/components/templates/components/Button/Button.html b/src/open_inwoner/components/templates/components/Button/Button.html index 6dd222e4de..724b41d08e 100644 --- a/src/open_inwoner/components/templates/components/Button/Button.html +++ b/src/open_inwoner/components/templates/components/Button/Button.html @@ -21,7 +21,7 @@ {% endif %} {% else %} - + ` + + fileDivBig.innerHTML = fileHTML + + if (files[0].size > maxBytes) { + console.log('Dit bestand is te groot') + fileDivBig.classList.add('error-message') + const fileSizeError = document.createElement('div') + fileSizeError.textContent = 'Dit bestand is te groot' + fileSizeError.classList.add('error-message') + fileDivBig + .querySelector('.file-material-icon') + .appendChild(fileSizeError) + } + + fileList.appendChild(fileDivBig) + selectedFiles.push(file) + }) + //end template + // Display info sizeInfo.textContent = formatFileSize(files[0].size) nameInfo.textContent = `${files[0].name}` // Display in DOM formControlInfo.forEach((elem) => { - elem.classList.remove('form__control__info') - elem.classList.add('form__control__info--active') + elem.classList.remove('form__content__info') + elem.classList.add('form__content__info--active') }) } }) @@ -80,8 +133,8 @@ export class ShowInfo { }) formControlInfo.forEach((elem) => { - elem.classList.remove('form__control__info--active') - elem.classList.add('form__control__info') + elem.classList.remove('form__content__info--active') + elem.classList.add('form__content__info') }) }) } diff --git a/src/open_inwoner/openzaak/tests/test_case_detail.py b/src/open_inwoner/openzaak/tests/test_case_detail.py index 3b4580b9e9..3dc812b94c 100644 --- a/src/open_inwoner/openzaak/tests/test_case_detail.py +++ b/src/open_inwoner/openzaak/tests/test_case_detail.py @@ -904,7 +904,7 @@ def test_successful_document_upload_flow(self, m): form.action = reverse( "cases:case_detail_document_form", kwargs={"object_id": self.zaak["uuid"]} ) - form["title"] = "uploaded file" + # form["title"] = "uploaded file" form["type"] = zaak_type_iotc.id form["file"] = Upload("upload.txt", b"data", "text/plain") form_response = form.submit() @@ -944,7 +944,6 @@ def test_successful_document_upload_flow_with_uppercase_extension(self, m): form.action = reverse( "cases:case_detail_document_form", kwargs={"object_id": self.zaak["uuid"]} ) - form["title"] = "uploaded file" form["type"] = zaak_type_iotc.id form["file"] = Upload("upload.TXT", b"data", "text/plain") form_response = form.submit() @@ -993,7 +992,6 @@ def test_upload_file_flow_fails_with_invalid_file_extension(self, m): user=self.user, ) form = response.forms["document-upload"] - form["title"] = "uploaded file" form["type"] = zaak_type_iotc.id form["file"] = Upload("upload.xml", b"data", "application/xml") form_response = form.submit() @@ -1034,7 +1032,6 @@ def test_upload_with_larger_file_size_fails(self, m): ) form = response.forms["document-upload"] - form["title"] = "uploaded file" form["type"] = zaak_type_iotc.id form["file"] = Upload("upload.txt", b"data", "text/plain") form_response = form.submit() @@ -1209,7 +1206,6 @@ def test_request_error_in_uploading_document_shows_proper_message(self, m): form.action = reverse( "cases:case_detail_document_form", kwargs={"object_id": self.zaak["uuid"]} ) - form["title"] = "uploaded file" form["file"] = Upload("upload.txt", b"data", "text/plain") form_response = form.submit() @@ -1250,7 +1246,6 @@ def test_request_error_in_connecting_doc_with_zaak_shows_proper_message(self, m) form.action = reverse( "cases:case_detail_document_form", kwargs={"object_id": self.zaak["uuid"]} ) - form["title"] = "A title" form["file"] = Upload("upload.txt", b"data", "text/plain") form_response = form.submit() diff --git a/src/open_inwoner/scss/components/Card/Card.scss b/src/open_inwoner/scss/components/Card/Card.scss index a1cb606640..faff9f764a 100644 --- a/src/open_inwoner/scss/components/Card/Card.scss +++ b/src/open_inwoner/scss/components/Card/Card.scss @@ -96,6 +96,7 @@ &__img--contain { object-fit: contain; } + &__body { padding: var(--card-spacing); @@ -105,6 +106,13 @@ flex-wrap: wrap; } + &--direction-vertical { + align-items: center; + display: flex; + flex-direction: column; + gap: 16px; + } + .spacer { display: inline-block; width: 100%; diff --git a/src/open_inwoner/scss/components/Form/DocumentUpload.scss b/src/open_inwoner/scss/components/Form/DocumentUpload.scss index b3c4b8f999..e69de29bb2 100644 --- a/src/open_inwoner/scss/components/Form/DocumentUpload.scss +++ b/src/open_inwoner/scss/components/Form/DocumentUpload.scss @@ -1,255 +0,0 @@ -#document-upload { - gap: var(--spacing-tiny); - max-width: var(--mobile-xs-width); - - .button[type='submit']:disabled { - background-color: var(--color-gray) !important; - border-color: var(--color-gray) !important; - color: var(--color-white); - pointer-events: none; - cursor: default; - } - - .form__control.upload .form__submit { - *[class*='icon'], - .button { - position: initial; - margin-top: 2em; - } - } - - .inputfile-group { - display: block; - - .label, - .close { - display: block; - } - - .input-file { - .label__label--required { - display: none; - } - } - } - - .form__control__info { - display: none; - - &--active { - display: block; - } - } -} - -/// File-input site wide -input[type='file'] { - background-color: var(--color-white); - color: var(--color-primary); - border: 1px solid var(--color-mute); - border-radius: var(--border-radius); - display: inline-block; - filter: saturate(70%); - min-width: 100%; - max-width: var(--form-width); - padding: 0; - overflow: hidden; - cursor: pointer; - - @media (min-width: 768px) { - display: flex; - flex-direction: column; - min-width: var(--form-width); - } -} - -/// File-input button site wide -input[type='file']::file-selector-button { - color: var(--color-white); - background-color: var(--color-primary); - text-transform: uppercase; - border: 1px; - border-radius: var(--border-radius); - font-size: var(--font-size-body); - line-height: var(--font-line-height-body); - height: var(--row-height); - font-weight: normal; - text-align: center; - vertical-align: middle; - cursor: pointer; - white-space: nowrap; - padding: 0 12px 0 12px; - margin: 0 12px 0 0; - width: 150px; - - @media (min-width: 768px) { - width: 200px; - } -} - -.button-row .upload-button--disabled { - background-color: var(--color-gray) !important; - border-color: var(--color-gray) !important; -} - -.form__open-upload { - .file-type__select { - max-width: var(--mobile-xs-width); - } - .form__control > .label *[class*='icon'] { - top: 69%; - } - - .input-file { - display: flex; - flex-direction: row; - align-items: center; - justify-content: flex-start; - gap: 7px; - position: relative; - //width: 200px; - - *[class*='icons'] { - position: absolute; - top: 18px; - left: 12px; - color: orange; - } - - /// Hidden file-input for cases - .inputfile { - display: inline-block; - margin-top: var(--spacing-medium); - min-width: 200px; - height: var(--row-height); - opacity: 0; - overflow: hidden; - z-index: 200; - } - - .inputfile + .label, - .inputfile + .label__label { - display: inline-block; - position: absolute; - top: 5px; - left: 0; - padding: var(--spacing-medium) var(--spacing-large) var(--spacing-medium) - calc(3 * (var(--spacing-extra-large))); - font-size: var(--font-size-body); - color: var(--color-font-primary); - background-color: var(--color-primary); - border: 1px solid var(--color-primary); - border-radius: var(--border-radius); - min-width: 202px; - z-index: -1; - } - - .inputfile:focus + .label__label, - .inputfile.has-focus + .label__label, - .inputfile:hover + .label__label, - .inputfile + .label__label:hover, - .inputfile:focus + .label, - .inputfile.has-focus + .label, - .inputfile:hover + .label, - .inputfile + .label:hover { - background-color: var(--color-primary-darker); - top: 4px; - transition: all 0.3s, background-color 0.3s; - } - - .inputfile + .label__label *[class*='icons'], - .inputfile + .label *[class*='icons'] { - width: 1.3em; - vertical-align: middle; - color: white; - margin-left: var(--spacing-medium); - } - - .inputfile + .label__label { - cursor: pointer; /* "hand" cursor */ - } - - .inputfile:focus + .label, - .inputfile:focus-visible + .label, - .inputfile:focus + .label__label, - .inputfile:focus-visible + .label__label { - outline: var(--border-width) solid var(--color-secondary); - outline: -webkit-focus-ring-color auto 5px; - } - } - - .drive { - display: block; - - &.error { - display: none; - } - } - - .close .button--transparent { - color: var(--color-red); - - &.error { - display: none; - } - } - - .info-container { - display: none; - } - - .fieldset-container { - display: flex; - box-sizing: border-box; - flex-direction: row; - justify-content: space-around; - border: 1px solid lightgray; - border-radius: 4px; - height: 80px; - padding-top: var(--spacing-large); - margin-bottom: 20px; - - .fieldset__content { - color: var(--color-mute); - width: 200px; - - .upload-info { - display: inline-block; - font-family: var(--font-family-body); - font-size: var(--font-size-body); - color: var(--color-mute); - width: 200px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - - &__name { - color: var(--font-color-body); - font-weight: bold; - } - - &__error { - display: none; - position: relative; - - & *[class*='icon'] { - position: absolute; - top: var(--spacing-small); - right: -100px; - color: var(--color-primary); - } - - &.error { - color: var(--font-color-body); - font-weight: bold; - font-size: 19px; - line-height: var(--spacing-giant); - display: block; - margin-left: calc(-1 * (var(--spacing-large))); - overflow: initial; - } - } - } - } - } -} diff --git a/src/open_inwoner/scss/components/Form/FileInput.scss b/src/open_inwoner/scss/components/Form/FileInput.scss new file mode 100644 index 0000000000..0118882380 --- /dev/null +++ b/src/open_inwoner/scss/components/Form/FileInput.scss @@ -0,0 +1,42 @@ +.file-input { + .card:first-child { + text-align: center; + position: relative; + } + + &--drag-active .card:first-child { + background-color: var(--color-gray-lightest); + } + + .card__body { + box-sizing: border-box; + padding: var(--row-height); + } + + [class*='icon'] { + pointer-events: none; + position: static !important; + transform: none !important; + } + + &--drag-active .button { + pointer-events: none; + } + + &__input { + position: absolute; + opacity: 0; + pointer-events: none; + } + + > .p { + margin: calc(0.5 * var(--gutter-width)) 0; + display: block; + text-align: center; + } + + .h4 { + margin-top: var(--gutter-width); + margin-bottom: calc(0.5 * var(--gutter-width)); + } +} diff --git a/src/open_inwoner/scss/components/_index.scss b/src/open_inwoner/scss/components/_index.scss index ed1cda4bb2..8ec0d0e375 100644 --- a/src/open_inwoner/scss/components/_index.scss +++ b/src/open_inwoner/scss/components/_index.scss @@ -31,6 +31,7 @@ @import './Form/DocumentUpload.scss'; @import './Form/Error.scss'; @import './Form/Fieldset.scss'; +@import './Form/FileInput.scss'; @import './Form/Form.scss'; @import './Form/GroupInput'; @import './Form/Input.scss'; diff --git a/src/open_inwoner/templates/pages/cases/document_form.html b/src/open_inwoner/templates/pages/cases/document_form.html index 49ba5ef658..f4d12d5857 100644 --- a/src/open_inwoner/templates/pages/cases/document_form.html +++ b/src/open_inwoner/templates/pages/cases/document_form.html @@ -1,37 +1,9 @@ {% load i18n form_tags button_tags icon_tags %} -
- {# if local upload is enabled #} - {% render_form id="document-upload" form=form method="POST" hxencoding="multipart/form-data" hxpost=hxpost_document_action hxtarget="#form_upload" submit_text=_("Bestand uploaden") show_required=True extra_classes="case-detail-form" %} - {% csrf_token %} -
-
-
-
{% icon icon="insert_drive_file" outlined=True icon_position="before" %}
-
-
- {% trans "Selecteer uw bestand opnieuw" %} {% icon icon="arrow_downward" outlined=True icon_position="before" %}
-
-
-
-
{% button id="close_upload" icon="cancel" type='reset' text='' transparent=True icon_outlined=True icon_position="before" %}
-
-
-
- -
{% input form.title no_label=False no_help=True id="id_title" %}
- -
{% input form.type no_label=False no_help=True icon="expand_more" icon_position="after" class="label input" id="id_type" extra_classes="file-type__select" %}
- -
-
- {% file_input form.file text=_("Document selecteren") no_label=False no_help=True extra_classes="file-upload" %} -
- {% button_row %} - {% button type="submit" text=_("Document uploaden") id="submit_upload" primary=True %} - {% endbutton_row %} -
-
-
- {% endrender_form %} -
+{# if local upload is enabled #} +{% render_form id="document-upload" form=form method="POST" hxencoding="multipart/form-data" hxpost=hxpost_document_action hxtarget="#form_upload" submit_text=_("Bestand uploaden") extra_classes="case-detail-form" %} + {% csrf_token %} + {% input form.type no_label=False no_help=True class="label input" id="id_type" extra_classes="file-type__select" %} + {% file_input form.file %} + {% form_actions primary_text=_("Upload documenten") primary_icon="arrow_forward" enctype="multipart/form-data" %} +{% endrender_form %} diff --git a/src/open_inwoner/templates/pages/cases/status_inner.html b/src/open_inwoner/templates/pages/cases/status_inner.html index 0d28ad5664..7106c8fff4 100644 --- a/src/open_inwoner/templates/pages/cases/status_inner.html +++ b/src/open_inwoner/templates/pages/cases/status_inner.html @@ -102,16 +102,6 @@

{% trans "Document uploaden" %}

{% endif %} - {% if case.case_type_config_description %} -

{{ case.case_type_config_description }}

- {% else %} -

- {% blocktranslate with max_filesize=openzaak_config.max_upload_size allowed_extensions=case.allowed_file_extensions|join:', ' %} - Grootte max. {{ max_filesize }} MB, toegestane document formaten: {{ allowed_extensions }}. - {% endblocktranslate %} -

- {% endif %} - {# Upload document form. #}
{% include 'pages/cases/document_form.html' %}