diff --git a/nummi/main/forms.py b/nummi/main/forms.py index 05a6ae4..36e5628 100644 --- a/nummi/main/forms.py +++ b/nummi/main/forms.py @@ -12,7 +12,8 @@ class NummiForm(forms.ModelForm): template_name = "main/form/form_base.html" meta_fieldsets = [] - def __init__(self, *args, user, **kwargs): + def __init__(self, *args, **kwargs): + kwargs.pop("user", None) super().__init__(*args, **kwargs) @property diff --git a/nummi/main/static/main/css/form.css b/nummi/main/static/main/css/form.css index 3a25e1d..73c9eb9 100644 --- a/nummi/main/static/main/css/form.css +++ b/nummi/main/static/main/css/form.css @@ -1,8 +1,32 @@ -@keyframes border-pulse { - from { - border-color: var(--green); +.drop-zone { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + grid-template-columns: 1fr; + grid-template-rows: 1fr; + align-items: center; + text-align: center; + color: transparent; + display: grid; + transition-property: backdrop-filter; + transition-duration: 750ms; + z-index: -1; + + > span { + font-weight: 650; + font-size: 2rem; + transition-property: color; + transition-duration: inherit; } - to { + + main.highlight > & { + z-index: 100; + backdrop-filter: blur(0.1rem); + > span { + color: var(--green); + } } } @@ -14,6 +38,10 @@ form { grid-template-columns: 1fr; } + &.hidden { + display: none; + } + .column { display: grid; gap: 0.5rem; diff --git a/nummi/main/static/main/css/main.css b/nummi/main/static/main/css/main.css index 3dc29d4..a154868 100644 --- a/nummi/main/static/main/css/main.css +++ b/nummi/main/static/main/css/main.css @@ -85,6 +85,7 @@ footer { @media (width > 720px) { padding: 2rem; } + background: var(--bg); } main { position: relative; diff --git a/nummi/main/templatetags/main_extras.py b/nummi/main/templatetags/main_extras.py index 0a9abcc..c5eea6c 100644 --- a/nummi/main/templatetags/main_extras.py +++ b/nummi/main/templatetags/main_extras.py @@ -59,7 +59,7 @@ def messageicon(level): @register.filter def extension(file): - return file.name.split(".")[-1].upper() + return file.name.split(".", 1)[1].upper() @register.filter diff --git a/nummi/statement/forms.py b/nummi/statement/forms.py index c3841f2..353ebe7 100644 --- a/nummi/statement/forms.py +++ b/nummi/statement/forms.py @@ -25,7 +25,7 @@ class StatementForm(NummiForm): ] def __init__(self, *args, **kwargs): - _user = kwargs.get("user") + _user = kwargs.pop("user") _disable_account = kwargs.pop("disable_account", False) super().__init__(*args, **kwargs) self.fields["account"].queryset = _user.account_set.exclude(archived=True) diff --git a/nummi/transaction/forms.py b/nummi/transaction/forms.py index 5583c84..807c00e 100644 --- a/nummi/transaction/forms.py +++ b/nummi/transaction/forms.py @@ -1,6 +1,8 @@ import json from category.forms import CategorySelect +from django import forms +from django.forms import formset_factory from main.forms import DatalistInput, NummiFileInput, NummiForm from statement.forms import StatementSelect @@ -46,7 +48,7 @@ class TransactionForm(NummiForm): ] def __init__(self, *args, **kwargs): - _user = kwargs.get("user") + _user = kwargs.pop("user") _disable_statement = kwargs.pop("disable_statement", False) _autocomplete = kwargs.pop("autocomplete", False) super().__init__(*args, **kwargs) @@ -117,3 +119,29 @@ class InvoiceForm(NummiForm): widgets = { "file": NummiFileInput, } + + +class MultipleFileInput(forms.ClearableFileInput): + allow_multiple_selected = True + + +class MultipleFileField(forms.FileField): + def __init__(self, *args, **kwargs): + kwargs.setdefault("widget", MultipleFileInput()) + super().__init__(*args, **kwargs) + + def clean(self, data, initial=None): + single_file_clean = super().clean + if isinstance(data, (list, tuple)): + result = [single_file_clean(d, initial) for d in data] + else: + result = single_file_clean(data, initial) + return result + + +class MultipleInvoicesForm(forms.Form): + prefix = "invoices" + invoices = MultipleFileField() + + +InvoicesFormSet = formset_factory(MultipleInvoicesForm) diff --git a/nummi/transaction/static/transaction/js/invoice_form.js b/nummi/transaction/static/transaction/js/invoice_form.js new file mode 100644 index 0000000..d18abfa --- /dev/null +++ b/nummi/transaction/static/transaction/js/invoice_form.js @@ -0,0 +1,22 @@ +const dropArea = document.querySelector("main"); +const form = document.querySelector("form.invoices"); + +dropArea.addEventListener("dragover", (event) => { + event.preventDefault(); + dropArea.classList.add("highlight"); +}); + +dropArea.addEventListener("dragleave", () => { + dropArea.classList.remove("highlight"); +}); + +dropArea.addEventListener("drop", (event) => { + console.log(event); + event.preventDefault(); + dropArea.classList.remove("highlight"); + const files = event.dataTransfer.files; + console.log(files); + const input = form.querySelector("input[type=file]"); + input.files = files; + form.submit(); +}); diff --git a/nummi/transaction/templates/transaction/transaction_detail.html b/nummi/transaction/templates/transaction/transaction_detail.html index 4cfd068..7e58c0f 100644 --- a/nummi/transaction/templates/transaction/transaction_detail.html +++ b/nummi/transaction/templates/transaction/transaction_detail.html @@ -10,6 +10,7 @@ {% css "main/css/form.css" %} {% css "main/css/table.css" %} {% css "main/css/plot.css" %} + {% js "transaction/js/invoice_form.js" %} {% endblock link %} {% block body %}