diff --git a/assets/controllers/form_upload_guard_controller.js b/assets/controllers/form_upload_guard_controller.js new file mode 100644 index 0000000..ddfd492 --- /dev/null +++ b/assets/controllers/form_upload_guard_controller.js @@ -0,0 +1,40 @@ +import { Controller } from '@hotwired/stimulus' + +export default class extends Controller { + + static targets = ['submit'] + + connect () { + this.uploading = false + this.boundOnUploading = this.onUploading.bind(this) + this.boundOnComplete = this.onComplete.bind(this) + window.addEventListener('dropzone:uploading', this.boundOnUploading) + window.addEventListener('dropzone:complete', this.boundOnComplete) + } + + onUploading () { + this.uploading = true + this.submitTargets.forEach(button => { + button.disabled = true + }) + } + + onComplete () { + this.uploading = false + this.submitTargets.forEach(button => { + button.disabled = false + }) + } + + guard (event) { + if (this.uploading) { + event.preventDefault() + event.stopImmediatePropagation() + } + } + + disconnect () { + window.removeEventListener('dropzone:uploading', this.boundOnUploading) + window.removeEventListener('dropzone:complete', this.boundOnComplete) + } +} diff --git a/assets/controllers/upload_collection_controller.js b/assets/controllers/upload_collection_controller.js index 3898a70..8b483a4 100644 --- a/assets/controllers/upload_collection_controller.js +++ b/assets/controllers/upload_collection_controller.js @@ -73,7 +73,7 @@ export default class extends Controller { }) } - disconnect() { + disconnect () { this.dropzone.destroy() } } diff --git a/assets/styles/components/button.css b/assets/styles/components/button.css index 426332a..1833cdd 100644 --- a/assets/styles/components/button.css +++ b/assets/styles/components/button.css @@ -1,6 +1,6 @@ .btn { @apply inline-flex space-x-1 justify-center rounded-lg text-sm uppercase font-semibold py-2.5 px-4; - @apply bg-primary text-white hover:bg-primary/80 shadow-md; + @apply bg-primary text-white hover:bg-primary/80 shadow-md disabled:opacity-50 disabled:cursor-not-allowed; } .btn--small { diff --git a/templates/admin/system/contact/_form.html.twig b/templates/admin/system/contact/_form.html.twig index a470281..5ee3f32 100644 --- a/templates/admin/system/contact/_form.html.twig +++ b/templates/admin/system/contact/_form.html.twig @@ -1,4 +1,5 @@ -{{ form_start(form, { 'attr': { 'hx-post': app.request.uri, 'hx-target': '#htmx-modal', 'hx-swap': 'outerHTML' } }) }} +{% set formAttr = stimulus_controller('form-upload-guard')|stimulus_action('form-upload-guard', 'guard', 'submit') %} +{{ form_start(form, { 'attr': { 'hx-post': app.request.uri, 'hx-target': '#htmx-modal', 'hx-swap': 'outerHTML' }|merge(formAttr.toArray()) }) }}
{{ form_row(form.category) }} {{ form_row(form.name) }} @@ -18,7 +19,7 @@ {{ form_errors(form) }}
- {{ form_rest(form) }} diff --git a/templates/administrative/disposition/modal_document_upload.html.twig b/templates/administrative/disposition/modal_document_upload.html.twig index a156e45..eab71f4 100644 --- a/templates/administrative/disposition/modal_document_upload.html.twig +++ b/templates/administrative/disposition/modal_document_upload.html.twig @@ -3,7 +3,8 @@ {% block title %}{{ modalTitle }}{% endblock %} {% block content %} - {{ form_start(form, { 'attr': { 'hx-post': app.request.uri, 'hx-target': '#htmx-modal', 'hx-swap': 'outerHTML' }}) }} + {% set formAttr = stimulus_controller('form-upload-guard')|stimulus_action('form-upload-guard', 'guard', 'submit') %} + {{ form_start(form, { 'attr': { 'hx-post': app.request.uri, 'hx-target': '#htmx-modal', 'hx-swap': 'outerHTML' }|merge(formAttr.toArray()) }) }}
{% include '_partials/_upload_collection_form.html.twig' with { 'endpoint_upload': path('_uploader_upload_contract'), @@ -12,7 +13,7 @@ 'accepted_files': 'image/jpg,image/jpeg,application/pdf', } %}
- {{ form_rest(form) }} diff --git a/templates/administrative/system/document/modal_replace.html.twig b/templates/administrative/system/document/modal_replace.html.twig index 2b8572b..c185a9c 100644 --- a/templates/administrative/system/document/modal_replace.html.twig +++ b/templates/administrative/system/document/modal_replace.html.twig @@ -3,7 +3,8 @@ {% block title %}Dokument ersetzen{% endblock %} {% block content %} - {{ form_start(form, { 'attr': { 'hx-post': app.request.uri, 'hx-target': '#htmx-modal', 'hx-swap': 'outerHTML' } }) }} + {% set formAttr = stimulus_controller('form-upload-guard')|stimulus_action('form-upload-guard', 'guard', 'submit') %} + {{ form_start(form, { 'attr': { 'hx-post': app.request.uri, 'hx-target': '#htmx-modal', 'hx-swap': 'outerHTML' }|merge(formAttr.toArray()) }) }}
{% include '_partials/_upload_collection_form.html.twig' with { 'endpoint_upload': path('_uploader_upload_document'), @@ -12,7 +13,7 @@ 'accepted_files': 'application/pdf', } %}
- {{ form_rest(form) }} diff --git a/templates/administrative/system/document/modal_upload.html.twig b/templates/administrative/system/document/modal_upload.html.twig index f2aab43..e192119 100644 --- a/templates/administrative/system/document/modal_upload.html.twig +++ b/templates/administrative/system/document/modal_upload.html.twig @@ -3,7 +3,8 @@ {% block title %}Dokumente hinzufügen{% endblock %} {% block content %} - {{ form_start(form, { 'attr': { 'hx-post': app.request.uri, 'hx-target': '#htmx-modal', 'hx-swap': 'outerHTML' }}) }} + {% set formAttr = stimulus_controller('form-upload-guard')|stimulus_action('form-upload-guard', 'guard', 'submit') %} + {{ form_start(form, { 'attr': { 'hx-post': app.request.uri, 'hx-target': '#htmx-modal', 'hx-swap': 'outerHTML' }|merge(formAttr.toArray()) }) }}
{% include '_partials/_upload_collection_form.html.twig' with { 'endpoint_upload': path('_uploader_upload_document'), @@ -11,7 +12,7 @@ 'accepted_files': 'application/pdf', } %}
- {{ form_rest(form) }} diff --git a/templates/administrative/teamer/index.html.twig b/templates/administrative/teamer/index.html.twig index 46e125a..03416a3 100644 --- a/templates/administrative/teamer/index.html.twig +++ b/templates/administrative/teamer/index.html.twig @@ -101,7 +101,7 @@ {{ icon('check') }} {% endif %} - {% if teamer.user.disabled %} + {% if teamer.user is not null and teamer.user.disabled %} {% if is_granted('ROLE_ADMIN') %} @@ -94,7 +95,8 @@ {# New invoice #} {% if workflow_can(disposition, 'upload_invoice') %} - {{ form_start(form) }} + {% set formAttr = stimulus_controller('form-upload-guard')|stimulus_action('form-upload-guard', 'guard', 'submit') %} + {{ form_start(form, { 'attr': formAttr.toArray() }) }}
Honorarnote @@ -106,7 +108,7 @@ 'endpoint_upload': path('_uploader_upload_invoice'), 'accepted_files': 'image/jpg,image/jpeg,application/pdf', } %} -
diff --git a/templates/teamer/profile/index.html.twig b/templates/teamer/profile/index.html.twig index b6f80e9..075b20f 100644 --- a/templates/teamer/profile/index.html.twig +++ b/templates/teamer/profile/index.html.twig @@ -15,7 +15,8 @@ {% endmacro %} {% block content %} - {{ form_start(form) }} + {% set formAttr = stimulus_controller('form-upload-guard')|stimulus_action('form-upload-guard', 'guard', 'submit') %} + {{ form_start(form, { 'attr': formAttr.toArray() }) }}
@@ -167,7 +168,7 @@ } %}
- diff --git a/templates/teamer/profile/license/modal_add.html.twig b/templates/teamer/profile/license/modal_add.html.twig index 7647ba7..2c94903 100644 --- a/templates/teamer/profile/license/modal_add.html.twig +++ b/templates/teamer/profile/license/modal_add.html.twig @@ -3,7 +3,8 @@ {% block title %}Lizenz hinzufügen{% endblock %} {% block content %} - {{ form_start(form, { 'attr': { 'hx-post': app.request.uri, 'hx-target': '#htmx-modal', 'hx-swap': 'outerHTML' } }) }} + {% set formAttr = stimulus_controller('form-upload-guard')|stimulus_action('form-upload-guard', 'guard', 'submit') %} + {{ form_start(form, { 'attr': { 'hx-post': app.request.uri, 'hx-target': '#htmx-modal', 'hx-swap': 'outerHTML' }|merge(formAttr.toArray()) }) }} {% if not form.vars.valid %}
{% include '_partials/_form_errors.html.twig' with { 'form': form } %} @@ -23,7 +24,7 @@ } %}
- {{ form_rest(form) }}