diff --git a/app/apps/accounts/forms.py b/app/apps/accounts/forms.py index c67da67..801ff12 100644 --- a/app/apps/accounts/forms.py +++ b/app/apps/accounts/forms.py @@ -3,12 +3,12 @@ from apps.common.fields.forms.dynamic_select import ( DynamicModelChoiceField, DynamicModelMultipleChoiceField, ) +from apps.common.widgets.crispy.daisyui import Switch from apps.common.widgets.crispy.submit import NoClassSubmit from apps.common.widgets.decimal import ArbitraryDecimalDisplayNumberInput from apps.common.widgets.tom_select import TomSelect from apps.currencies.models import Currency from apps.transactions.models import TransactionCategory, TransactionTag -from crispy_bootstrap5.bootstrap5 import Switch from crispy_forms.bootstrap import FormActions from crispy_forms.helper import FormHelper from crispy_forms.layout import Column, Field, Layout, Row @@ -36,17 +36,13 @@ class AccountGroupForm(forms.ModelForm): if self.instance and self.instance.pk: self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Update"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Update"), css_class="btn btn-primary"), ), ) else: self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Add"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Add"), css_class="btn btn-primary"), ), ) @@ -106,17 +102,13 @@ class AccountForm(forms.ModelForm): if self.instance and self.instance.pk: self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Update"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Update"), css_class="btn btn-primary"), ), ) else: self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Add"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Add"), css_class="btn btn-primary"), ), ) @@ -156,7 +148,6 @@ class AccountBalanceForm(forms.Form): Row( Column("category"), Column("tags"), - css_class="form-row", ), Field("account_id"), ) diff --git a/app/apps/common/forms.py b/app/apps/common/forms.py index ccde74b..d604ed8 100644 --- a/app/apps/common/forms.py +++ b/app/apps/common/forms.py @@ -1,14 +1,13 @@ -from crispy_forms.bootstrap import FormActions -from django import forms -from django.contrib.auth import get_user_model -from django.utils.translation import gettext_lazy as _ -from django.core.exceptions import ValidationError -from crispy_forms.helper import FormHelper -from crispy_forms.layout import Layout, Field, Submit, Div, HTML - -from apps.common.widgets.tom_select import TomSelect, TomSelectMultiple from apps.common.models import SharedObject from apps.common.widgets.crispy.submit import NoClassSubmit +from apps.common.widgets.tom_select import TomSelect, TomSelectMultiple +from crispy_forms.bootstrap import FormActions +from crispy_forms.helper import FormHelper +from crispy_forms.layout import HTML, Div, Field, Layout, Submit +from django import forms +from django.contrib.auth import get_user_model +from django.core.exceptions import ValidationError +from django.utils.translation import gettext_lazy as _ User = get_user_model() @@ -76,9 +75,7 @@ class SharedObjectForm(forms.Form): HTML("
"), Field("shared_with_users"), FormActions( - NoClassSubmit( - "submit", _("Save"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Save"), css_class="btn btn-primary"), ), ) diff --git a/app/apps/common/widgets/crispy/daisyui.py b/app/apps/common/widgets/crispy/daisyui.py new file mode 100644 index 0000000..93d4b07 --- /dev/null +++ b/app/apps/common/widgets/crispy/daisyui.py @@ -0,0 +1,5 @@ +from crispy_forms.layout import Field + + +class Switch(Field): + template = "crispy-daisyui/layout/switch.html" diff --git a/app/apps/currencies/forms.py b/app/apps/currencies/forms.py index 1ef5c26..3c9ff64 100644 --- a/app/apps/currencies/forms.py +++ b/app/apps/currencies/forms.py @@ -1,9 +1,9 @@ +from apps.common.widgets.crispy.daisyui import Switch from apps.common.widgets.crispy.submit import NoClassSubmit from apps.common.widgets.datepicker import AirDateTimePickerInput from apps.common.widgets.decimal import ArbitraryDecimalDisplayNumberInput from apps.common.widgets.tom_select import TomSelect from apps.currencies.models import Currency, ExchangeRate, ExchangeRateService -from crispy_bootstrap5.bootstrap5 import Switch from crispy_forms.bootstrap import FormActions from crispy_forms.helper import FormHelper from crispy_forms.layout import Column, Layout, Row @@ -50,17 +50,13 @@ class CurrencyForm(forms.ModelForm): if self.instance and self.instance.pk: self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Update"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Update"), css_class="btn btn-primary"), ), ) else: self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Add"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Add"), css_class="btn btn-primary"), ), ) @@ -88,17 +84,13 @@ class ExchangeRateForm(forms.ModelForm): if self.instance and self.instance.pk: self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Update"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Update"), css_class="btn btn-primary"), ), ) else: self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Add"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Add"), css_class="btn btn-primary"), ), ) @@ -141,16 +133,12 @@ class ExchangeRateServiceForm(forms.ModelForm): if self.instance and self.instance.pk: self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Update"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Update"), css_class="btn btn-primary"), ), ) else: self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Add"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Add"), css_class="btn btn-primary"), ), ) diff --git a/app/apps/dca/forms.py b/app/apps/dca/forms.py index 939aa39..31f25b2 100644 --- a/app/apps/dca/forms.py +++ b/app/apps/dca/forms.py @@ -3,13 +3,14 @@ from apps.common.fields.forms.dynamic_select import ( DynamicModelChoiceField, DynamicModelMultipleChoiceField, ) +from apps.common.widgets.crispy.daisyui import Switch from apps.common.widgets.crispy.submit import NoClassSubmit from apps.common.widgets.datepicker import AirDatePickerInput from apps.common.widgets.decimal import ArbitraryDecimalDisplayNumberInput from apps.common.widgets.tom_select import TomSelect, TransactionSelect from apps.dca.models import DCAEntry, DCAStrategy from apps.transactions.models import Transaction, TransactionCategory, TransactionTag -from crispy_bootstrap5.bootstrap5 import BS5Accordion, Switch +from crispy_bootstrap5.bootstrap5 import BS5Accordion from crispy_forms.bootstrap import AccordionGroup, FormActions from crispy_forms.helper import FormHelper from crispy_forms.layout import HTML, Column, Layout, Row @@ -43,17 +44,13 @@ class DCAStrategyForm(forms.ModelForm): if self.instance and self.instance.pk: self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Update"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Update"), css_class="btn btn-primary"), ), ) else: self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Add"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Add"), css_class="btn btn-primary"), ), ) @@ -206,17 +203,13 @@ class DCAEntryForm(forms.ModelForm): if self.instance and self.instance.pk: self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Update"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Update"), css_class="btn btn-primary"), ), ) else: self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Add"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Add"), css_class="btn btn-primary"), ), ) diff --git a/app/apps/export_app/forms.py b/app/apps/export_app/forms.py index 3100c2b..1f7d6ed 100644 --- a/app/apps/export_app/forms.py +++ b/app/apps/export_app/forms.py @@ -1,11 +1,10 @@ +from apps.common.widgets.crispy.submit import NoClassSubmit from crispy_forms.bootstrap import FormActions from crispy_forms.helper import FormHelper -from crispy_forms.layout import Layout, HTML +from crispy_forms.layout import HTML, Layout from django import forms from django.utils.translation import gettext_lazy as _ -from apps.common.widgets.crispy.submit import NoClassSubmit - class ExportForm(forms.Form): users = forms.BooleanField( @@ -115,9 +114,7 @@ class ExportForm(forms.Form): "dca", "import_profiles", FormActions( - NoClassSubmit( - "submit", _("Export"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Export"), css_class="btn btn-primary"), ), ) @@ -181,9 +178,7 @@ class RestoreForm(forms.Form): "dca_entries", "import_profiles", FormActions( - NoClassSubmit( - "submit", _("Restore"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Restore"), css_class="btn btn-primary"), ), ) diff --git a/app/apps/import_app/forms.py b/app/apps/import_app/forms.py index 83eb6c4..0b60165 100644 --- a/app/apps/import_app/forms.py +++ b/app/apps/import_app/forms.py @@ -1,3 +1,5 @@ +from apps.common.widgets.crispy.submit import NoClassSubmit +from apps.import_app.models import ImportProfile from crispy_forms.bootstrap import FormActions from crispy_forms.helper import FormHelper from crispy_forms.layout import ( @@ -6,9 +8,6 @@ from crispy_forms.layout import ( from django import forms from django.utils.translation import gettext_lazy as _ -from apps.import_app.models import ImportProfile -from apps.common.widgets.crispy.submit import NoClassSubmit - class ImportProfileForm(forms.ModelForm): class Meta: @@ -30,17 +29,13 @@ class ImportProfileForm(forms.ModelForm): if self.instance and self.instance.pk: self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Update"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Update"), css_class="btn btn-primary"), ), ) else: self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Add"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Add"), css_class="btn btn-primary"), ), ) @@ -57,8 +52,6 @@ class ImportRunFileUploadForm(forms.Form): self.helper.layout = Layout( "file", FormActions( - NoClassSubmit( - "submit", _("Import"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Import"), css_class="btn btn-primary"), ), ) diff --git a/app/apps/rules/forms.py b/app/apps/rules/forms.py index 7bfa40c..a12da0f 100644 --- a/app/apps/rules/forms.py +++ b/app/apps/rules/forms.py @@ -1,4 +1,5 @@ from apps.common.fields.forms.dynamic_select import DynamicModelChoiceField +from apps.common.widgets.crispy.daisyui import Switch from apps.common.widgets.crispy.submit import NoClassSubmit from apps.common.widgets.tom_select import TomSelect, TransactionSelect from apps.rules.models import ( @@ -8,7 +9,7 @@ from apps.rules.models import ( ) from apps.transactions.forms import BulkEditTransactionForm from apps.transactions.models import Transaction -from crispy_bootstrap5.bootstrap5 import BS5Accordion, Switch +from crispy_bootstrap5.bootstrap5 import BS5Accordion from crispy_forms.bootstrap import AccordionGroup, FormActions from crispy_forms.helper import FormHelper from crispy_forms.layout import HTML, Column, Field, Layout, Row @@ -54,17 +55,13 @@ class TransactionRuleForm(forms.ModelForm): if self.instance and self.instance.pk: self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Update"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Update"), css_class="btn btn-primary"), ), ) else: self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Add"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Add"), css_class="btn btn-primary"), ), ) @@ -98,17 +95,13 @@ class TransactionRuleActionForm(forms.ModelForm): if self.instance and self.instance.pk: self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Update"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Update"), css_class="btn btn-primary"), ), ) else: self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Add"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Add"), css_class="btn btn-primary"), ), ) @@ -222,7 +215,7 @@ class UpdateOrCreateTransactionRuleActionForm(forms.ModelForm): Row( Column( Field("search_type_operator"), - css_class="md:col-span-4", + css_class="col-span-12 md:col-span-4", ), Column( Field("search_type", rows=1), @@ -232,7 +225,7 @@ class UpdateOrCreateTransactionRuleActionForm(forms.ModelForm): Row( Column( Field("search_is_paid_operator"), - css_class="md:col-span-4", + css_class="col-span-12 md:col-span-4", ), Column( Field("search_is_paid", rows=1), @@ -242,7 +235,7 @@ class UpdateOrCreateTransactionRuleActionForm(forms.ModelForm): Row( Column( Field("search_mute_operator"), - css_class="md:col-span-4", + css_class="col-span-12 md:col-span-4", ), Column( Field("search_mute", rows=1), @@ -252,7 +245,7 @@ class UpdateOrCreateTransactionRuleActionForm(forms.ModelForm): Row( Column( Field("search_account_operator"), - css_class="md:col-span-4", + css_class="col-span-12 md:col-span-4", ), Column( Field("search_account", rows=1), @@ -262,7 +255,7 @@ class UpdateOrCreateTransactionRuleActionForm(forms.ModelForm): Row( Column( Field("search_entities_operator"), - css_class="md:col-span-4", + css_class="col-span-12 md:col-span-4", ), Column( Field("search_entities", rows=1), @@ -272,91 +265,91 @@ class UpdateOrCreateTransactionRuleActionForm(forms.ModelForm): Row( Column( Field("search_date_operator"), - css_class="md:col-span-4", + css_class="col-span-12 md:col-span-4", ), Column( Field("search_date", rows=1), - css_class="form-group col-md-8", + css_class="col-span-12 md:col-span-8", ), ), Row( Column( Field("search_reference_date_operator"), - css_class="md:col-span-4", + css_class="col-span-12 md:col-span-4", ), Column( Field("search_reference_date", rows=1), - css_class="form-group col-md-8", + css_class="col-span-12 md:col-span-8", ), ), Row( Column( Field("search_description_operator"), - css_class="md:col-span-4", + css_class="col-span-12 md:col-span-4", ), Column( Field("search_description", rows=1), - css_class="form-group col-md-8", + css_class="col-span-12 md:col-span-8", ), ), Row( Column( Field("search_amount_operator"), - css_class="md:col-span-4", + css_class="col-span-12 md:col-span-4", ), Column( Field("search_amount", rows=1), - css_class="form-group col-md-8", + css_class="col-span-12 md:col-span-8", ), ), Row( Column( Field("search_category_operator"), - css_class="md:col-span-4", + css_class="col-span-12 md:col-span-4", ), Column( Field("search_category", rows=1), - css_class="form-group col-md-8", + css_class="col-span-12 md:col-span-8", ), ), Row( Column( Field("search_tags_operator"), - css_class="md:col-span-4", + css_class="col-span-12 md:col-span-4", ), Column( Field("search_tags", rows=1), - css_class="form-group col-md-8", + css_class="col-span-12 md:col-span-8", ), ), Row( Column( Field("search_notes_operator"), - css_class="md:col-span-4", + css_class="col-span-12 md:col-span-4", ), Column( Field("search_notes", rows=1), - css_class="form-group col-md-8", + css_class="col-span-12 md:col-span-8", ), ), Row( Column( Field("search_internal_note_operator"), - css_class="md:col-span-4", + css_class="col-span-12 md:col-span-4", ), Column( Field("search_internal_note", rows=1), - css_class="form-group col-md-8", + css_class="col-span-12 md:col-span-8", ), ), Row( Column( Field("search_internal_id_operator"), - css_class="md:col-span-4", + css_class="col-span-12 md:col-span-4", ), Column( Field("search_internal_id", rows=1), - css_class="form-group col-md-8", + css_class="col-span-12 md:col-span-8", ), ), active=True, @@ -387,17 +380,13 @@ class UpdateOrCreateTransactionRuleActionForm(forms.ModelForm): if self.instance and self.instance.pk: self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Update"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Update"), css_class="btn btn-primary"), ), ) else: self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Add"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Add"), css_class="btn btn-primary"), ), ) @@ -428,9 +417,7 @@ class DryRunCreatedTransacion(forms.Form): self.helper.layout = Layout( "transaction", FormActions( - NoClassSubmit( - "submit", _("Test"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Test"), css_class="btn btn-primary"), ), ) @@ -465,9 +452,7 @@ class DryRunDeletedTransacion(forms.Form): self.helper.layout = Layout( "transaction", FormActions( - NoClassSubmit( - "submit", _("Test"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Test"), css_class="btn btn-primary"), ), ) @@ -501,9 +486,7 @@ class DryRunUpdatedTransactionForm(BulkEditTransactionForm): # Change submit button self.helper.layout[-1] = FormActions( - NoClassSubmit( - "submit", _("Test"), css_class="btn btn-outline-primary w-100" - ) + NoClassSubmit("submit", _("Test"), css_class="btn btn-primary") ) if self.data.get("transaction"): diff --git a/app/apps/transactions/filters.py b/app/apps/transactions/filters.py index e28f4af..25e8329 100644 --- a/app/apps/transactions/filters.py +++ b/app/apps/transactions/filters.py @@ -160,12 +160,10 @@ class TransactionsFilter(django_filters.FilterSet): Row( Column("reference_date_start"), Column("reference_date_end"), - css_class="form-row", ), Row( Column("from_amount"), Column("to_amount"), - css_class="form-row", ), Field("account", size=1), Field("currency", size=1), diff --git a/app/apps/transactions/forms.py b/app/apps/transactions/forms.py index f240594..d9c3bff 100644 --- a/app/apps/transactions/forms.py +++ b/app/apps/transactions/forms.py @@ -5,6 +5,7 @@ from apps.common.fields.forms.dynamic_select import ( DynamicModelChoiceField, DynamicModelMultipleChoiceField, ) +from apps.common.widgets.crispy.daisyui import Switch from apps.common.widgets.crispy.submit import NoClassSubmit from apps.common.widgets.datepicker import AirDatePickerInput, AirMonthYearPickerInput from apps.common.widgets.decimal import ArbitraryDecimalDisplayNumberInput @@ -19,7 +20,7 @@ from apps.transactions.models import ( TransactionEntity, TransactionTag, ) -from crispy_bootstrap5.bootstrap5 import BS5Accordion, Switch +from crispy_bootstrap5.bootstrap5 import BS5Accordion from crispy_forms.bootstrap import AccordionGroup, AppendedText, FormActions from crispy_forms.helper import FormHelper from crispy_forms.layout import ( @@ -135,19 +136,16 @@ class TransactionForm(forms.ModelForm): Row( Column("account"), Column("entities"), - css_class="form-row", ), Row( Column(Field("date")), Column(Field("reference_date")), - css_class="form-row", ), "description", Field("amount", inputmode="decimal"), Row( Column("category"), Column("tags"), - css_class="form-row", ), "notes", ) @@ -165,7 +163,6 @@ class TransactionForm(forms.ModelForm): Row( Column(Field("date")), Column(Field("reference_date")), - css_class="form-row", ), "description", Field("amount", inputmode="decimal"), @@ -176,7 +173,6 @@ class TransactionForm(forms.ModelForm): Row( Column("category"), Column("tags"), - css_class="form-row", ), "notes", active=False, @@ -186,9 +182,7 @@ class TransactionForm(forms.ModelForm): css_class="mb-3", ), FormActions( - NoClassSubmit( - "submit", _("Add"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Add"), css_class="btn btn-primary"), ), ) @@ -201,29 +195,25 @@ class TransactionForm(forms.ModelForm): ) self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Update"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Update"), css_class="btn btn-primary"), ), ) else: self.fields["amount"].widget = ArbitraryDecimalDisplayNumberInput() self.helper.layout.append( Div( - NoClassSubmit( - "submit", _("Add"), css_class="btn btn-outline-primary" - ), + NoClassSubmit("submit", _("Add"), css_class="btn btn-primary"), NoClassSubmit( "submit_and_similar", _("Save and add similar"), - css_class="btn btn-outline-primary", + css_class="btn btn-primary btn-soft", ), NoClassSubmit( "submit_and_another", _("Save and add another"), - css_class="btn btn-outline-primary", + css_class="btn btn-primary btn-soft", ), - css_class="d-grid gap-2", + css_class="flex flex-col gap-2 mt-3", ), ) @@ -351,14 +341,12 @@ class QuickTransactionForm(forms.ModelForm): Row( Column("account"), Column("entities"), - css_class="form-row", ), "description", Field("amount", inputmode="decimal"), Row( Column("category"), Column("tags"), - css_class="form-row", ), "notes", Switch("mute"), @@ -371,9 +359,7 @@ class QuickTransactionForm(forms.ModelForm): ) self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Update"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Update"), css_class="btn btn-primary"), ), ) else: @@ -482,25 +468,20 @@ class BulkEditTransactionForm(forms.Form): Row( Column("account"), Column("entities"), - css_class="form-row", ), Row( Column(Field("date")), Column(Field("reference_date")), - css_class="form-row", ), "description", Field("amount", inputmode="decimal"), Row( Column("category"), Column("tags"), - css_class="form-row", ), "notes", FormActions( - NoClassSubmit( - "submit", _("Update"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Update"), css_class="btn btn-primary"), ), ) @@ -612,7 +593,7 @@ class TransferForm(forms.Form): Column(Field("from_amount")), Column("from_category"), Column("from_tags"), - css_class="bg-base-200 rounded-box p-4 border-base-content/60 border mb-3", + css_class="bg-base-100 rounded-box p-4 border-base-content/60 border my-3", ), Row( Column( @@ -623,12 +604,10 @@ class TransferForm(forms.Form): ), Column("to_category"), Column("to_tags"), - css_class="bg-base-200 rounded-box p-4 border-base-content/60 border mb-3", + css_class="bg-base-100 rounded-box p-4 border-base-content/60 border", ), FormActions( - NoClassSubmit( - "submit", _("Transfer"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Transfer"), css_class="btn btn-primary"), ), ) @@ -816,7 +795,6 @@ class InstallmentPlanForm(forms.ModelForm): Row( Column("account"), Column("entities"), - css_class="form-row", ), "description", Switch("add_description_to_transaction"), @@ -825,19 +803,16 @@ class InstallmentPlanForm(forms.ModelForm): Row( Column("number_of_installments"), Column("installment_start"), - css_class="form-row", ), Row( - Column("start_date", css_class="md:col-span-4 mb-0"), - Column("reference_date", css_class="md:col-span-4 mb-0"), - Column("recurrence", css_class="md:col-span-4 mb-0"), - css_class="form-row", + Column("start_date", css_class="col-span-12 md:col-span-4"), + Column("reference_date", css_class="col-span-12 md:col-span-4"), + Column("recurrence", css_class="col-span-12 md:col-span-4"), ), "installment_amount", Row( Column("category"), Column("tags"), - css_class="form-row", ), ) @@ -847,17 +822,13 @@ class InstallmentPlanForm(forms.ModelForm): if self.instance and self.instance.pk: self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Update"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Update"), css_class="btn btn-primary"), ), ) else: self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Add"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Add"), css_class="btn btn-primary"), ), ) @@ -890,17 +861,13 @@ class TransactionTagForm(forms.ModelForm): if self.instance and self.instance.pk: self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Update"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Update"), css_class="btn btn-primary"), ), ) else: self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Add"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Add"), css_class="btn btn-primary"), ), ) @@ -922,17 +889,13 @@ class TransactionEntityForm(forms.ModelForm): if self.instance and self.instance.pk: self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Update"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Update"), css_class="btn btn-primary"), ), ) else: self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Add"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Add"), css_class="btn btn-primary"), ), ) @@ -957,17 +920,13 @@ class TransactionCategoryForm(forms.ModelForm): if self.instance and self.instance.pk: self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Update"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Update"), css_class="btn btn-primary"), ), ) else: self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Add"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Add"), css_class="btn btn-primary"), ), ) @@ -1078,7 +1037,6 @@ class RecurringTransactionForm(forms.ModelForm): Row( Column("account"), Column("entities"), - css_class="form-row", ), "description", Switch("add_description_to_transaction"), @@ -1086,20 +1044,17 @@ class RecurringTransactionForm(forms.ModelForm): Row( Column("category"), Column("tags"), - css_class="form-row", ), "notes", Switch("add_notes_to_transaction"), Row( Column("start_date"), Column("reference_date"), - css_class="form-row", ), Row( - Column("recurrence_interval", css_class="md:col-span-4 mb-0"), - Column("recurrence_type", css_class="md:col-span-4 mb-0"), - Column("end_date", css_class="md:col-span-4 mb-0"), - css_class="form-row", + Column("recurrence_interval", css_class="col-span-12 md:col-span-4"), + Column("recurrence_type", css_class="col-span-12 md:col-span-4"), + Column("end_date", css_class="col-span-12 md:col-span-4"), ), AppendedText("keep_at_most", _("future transactions")), ) @@ -1111,17 +1066,13 @@ class RecurringTransactionForm(forms.ModelForm): if self.instance and self.instance.pk: self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Update"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Update"), css_class="btn btn-primary"), ), ) else: self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Add"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Add"), css_class="btn btn-primary"), ), ) diff --git a/app/apps/users/forms.py b/app/apps/users/forms.py index bb3aec6..5d12917 100644 --- a/app/apps/users/forms.py +++ b/app/apps/users/forms.py @@ -146,9 +146,7 @@ class UserSettingsForm(forms.ModelForm): HTML("
"), "volume", FormActions( - NoClassSubmit( - "submit", _("Save"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Save"), css_class="btn btn-primary"), ), ) @@ -221,17 +219,13 @@ class UserUpdateForm(forms.ModelForm): if self.instance and self.instance.pk: self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Update"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Update"), css_class="btn btn-primary"), ), ) else: self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Add"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Add"), css_class="btn btn-primary"), ), ) @@ -383,17 +377,13 @@ class UserAddForm(UserCreationForm): if self.instance and self.instance.pk: self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Update"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Update"), css_class="btn btn-primary"), ), ) else: self.helper.layout.append( FormActions( - NoClassSubmit( - "submit", _("Add"), css_class="btn btn-outline-primary w-100" - ), + NoClassSubmit("submit", _("Add"), css_class="btn btn-primary"), ), ) diff --git a/app/apps/users/urls.py b/app/apps/users/urls.py index 6576bb8..b98c743 100644 --- a/app/apps/users/urls.py +++ b/app/apps/users/urls.py @@ -18,10 +18,15 @@ urlpatterns = [ name="toggle_sound_playing", ), path( - "user/toggle-sidebar/", + "user/session/toggle-sidebar/", views.toggle_sidebar_status, name="toggle_sidebar_status", ), + path( + "user/session/toggle-theme/", + views.toggle_theme, + name="toggle_theme", + ), path( "user/settings/", views.update_settings, diff --git a/app/apps/users/views.py b/app/apps/users/views.py index f8f0ef9..a8c7580 100644 --- a/app/apps/users/views.py +++ b/app/apps/users/views.py @@ -1,27 +1,26 @@ +from apps.common.decorators.demo import disabled_on_demo +from apps.common.decorators.htmx import only_htmx +from apps.common.decorators.user import htmx_login_required, is_superuser +from apps.users.forms import ( + LoginForm, + UserAddForm, + UserSettingsForm, + UserUpdateForm, +) +from apps.users.models import UserSettings from django.contrib import messages -from django.contrib.auth import logout, get_user_model +from django.contrib.auth import get_user_model, logout from django.contrib.auth.decorators import login_required from django.contrib.auth.views import ( LoginView, ) from django.core.exceptions import PermissionDenied from django.http import HttpResponse -from django.shortcuts import redirect, render, get_object_or_404 +from django.shortcuts import get_object_or_404, redirect, render from django.urls import reverse from django.utils.translation import gettext_lazy as _ from django.views.decorators.http import require_http_methods -from apps.common.decorators.htmx import only_htmx -from apps.common.decorators.user import is_superuser, htmx_login_required -from apps.users.forms import ( - LoginForm, - UserSettingsForm, - UserUpdateForm, - UserAddForm, -) -from apps.users.models import UserSettings -from apps.common.decorators.demo import disabled_on_demo - def logout_view(request): logout(request) @@ -118,6 +117,7 @@ def update_settings(request): @only_htmx @htmx_login_required +@require_http_methods(["GET"]) def toggle_sidebar_status(request): if not request.session.get("sidebar_status"): request.session["sidebar_status"] = "floating" @@ -134,6 +134,24 @@ def toggle_sidebar_status(request): ) +@htmx_login_required +@require_http_methods(["GET"]) +def toggle_theme(request): + if not request.session.get("theme"): + request.session["theme"] = "wygiwyh_dark" + + if request.session["theme"] == "wygiwyh_dark": + request.session["theme"] = "wygiwyh_light" + elif request.session["theme"] == "wygiwyh_light": + request.session["theme"] = "wygiwyh_dark" + else: + request.session["theme"] = "wygiwyh_dark" + + return HttpResponse( + status=204, + ) + + @htmx_login_required @is_superuser @require_http_methods(["GET"]) diff --git a/app/static/img/logo-icon.svg b/app/static/img/logo-icon.svg index cb9a674..708605a 100644 --- a/app/static/img/logo-icon.svg +++ b/app/static/img/logo-icon.svg @@ -1 +1,3 @@ - \ No newline at end of file + + + \ No newline at end of file diff --git a/app/templates/accounts/fragments/account_reconciliation.html b/app/templates/accounts/fragments/account_reconciliation.html index 77ffad8..094fff7 100644 --- a/app/templates/accounts/fragments/account_reconciliation.html +++ b/app/templates/accounts/fragments/account_reconciliation.html @@ -11,17 +11,23 @@ {{ form.management_form }}
{% for form in form.forms %} -
- - {% if form.account_group %}{{ form.account_group.name }}{% endif %}{{ form.account_name }} - -
+
+ +
+ {% if form.account_group %}{{ form.account_group.name }}{% endif %}{{ form.account_name }} +
+
{% translate 'Current balance' %}
- {% currency_display amount=form.current_balance prefix=form.currency_prefix suffix=form.currency_suffix decimal_places=form.currency_decimal_places %} +
@@ -52,7 +58,7 @@ put '-' into me">-
-
+
{% endfor %}
diff --git a/app/templates/common/placeholder.html b/app/templates/common/placeholder.html index a375b34..5fbca30 100644 --- a/app/templates/common/placeholder.html +++ b/app/templates/common/placeholder.html @@ -14,6 +14,7 @@
+
diff --git a/app/templates/cotton/amount/display.html b/app/templates/cotton/amount/display.html index 9def514..5c1f1c3 100644 --- a/app/templates/cotton/amount/display.html +++ b/app/templates/cotton/amount/display.html @@ -5,7 +5,15 @@ {% if not divless %}
{% endif %} - 0 %} text-income + {% elif amount < 0 %} text-expense + {% else %} text-base-content {% endif %} + {% endif %} + font-medium {{ custom_class }}" data-original-sign="{{ formatted_amount.sign }}" data-original-prefix="{{ formatted_amount.prefix }}" data-original-amount="{{ formatted_amount.amount }}" diff --git a/app/templates/cotton/components/sidebar_menu_header.html b/app/templates/cotton/components/sidebar_menu_header.html index 4212855..55c8f93 100644 --- a/app/templates/cotton/components/sidebar_menu_header.html +++ b/app/templates/cotton/components/sidebar_menu_header.html @@ -1,6 +1,6 @@
  • -
    - {{ title }} +
    + {{ title }}
  • diff --git a/app/templates/cotton/components/sidebar_menu_item.html b/app/templates/cotton/components/sidebar_menu_item.html index 9dfa842..2f78d50 100644 --- a/app/templates/cotton/components/sidebar_menu_item.html +++ b/app/templates/cotton/components/sidebar_menu_item.html @@ -1,7 +1,7 @@ {% load active_link %}
  • 0
  • -
    diff --git a/app/templates/crispy-daisyui/layout/formactions.html b/app/templates/crispy-daisyui/layout/formactions.html index 172a7a4..e79b437 100644 --- a/app/templates/crispy-daisyui/layout/formactions.html +++ b/app/templates/crispy-daisyui/layout/formactions.html @@ -1,11 +1,10 @@
    {% if label_class %}
    {% endif %} -
    - {{ fields_output|safe }} -
    + + {{ fields_output|safe }}
    diff --git a/app/templates/crispy-daisyui/layout/help_text.html b/app/templates/crispy-daisyui/layout/help_text.html index 6e6dddb..f5acf6a 100644 --- a/app/templates/crispy-daisyui/layout/help_text.html +++ b/app/templates/crispy-daisyui/layout/help_text.html @@ -1,7 +1,7 @@ {% if field.help_text %} {% if help_text_inline %} - {{ field.help_text|safe}} + {{ field.help_text|safe}} {% else %} -
    {{ field.help_text|safe }}
    +
    {{ field.help_text|safe }}
    {% endif %} {% endif %} diff --git a/app/templates/crispy-daisyui/layout/prepended_appended_text.html b/app/templates/crispy-daisyui/layout/prepended_appended_text.html index a95481f..d0d72d3 100644 --- a/app/templates/crispy-daisyui/layout/prepended_appended_text.html +++ b/app/templates/crispy-daisyui/layout/prepended_appended_text.html @@ -5,46 +5,48 @@ {% else %}
    - {% if field.label and form_show_labels %} - - {% endif %} +
    + {% if field.label and form_show_labels %} + + {{ field.label }}{% if field.field.required %}*{% endif %} + + {% endif %} -
    -
    + + {# help text as label paragraph #} + {% if not help_text_inline %} + {% include 'crispy-daisyui/layout/help_text.html' %} + {% endif %} + + {# errors #} + {% if error_text_inline %} + {% include 'crispy-daisyui/layout/field_errors.html' %} + {% else %} + {% include 'crispy-daisyui/layout/field_errors_block.html' %} + {% endif %} +
    {% endif %} diff --git a/app/templates/crispy-daisyui/layout/row.html b/app/templates/crispy-daisyui/layout/row.html index 1333ce8..b9429a8 100644 --- a/app/templates/crispy-daisyui/layout/row.html +++ b/app/templates/crispy-daisyui/layout/row.html @@ -1,3 +1,3 @@ -
    +
    {{ fields|safe }}
    diff --git a/app/templates/crispy-daisyui/layout/switch.html b/app/templates/crispy-daisyui/layout/switch.html index eb7da8b..9e3c5ff 100644 --- a/app/templates/crispy-daisyui/layout/switch.html +++ b/app/templates/crispy-daisyui/layout/switch.html @@ -3,15 +3,19 @@ {% if field.is_hidden %} {{ field }} {% else %} - <{% if tag %}{{ tag }}{% else %}div{% endif %} id="div_{{ field.auto_id }}" class="form-control{% if wrapper_class %} {{ wrapper_class }}{% endif %}{% if field.css_classes %} {{ field.css_classes }}{% endif %}"> -
    +
    {% block title %}{% endblock %}
    diff --git a/app/templates/includes/mobile_navbar.html b/app/templates/includes/mobile_navbar.html index 3627f1b..9b1c207 100644 --- a/app/templates/includes/mobile_navbar.html +++ b/app/templates/includes/mobile_navbar.html @@ -3,10 +3,10 @@ {% load static %} {% load i18n %} {% load active_link %} -
    {% endif %} - {# Floating bar#} - -
    diff --git a/app/templates/transactions/fragments/summary.html b/app/templates/transactions/fragments/summary.html index 34bd883..59515b7 100644 --- a/app/templates/transactions/fragments/summary.html +++ b/app/templates/transactions/fragments/summary.html @@ -1,47 +1,30 @@ {% load tools %} {% load i18n %} {% load currency_display %} - -
    -
    -
    - {% for currency_id, currency in currency_data.items %} -
    - -
    - {% empty %} -
    - - {% endfor %} -
    +
    + {% for currency_id, currency in currency_data.items %} +
    +
    -
    -
    -
    - {% for account_id, account in account_data.items %} -
    - -
    - {% empty %} -
    - - {% endfor %} -
    + {% empty %} +
    +
    + {% endfor %} +
    + +
    + {% for account_id, account in account_data.items %} +
    + +
    + {% empty %} +
    + + {% endfor %}
    diff --git a/app/templates/transactions/pages/transactions.html b/app/templates/transactions/pages/transactions.html index 717d914..df1fd32 100644 --- a/app/templates/transactions/pages/transactions.html +++ b/app/templates/transactions/pages/transactions.html @@ -5,12 +5,45 @@ {% block title %}{% translate 'Transactions' %}{% endblock %} {% block content %} -
    -
    -
    -
    +
    +
    +
    +
    + +
    +
    +
    +
    + + +
    +
    +
    +
    +
    + +
    +
    + +
    {# Hidden select to hold the order value and preserve the original update trigger #} - @@ -19,7 +52,7 @@ {# Main control bar with filter, search, and ordering #}
    - {# Search box #} -
    {# Filter transactions form #} -
    -
    -
    +
    +
    +
    @@ -98,46 +130,20 @@ {% crispy filter.form %} -
    +
    + {# Transactions list#}
    -
    -
    - -
    -
    -
    -
    - - -
    -
    -
    -
    -
    -
    diff --git a/frontend/src/js/_htmx.js b/frontend/src/js/_htmx.js index 63ad684..2094246 100644 --- a/frontend/src/js/_htmx.js +++ b/frontend/src/js/_htmx.js @@ -38,7 +38,7 @@ htmx.defineExtension('htmx-download', { const mimetype = headers['content-type'] || 'application/octet-stream'; // Create Blob - const blob = new Blob([xhr.response], {type: mimetype}); + const blob = new Blob([xhr.response], { type: mimetype }); const url = URL.createObjectURL(blob); // Trigger download diff --git a/frontend/src/js/_tooltip.js b/frontend/src/js/_tooltip.js index 0451725..2c9ebf3 100644 --- a/frontend/src/js/_tooltip.js +++ b/frontend/src/js/_tooltip.js @@ -14,7 +14,8 @@ function initiateTooltips() { } tippy('[data-tippy-content]', { - theme: theme + theme: theme, + zIndex: 1050, }); } diff --git a/frontend/src/styles/_offcanvas.scss b/frontend/src/styles/_offcanvas.scss index 88fe9ce..1f0b772 100644 --- a/frontend/src/styles/_offcanvas.scss +++ b/frontend/src/styles/_offcanvas.scss @@ -5,7 +5,7 @@ @use "sass:map"; // Variables -$offcanvas-z-index: 1045 !default; +$offcanvas-z-index: 1090 !default; $offcanvas-backdrop-z-index: 1040 !default; $offcanvas-width: 400px !default; $offcanvas-height: 30vh !default; @@ -67,8 +67,8 @@ $breakpoints: ( --offcanvas-padding-y: #{$offcanvas-padding}; --offcanvas-color: var(--color-base-content); --offcanvas-bg: var(--color-base-300); - --offcanvas-border-width: 1px; - --offcanvas-border-color: var(--color-base-300); + --offcanvas-border-width: var(--border); + --offcanvas-border-color: var(--color-base-100); --offcanvas-box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075); --offcanvas-transition: transform #{$offcanvas-transition-duration} ease-in-out; --offcanvas-title-line-height: 1.5; diff --git a/frontend/src/styles/_transitions.scss b/frontend/src/styles/_transitions.scss index ca57dbc..307ba92 100644 --- a/frontend/src/styles/_transitions.scss +++ b/frontend/src/styles/_transitions.scss @@ -24,14 +24,14 @@ $transition-collapse-width: width 0.35s ease !default; } } -// Collapse transitions -.collapse { +// // Collapse transitions +.bs.collapse { &:not(.show) { display: none; } } -.collapsing { +.bs.collapsing { height: 0; overflow: hidden; transition: $transition-collapse; diff --git a/frontend/src/styles/style.scss b/frontend/src/styles/style.scss index 9e23c0b..c0a5a97 100644 --- a/frontend/src/styles/style.scss +++ b/frontend/src/styles/style.scss @@ -78,4 +78,30 @@ select { div:where(.swal2-container) { z-index: 1100 !important; +} + +.logo { + /* Set the background-color to DaisyUI CSS variable */ + background-color: var(--color-primary); + + /* Use SVG file as the mask */ + mask-image: url('/static/img/logo-icon.svg'); + -webkit-mask-image: url('/static/img/logo-icon.svg'); + + /* Set mask properties to size it correctly */ + mask-size: contain; + -webkit-mask-size: contain; + mask-repeat: no-repeat; + -webkit-mask-repeat: no-repeat; + mask-position: center; + -webkit-mask-position: center; + + /* Give the element a size */ + width: 30px; + height: 30px; + + &.mobile { + width: 40px; + height: 40px; + } } \ No newline at end of file diff --git a/frontend/src/styles/tailwind.css b/frontend/src/styles/tailwind.css index ce1599f..51a3ea9 100644 --- a/frontend/src/styles/tailwind.css +++ b/frontend/src/styles/tailwind.css @@ -96,7 +96,7 @@ background-color: oklch(from var(--color-primary) l c h / 15%); } - + .bg-root { background-color: var(--root-bg) !important; } @@ -208,22 +208,9 @@ @apply lg:ml-16 transition-all duration-100; } - .sidebar-floating .sidebar-item { - /* Maintains consistent height when collapsed */ - @apply lg:min-h-[2.3rem]; - } - - .sidebar-floating .sidebar-item i { - /* Centers icon when collapsed by adding auto margins */ - @apply lg:mx-auto lg:group-hover:mx-0; - } - - .sidebar-floating .sidebar-item span, - .sidebar-floating .sidebar-item i:not(:first-child) { + .sidebar-floating .sidebar-item span { /* Hides the text labels and reveals them only on hover */ @apply lg:invisible lg:group-hover:visible; - /* Position absolute to remove from layout when invisible */ - @apply lg:absolute lg:group-hover:static; } .htmx-swapping .sidebar-floating, @@ -280,8 +267,6 @@ @apply text-wrap lg:text-nowrap ; } - - /* --- STATE 2: Fixed (Permanently Expanded) --- */ .sidebar-fixed { /* Sets the fixed, expanded width for the container */ @apply lg:w-[17%] transition-all duration-100;