feat: more changes and fixes

This commit is contained in:
Herculino Trotta
2025-11-08 14:06:01 -03:00
parent a878af28f1
commit cd54df6f2d
45 changed files with 412 additions and 476 deletions

View File

@@ -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"),
)

View File

@@ -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("<hr>"),
Field("shared_with_users"),
FormActions(
NoClassSubmit(
"submit", _("Save"), css_class="btn btn-outline-primary w-100"
),
NoClassSubmit("submit", _("Save"), css_class="btn btn-primary"),
),
)

View File

@@ -0,0 +1,5 @@
from crispy_forms.layout import Field
class Switch(Field):
template = "crispy-daisyui/layout/switch.html"

View File

@@ -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"),
),
)

View File

@@ -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"),
),
)

View File

@@ -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"),
),
)

View File

@@ -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"),
),
)

View File

@@ -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"):

View File

@@ -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),

View File

@@ -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"),
),
)

View File

@@ -146,9 +146,7 @@ class UserSettingsForm(forms.ModelForm):
HTML("<hr />"),
"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"),
),
)

View File

@@ -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,

View File

@@ -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"])

View File

@@ -1 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="500" zoomAndPan="magnify" viewBox="0 0 375 374.999991" height="500" preserveAspectRatio="xMidYMid meet" version="1.0"><defs><clipPath id="a2373d79ec"><path d="M 1.980469 1.980469 L 373 1.980469 L 373 373 L 1.980469 373 Z M 1.980469 1.980469 " clip-rule="nonzero"/></clipPath></defs><g clip-path="url(#a2373d79ec)"><path fill="#fbb700" d="M 239.671875 301.757812 L 79.152344 141.238281 L 118.234375 102.152344 L 239.671875 223.589844 L 355.179688 108.078125 C 325.429688 45.34375 261.519531 1.957031 187.472656 1.957031 C 113.375 1.957031 49.433594 45.410156 19.707031 108.210938 L 174.503906 263.003906 L 135.757812 301.757812 L 2.882812 168.878906 C 2.273438 174.996094 1.957031 181.199219 1.957031 187.472656 C 1.957031 289.929688 85.015625 372.988281 187.472656 372.988281 C 289.929688 372.988281 372.988281 289.929688 372.988281 187.472656 C 372.988281 181.347656 372.679688 175.296875 372.101562 169.320312 L 239.671875 301.757812 " fill-opacity="1" fill-rule="nonzero"/></g></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 375 374.999991" version="1.0">
<path fill="#000000" d="M 239.671875 301.757812 L 79.152344 141.238281 L 118.234375 102.152344 L 239.671875 223.589844 L 355.179688 108.078125 C 325.429688 45.34375 261.519531 1.957031 187.472656 1.957031 C 113.375 1.957031 49.433594 45.410156 19.707031 108.210938 L 174.503906 263.003906 L 135.757812 301.757812 L 2.882812 168.878906 C 2.273438 174.996094 1.957031 181.199219 1.957031 187.472656 C 1.957031 289.929688 85.015625 372.988281 187.472656 372.988281 C 289.929688 372.988281 372.988281 289.929688 372.988281 187.472656 C 372.988281 181.347656 372.679688 175.296875 372.101562 169.320312 L 239.671875 301.757812 "/>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 718 B

View File

@@ -11,17 +11,23 @@
{{ form.management_form }}
<div class="space-y-2" id="balanceAccordionFlush">
{% for form in form.forms %}
<details class="collapse collapse-arrow bg-base-100 border-base-300 border overflow-visible show">
<summary class="collapse-title font-medium text-sm">
{% if form.account_group %}<span class="badge badge-primary me-2">{{ form.account_group.name }}</span>{% endif %}{{ form.account_name }}
</summary>
<div class="collapse-content">
<div class="collapse collapse-arrow bg-base-100 border-base-300 border overflow-visible">
<input type="checkbox" />
<div class="collapse-title font-medium text-sm">
{% if form.account_group %}<span class="badge badge-primary badge-outline me-2">{{ form.account_group.name }}</span>{% endif %}{{ form.account_name }}
</div>
<div class="collapse-content bg-base-200">
<div class="fieldset">
<span class="fieldset-legend">{% translate 'Current balance' %}</span>
<div data-amount="{{ form.current_balance|floatformat:"-40u" }}"
data-decimal-places="{{ form.currency_decimal_places }}"
id="amount-{{ forloop.counter0 }}" class="text-base">
{% currency_display amount=form.current_balance prefix=form.currency_prefix suffix=form.currency_suffix decimal_places=form.currency_decimal_places %}
<c-amount.display
:amount="form.current_balance"
:prefix="form.currency_prefix"
:suffix="form.currency_suffix"
:decimal_places="form.currency_decimal_places"
color="auto"></c-amount.display>
</div>
</div>
<div>
@@ -52,7 +58,7 @@
put '-' into me">-</div>
</div>
</div>
</details>
</div>
{% endfor %}
</div>
<div class="mt-3">

View File

@@ -14,6 +14,7 @@
<div class="md:col-span-10"></div>
<div class="md:col-span-11"></div>
<div class="md:col-span-12"></div>
<div class="col-span-12"></div>
<div class="alert-error"></div>
<div class="alert-info"></div>
<div class="alert-success"></div>

View File

@@ -5,7 +5,15 @@
{% if not divless %}
<div class="{% if text_end %}text-end{% elif text_start %}text-start{% endif %}">
{% endif %}
<span class="amount{% if color == 'grey' or color == "gray" %} text-exchange-rate{% elif color == 'green' %} text-income {% elif color == 'red' %} text-expense{% endif %} font-medium {{ custom_class }}"
<span class="amount
{% if color == 'grey' or color == "gray" %} text-exchange-rate
{% elif color == 'green' %} text-income {% elif color == 'red' %} text-expense
{% elif color == 'auto' %}
{% if amount > 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 }}"

View File

@@ -1,6 +1,6 @@
<li>
<div class="flex items-center min-h-[1.25rem]">
<span class="sidebar-menu-header text-base-content/60 text-sm font-bold uppercase mr-3">{{ title }}</span>
<div class="flex items-center min-h-6">
<span class="sidebar-menu-header text-base-content/60 text-xs font-bold uppercase mr-3">{{ title }}</span>
<hr class="hr grow"/>
</div>
</li>

View File

@@ -1,7 +1,7 @@
{% load active_link %}
<li>
<a href="{% url url %}"
class="lg:text-sm flex items-center no-underline p-2 rounded-box sidebar-item {% active_link views=active css_class="sidebar-active" %}"
class="lg:text-sm flex items-center no-underline ps-3 p-2 rounded-box sidebar-item {% active_link views=active css_class="sidebar-active" %}"
{% if tooltip %}
data-tippy-placement="right"
data-tippy-content="{{ tooltip }}"

View File

@@ -2,7 +2,7 @@
<li>
<a href="{{ url }}"
hx-boost="false"
class="lg:text-sm flex items-center no-underline p-2 rounded-3xl sidebar-item {% active_link views=active css_class="sidebar-active" %}"
class="lg:text-sm flex items-center no-underline ps-3 p-2 rounded-3xl sidebar-item {% active_link views=active css_class="sidebar-active" %}"
{% if tooltip %}
data-tippy-placement="right"
data-tippy-content="{{ tooltip }}"

View File

@@ -23,7 +23,7 @@
<div class="font-bold text-md ms-2" id="selected-count">0</div>
<div class="divider divider-horizontal m-0"></div>
<div class="dropdown dropdown-top dropdown-end">
<button tabindex="0" role="button" class="btn btn-secondary btn-sm" type="button">
<button tabindex="0" role="button" class="btn btn-secondary btn-soft btn-sm" type="button">
<i class="fa-regular fa-square-check fa-fw"></i>
<i class="fa-solid fa-chevron-down fa-xs"></i>
</button>
@@ -44,7 +44,7 @@
</div>
<div class="divider divider-horizontal m-0"></div>
<div class="join">
<button class="btn btn-secondary join-item btn-sm"
<button class="btn btn-secondary btn-soft join-item btn-sm"
hx-get="{% url 'transactions_bulk_edit' %}"
hx-target="#generic-offcanvas"
hx-include=".transaction"

View File

@@ -1,4 +1,4 @@
<div {% if buttonholder.css_id %}id="{{ buttonholder.css_id }}"{% endif %}
class="flex gap-2{% if buttonholder.css_class %} {{ buttonholder.css_class }}{% endif %}">
class="flex flex-col gap-2{% if buttonholder.css_class %} {{ buttonholder.css_class }}{% endif %}">
{{ fields_output|safe }}
</div>

View File

@@ -1,11 +1,10 @@
<div
{% if formactions.flat_attrs %}{{ formactions.flat_attrs }}{% endif %}
class="flex gap-2 {{ formactions.css_class|default:'' }} {{ field_class }}"
class="flex flex-col gap-2 mt-3 {{ formactions.css_class|default:'' }} {{ field_class }}"
{% if formactions.id %} id="{{ formactions.id }}"{% endif %}>
{% if label_class %}
<div class="aab {{ label_class }}"></div>
{% endif %}
<div class="{{ field_class }}">
{{ fields_output|safe }}
</div>
{{ fields_output|safe }}
</div>

View File

@@ -1,7 +1,7 @@
{% if field.help_text %}
{% if help_text_inline %}
<span id="{{ field.auto_id }}_helptext" class="text-sm text-base-content/60">{{ field.help_text|safe}}</span>
<span id="{{ field.auto_id }}_helptext" class="text-xs text-base-content/60 text-wrap">{{ field.help_text|safe}}</span>
{% else %}
<div {% if field.auto_id %}id="{{ field.auto_id }}_helptext" {% endif %}class="text-sm text-base-content/60 mt-1">{{ field.help_text|safe }}</div>
<div {% if field.auto_id %}id="{{ field.auto_id }}_helptext" {% endif %}class="text-xs text-base-content/60 mt-1 text-wrap">{{ field.help_text|safe }}</div>
{% endif %}
{% endif %}

View File

@@ -5,46 +5,48 @@
{% else %}
<div id="div_{{ field.auto_id }}" class="{% if wrapper_class %} {{ wrapper_class }}{% endif %}{% if form_group_wrapper_class %} {{ form_group_wrapper_class }}{% endif %}{% if form_show_errors and field.errors %} has-error{% endif %}{% if field.css_classes %} {{ field.css_classes }}{% endif %}">
{% if field.label and form_show_labels %}
<label for="{{ field.id_for_label }}" class="label{{ label_class }}{% if field.field.required %} requiredField{% endif %}">
<span class="label-text">{{ field.label }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %}</span>
</label>
{% endif %}
<fieldset class="fieldset{% if field_class %} {{ field_class }}{% endif %}">
{% if field.label and form_show_labels %}
<legend class="fieldset-legend{{ label_class }}{% if field.field.required %} requiredField{% endif %}">
{{ field.label }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %}
</legend>
{% endif %}
<div {% if field_class %}class="{{ field_class }}"{% endif %}>
<label class="input input-bordered flex items-center gap-2{% if input_size %} {{ input_size }}{% endif %}{% if field.errors %} input-error{% endif %}">
<label class="input w-full {% if input_size %} {{ input_size }}{% endif %}{% if field.errors %} input-error{% endif %}">
{# prepend #}
{% if crispy_prepended_text %}
<span>{{ crispy_prepended_text }}</span>
{{ crispy_prepended_text }}
{% endif %}
{# input #}
{% if field|is_select %}
{% if field.errors %}
{% crispy_field field 'class' 'select-error' %}
{% crispy_field field 'class' 'select-error grow' %}
{% else %}
{% crispy_field field 'class' '' %}
{% crispy_field field 'class' 'grow' %}
{% endif %}
{% elif field.errors %}
{% crispy_field field 'class' 'grow' %}
{% else %}
{% crispy_field field 'class' 'grow' %}
{% endif %}
{# append #}
{% if crispy_appended_text %}
<span>{{ crispy_appended_text }}</span>
{{ crispy_appended_text }}
{% endif %}
</label>
{% if error_text_inline %}
{% include 'crispy-daisyui/layout/field_errors.html' %}
{% else %}
{% include 'crispy-daisyui/layout/field_errors_block.html' %}
{% endif %}
{% if not help_text_inline %}
{% include 'crispy-daisyui/layout/help_text.html' %}
{% endif %}
</div>
{# 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 %}
</fieldset>
</div>
{% endif %}

View File

@@ -1,3 +1,3 @@
<div {% if div.css_id %}id="{{ div.css_id }}"{% endif %} class="grid grid-cols-12 gap-4 {{ div.css_class|default:'' }}" {{ div.flat_attrs }}>
<div {% if div.css_id %}id="{{ div.css_id }}"{% endif %} class="grid grid-cols-12 gap-x-4 {{ div.css_class|default:'' }}" {{ div.flat_attrs }}>
{{ fields|safe }}
</div>

View File

@@ -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 %}">
<label class="label cursor-pointer justify-start gap-2">
<span class="label-text">{{ field.label }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %}</span>
<{% if tag %}{{ tag }}{% else %}fieldset{% endif %} id="div_{{ field.auto_id }}" class="fieldset mt-2 {% if wrapper_class %} {{ wrapper_class }}{% endif %}{% if field.css_classes %} {{ field.css_classes }}{% endif %}">
<label class="label flex flex-row gap-3">
<div>
{% if field.errors %}
{% crispy_field field 'class' 'toggle toggle-error' 'role' 'switch' %}
{% crispy_field field 'class' 'toggle toggle-error toggle-sm' %}
{% else %}
{% crispy_field field 'class' 'toggle' 'role' 'switch' %}
{% crispy_field field 'class' 'toggle toggle-sm' %}
{% endif %}
</div>
<div>
{{ field.label }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %}
{% include 'crispy-daisyui/layout/help_text_and_errors.html' %}
</div>
</label>
{% include 'crispy-daisyui/layout/help_text_and_errors.html' %}
</{% if tag %}{{ tag }}{% else %}div{% endif %}>
</{% if tag %}{{ tag }}{% else %}fieldset{% endif %}>
{% endif %}

View File

@@ -1,5 +1,5 @@
{% load i18n %}
<div class="offcanvas-header flex justify-between items-center">
<div class="offcanvas-header flex justify-between items-center border-b border-base-content/10">
<h5 class="offcanvas-title font-medium text-xl">{% block title %}{% endblock %}</h5>
<button type="button" class="btn btn-ghost btn-sm btn-circle" aria-label="{% trans 'Close' %}" data-bs-dismiss="offcanvas"><i class="fa-solid fa-xmark"></i></button>
</div>

View File

@@ -3,10 +3,10 @@
{% load static %}
{% load i18n %}
{% load active_link %}
<nav class="navbar border-b border-base-300 bg-base-200 flex lg:hidden" hx-boost="true">
<nav class="navbar border-b-2 border-base-100 bg-base-200 flex lg:hidden shadow-lg" hx-boost="true">
<div class="container mx-auto px-4 flex justify-between items-center w-full">
<a class="text-xl font-bold text-primary" href="{% url 'index' %}">
<img src="{% static 'img/logo-icon.svg' %}" alt="WYGIWYH Logo" height="40" width="40" title="WYGIWYH"/>
<div class="logo mobile"></div>
</a>
<button class="btn btn-ghost lg:hidden" type="button" data-bs-toggle="offcanvas" data-bs-target="#sidebar"
aria-controls="sidebar" aria-label={% translate "Toggle navigation" %}>

View File

@@ -1,10 +1,28 @@
{% load settings %}
{% load i18n %}
<label class="swap swap-rotate btn btn-secondary btn-sm" data-tippy-content="{% translate 'Toggle theme' %}">
<input type="checkbox"
_="on load
if <html/>'s @data-theme is 'wygiwyh_dark' set my.checked to true end
end
on change
if my.checked set <html/>'s @data-theme to 'wygiwyh_dark'
else set <html/>'s @data-theme to 'wygiwyh_light'
then fetch {% url 'toggle_theme' %}
end
end"
/>
<i class="fa-regular fa-sun swap-off"></i>
<i class="fa-regular fa-moon swap-on"></i>
</label>
<div class="dropdown dropdown-top dropdown-end">
<div tabindex="0" role="button" class="btn btn-secondary btn-sm">
<i class="fa-solid fa-cog"></i>
</div>
<ul tabindex="0" class="dropdown-content menu bg-base-100 rounded-box z-[1] w-52 p-2 shadow">
<ul tabindex="0" class="dropdown-content menu bg-base-100 rounded-box z-1 w-52 p-2 shadow">
<li><a
hx-get="{% url 'user_settings' %}"
hx-target="#generic-offcanvas"

View File

@@ -12,10 +12,10 @@
hx-boost="true"
hx-swap="transition:true"
data-bs-scroll="true"
class="offcanvas-lg offcanvas-start lg:flex flex-col fixed top-0 left-0 h-full bg-base-300! shadow-sm z-[1045]">
<div data-theme="wygiwyh_dark" class="hidden lg:flex items-center justify-between pr-4 border-b border-base-content/10 sidebar-submenu-header bg-base-300">
<a href="{% url 'index' %}" class="m-0 hidden lg:flex justify-start p-3 no-underline sidebar-title">
<img src="{% static 'img/logo-icon.svg' %}" alt="WYGIWYH Logo" height="30" width="30" title="WYGIWYH"/>
class="offcanvas-lg offcanvas-start lg:flex flex-col fixed top-0 left-0 h-full bg-base-300! border-e-2 border-base-100 lg:group-hover:shadow-[5px_0px_10px_-2px_rgba(0,0,0,0.2)] z-1045">
<div class="hidden lg:flex items-center justify-between border-b border-base-content/10 sidebar-submenu-header">
<a href="{% url 'index' %}" class="m-0 hidden lg:flex justify-start p-4 no-underline sidebar-title">
<div class="logo"></div>
<span class="text-2xl font-bold ml-3">WYGIWYH</span>
</a>
@@ -37,13 +37,12 @@
<div class="lg:hidden flex justify-between items-center p-4 text-base-content">
<a href="{% url 'index' %}" class="flex justify-start no-underline">
<img src="{% static 'img/logo-icon.svg' %}" alt="WYGIWYH Logo" height="30" width="30" title="WYGIWYH"/>
<div class="logo"></div>
<span class="text-2xl font-bold ml-3">WYGIWYH</span>
</a>
<button type="button" class="btn btn-ghost btn-sm btn-circle" data-bs-target="#sidebar" data-bs-dismiss="offcanvas"
aria-label={% translate 'Close' %}><i class="fa-solid fa-xmark"></i></button>
</div>
<hr class="m-0 hr">
<ul class="list-none p-3 flex flex-col gap-1 whitespace-nowrap lg:group-hover:animate-[disable-pointer-events] overflow-y-auto overflow-x-hidden"
style="animation-duration: 100ms">
@@ -143,7 +142,7 @@
data-bs-target="#collapsible-panel"
aria-expanded="false"
aria-controls="collapsible-panel"
class="sidebar-item text-wrap lg:text-nowrap lg:text-sm flex items-center no-underline p-2 cursor-pointer sidebar-item {% active_link views='tags_index||entities_index||categories_index||accounts_index||account_groups_index||currencies_index||exchange_rates_index||rules_index||import_profiles_index||automatic_exchange_rates_index||export_index||users_index' css_class="sidebar-active" %}">
class="lg:text-sm flex items-center no-underline ps-3 p-2 rounded-box sidebar-item cursor-pointer {% active_link views='tags_index||entities_index||categories_index||accounts_index||account_groups_index||currencies_index||exchange_rates_index||rules_index||import_profiles_index||automatic_exchange_rates_index||export_index||users_index' css_class="sidebar-active" %}">
<i class="fa-solid fa-toolbox fa-fw"></i>
<span class="ml-3 font-medium lg:group-hover:truncate lg:group-focus:truncate lg:group-hover:text-ellipsis lg:group-focus:text-ellipsis">
{% translate 'Management' %}
@@ -154,7 +153,7 @@
<div class="mt-auto p-2 w-full">
<div id="collapsible-panel"
class="p-0 collapse absolute bottom-0 left-0 w-full z-30 max-h-dvh {% active_link views='tags_index||entities_index||categories_index||accounts_index||account_groups_index||currencies_index||exchange_rates_index||rules_index||import_profiles_index||automatic_exchange_rates_index||export_index||users_index' css_class="show" %}">
class="bs collapse p-0 absolute bottom-0 left-0 w-full z-30 max-h-dvh {% active_link views='tags_index||entities_index||categories_index||accounts_index||account_groups_index||currencies_index||exchange_rates_index||rules_index||import_profiles_index||automatic_exchange_rates_index||export_index||users_index' css_class="show" %}">
<div class="h-dvh bg-base-300 flex flex-col">
<div
class="justify-between items-center p-4 border-b border-base-content/10 sidebar-submenu-header text-base-content">
@@ -171,7 +170,7 @@
</button>
</div>
<ul class="list-none p-3 flex flex-col gap-2 lg:group-hover:animate-[disable-pointer-events] flex-1 overflow-y-auto overflow-x-hidden"
<ul class="list-none p-3 flex flex-col gap-1 whitespace-nowrap lg:group-hover:animate-[disable-pointer-events] overflow-y-auto overflow-x-hidden"
style="animation-duration: 100ms">
<c-components.sidebar-menu-header title="{% translate 'Transactions' %}"></c-components.sidebar-menu-header>
<c-components.sidebar-menu-item
@@ -270,10 +269,10 @@
{% get_update_check as update_check %}
{% if update_check.update_available %}
<div class="my-3">
<a class="px-3 badge badge-primary no-underline cursor-pointer w-full !text-xs"
<a class="btn btn-primary btn-soft btn-sm w-full sidebar-item"
href="https://github.com/eitchtee/WYGIWYH/releases/latest" target="_blank"><i
class="fa-solid fa-circle-exclamation fa-fw mr-2"></i><span
class="lg:invisible lg:group-hover:visible">v.{{ update_check.latest_version }} {% translate 'is available' %}!</span></a>
class="fa-solid fa-circle-exclamation fa-fw lg:group-hover:me-2"></i><span
class="lg:hidden lg:group-hover:block">v.{{ update_check.latest_version }} {% translate 'is available' %}!</span></a>
</div>
{% endif %}
@@ -286,19 +285,23 @@
</div>
<div>
<hr class="my-1 border-base-300">
<hr class="hr my-1">
<div
class="ps-4 pe-2 py-2 flex items-center no-underline justify-between">
class="ps-6 pe-2 py-2 flex items-center no-underline justify-between">
<div class="flex items-center" style="min-width: 0;">
<i class="fa-solid fa-circle-user text-base-content/60"></i>
<i class="fa-solid fa-circle-user text-subtle"></i>
<strong class="mx-2 text-base-content/60 truncate sidebar-invisible">
{{ user.email }}
<strong class="mx-2 text-subtle truncate sidebar-invisible">
{% if user.first_name and user.last_name %}
{{ user.first_name }} {{ user.last_name }}
{% else %}
{{ user.email }}
{% endif %}
</strong>
</div>
<div class="sidebar-invisible">
<div class="sidebar-invisible flex flex-row gap-2">
{% include 'includes/navbar/user_menu.html' %}
</div>

View File

@@ -6,11 +6,11 @@
<div class="join join-vertical w-full" id="emergency-fund-accordion">
{% for id, data in data.items %}
{% if data.average %}
<div class="collapse collapse-arrow join-item border-base-300 border">
<input type="radio" name="emergency-fund-accordion" />
<div class="collapse collapse-arrow join-item bg-base-100 border-base-200 border">
<input type="checkbox" />
<div class="collapse-title text-base font-medium">
<span>
<span class="text-base-content/60">{% trans "You've spent an average of" %}</span>
<span class="text-subtle">{% trans "You've spent an average of" %}</span>
<c-amount.display
:amount="data.average"
:prefix="data.currency.prefix"
@@ -18,15 +18,15 @@
:decimal_places="data.currency.decimal_places"
custom_class="text-3xl"
divless></c-amount.display>
<span class="text-base-content/60">{% trans 'on the last 12 months, at this rate you could go by' %}</span>
<span class="text-subtle">{% trans 'on the last 12 months, at this rate you could go by' %}</span>
<span class="text-3xl">{{ data.months }}</span>
<span class="text-base-content/60">{% trans 'months without any income.' %}</span>
<span class="text-subtle">{% trans 'months without any income.' %}</span>
</span>
</div>
<div class="collapse-content">
<div class="collapse-content bg-base-200">
<div class="flex justify-between items-baseline mt-2">
<div class="text-end font-mono">
<div class="text-base-content/60">{% translate 'average expenses' %}</div>
<div class="text-subtle">{% translate 'average expenses' %}</div>
</div>
<div class="dotted-line flex-grow"></div>
<div class="text-end font-mono">
@@ -40,7 +40,7 @@
</div>
<div class="flex justify-between items-baseline mt-2">
<div class="text-end font-mono">
<div class="text-base-content/60">{% translate 'liquid total' %}</div>
<div class="text-subtle">{% translate 'liquid total' %}</div>
</div>
<div class="dotted-line flex-grow"></div>
<div class="text-end font-mono">
@@ -54,7 +54,7 @@
</div>
<div class="flex justify-between items-baseline mt-2">
<div class="text-end font-mono">
<div class="text-base-content/60">{% translate 'months left' %}</div>
<div class="text-subtle">{% translate 'months left' %}</div>
</div>
<div class="dotted-line flex-grow"></div>
<div class="text-end font-mono">

View File

@@ -4,7 +4,8 @@
{% load i18n %}
{% load title %}
<!DOCTYPE html>
<html lang="en" data-theme="wygiwyh_dark">
<html lang="en"
data-theme="{% if request.session.theme == 'wygiwyh_light' %}wygiwyh_light{% else %}wygiwyh_dark{% endif %}">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
@@ -22,26 +23,6 @@
{% block extra_js_head %}{% endblock %}
</head>
<body class="font-mono">
<div class="fixed top-4 right-4 z-50">
<label class="swap swap-rotate">
<!-- this hidden checkbox controls the state -->
<input type="checkbox"
class="theme-controller text-base-content text-sm"
value="wygiwyh_light" />
<!-- sun icon -->
<svg class="swap-off h-10 w-10 fill-current"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24">
<path d="M5.64,17l-.71.71a1,1,0,0,0,0,1.41,1,1,0,0,0,1.41,0l.71-.71A1,1,0,0,0,5.64,17ZM5,12a1,1,0,0,0-1-1H3a1,1,0,0,0,0,2H4A1,1,0,0,0,5,12Zm7-7a1,1,0,0,0,1-1V3a1,1,0,0,0-2,0V4A1,1,0,0,0,12,5ZM5.64,7.05a1,1,0,0,0,.7.29,1,1,0,0,0,.71-.29,1,1,0,0,0,0-1.41l-.71-.71A1,1,0,0,0,4.93,6.34Zm12,.29a1,1,0,0,0,.7-.29l.71-.71a1,1,0,1,0-1.41-1.41L17,5.64a1,1,0,0,0,0,1.41A1,1,0,0,0,17.66,7.34ZM21,11H20a1,1,0,0,0,0,2h1a1,1,0,0,0,0-2Zm-9,8a1,1,0,0,0-1,1v1a1,1,0,0,0,2,0V20A1,1,0,0,0,12,19ZM18.36,17A1,1,0,0,0,17,18.36l.71.71a1,1,0,0,0,1.41,0,1,1,0,0,0,0-1.41ZM12,6.5A5.5,5.5,0,1,0,17.5,12,5.51,5.51,0,0,0,12,6.5Zm0,9A3.5,3.5,0,1,1,15.5,12,3.5,3.5,0,0,1,12,15.5Z" />
</svg>
<!-- moon icon -->
<svg class="swap-on h-10 w-10 fill-current"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24">
<path d="M21.64,13a1,1,0,0,0-1.05-.14,8.05,8.05,0,0,1-3.37.73A8.15,8.15,0,0,1,9.08,5.49a8.59,8.59,0,0,1,.25-2A1,1,0,0,0,8,2.36,10.14,10.14,0,1,0,22,14.05,1,1,0,0,0,21.64,13Zm-9.5,6.69A8.14,8.14,0,0,1,7.08,5.22v.27A10.15,10.15,0,0,0,17.22,15.63a9.79,9.79,0,0,0,2.1-.22A8.11,8.11,0,0,1,12.14,19.73Z" />
</svg>
</label>
</div>
<div _="install hide_amounts install htmx_error_handler
{% block body_hyperscript %}{% endblock %}"
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'>

View File

@@ -6,7 +6,7 @@
{% for x in transactions_by_date %}
<div id="{{ x.grouper|slugify }}" class="transactions-divider"
_="on htmx:afterSwap from #transactions if sessionStorage.getItem(my id) is null then sessionStorage.setItem(my id, 'true')">
<div class="mt-3 mb-1 w-full border-b border-b-base-content/30 transactions-divider-title">
<div class="mt-3 mb-1 w-full border-b border-b-base-content/30 transactions-divider-title cursor-pointer">
<a class="no-underline inline-block w-full"
role="button"
data-bs-toggle="collapse"
@@ -17,7 +17,7 @@
{{ x.grouper }}
</a>
</div>
<div class="collapse transactions-divider-collapse overflow-visible isolation-auto" id="c-{{ x.grouper|slugify }}-collapse"
<div class="bs collapse transactions-divider-collapse overflow-visible isolation-auto" id="c-{{ x.grouper|slugify }}-collapse"
_="on shown.bs.collapse sessionStorage.setItem(the closest parent @id, 'true')
on hidden.bs.collapse sessionStorage.setItem(the closest parent @id, 'false')
on htmx:afterSettle from #transactions or toggle

View File

@@ -192,7 +192,7 @@
{% endfor %}
</div>
</div>
<div class="flex justify-between mt-3">
<div class="flex justify-between">
<div class="text-right font-mono">
<div class="text-subtle">{% translate 'projected' %}</div>
</div>

View File

@@ -132,7 +132,7 @@
title="{% translate 'Order by' %}">
<i class="fa-solid fa-sort fa-fw"></i>
</button>
<ul tabindex="0" class="dropdown-content menu bg-base-300 rounded-box z-[1] w-52 p-2 shadow-md mt-1">
<ul tabindex="0" class="dropdown-content menu bg-base-300 rounded-box z-1 w-62 p-2 shadow-md mt-1">
<li>
<button class="{% if order == 'default' %}menu-active{% endif %}" type="button"
_="on click remove .menu-active from <li > button/> in the closest <ul/>
@@ -165,7 +165,7 @@
</div>
{# Filter transactions form #}
<div class="collapse overflow-visible" id="collapse-filter" hx-preserve>
<div class="bs collapse overflow-visible" id="collapse-filter" hx-preserve>
<div class="card card-body bg-base-200 mt-2">
<div class="text-right">
<button class="btn btn-outline btn-error btn-sm w-fit"

View File

@@ -1,13 +1,12 @@
{% load natural %}
{% load i18n %}
{% regroup page_obj by date|customnaturaldate as transactions_by_date %}
<div id="transactions-list">
<div id="transactions-list" class="show-loading">
{% for x in transactions_by_date %}
<div id="{{ x.grouper|slugify }}" class="transactions-divider"
_="on htmx:afterSwap from #transactions if sessionStorage.getItem(my id) is null then sessionStorage.setItem(my id, 'true')">
<div class="mt-3 mb-1 w-full text-base border-b border-base-300 bg-base-100 transactions-divider-title">
<div class="mt-3 mb-1 w-full border-b border-b-base-content/30 transactions-divider-title cursor-pointer">
<a class="no-underline inline-block w-full"
role="button"
data-bs-toggle="collapse"
@@ -18,7 +17,7 @@
{{ x.grouper }}
</a>
</div>
<div class="collapse transactions-divider-collapse overflow-visible isolation-auto" id="c-{{ x.grouper|slugify }}-collapse"
<div class="bs collapse transactions-divider-collapse overflow-visible isolation-auto" id="c-{{ x.grouper|slugify }}-collapse"
_="on shown.bs.collapse sessionStorage.setItem(the closest parent @id, 'true')
on hidden.bs.collapse sessionStorage.setItem(the closest parent @id, 'false')
on htmx:afterSettle from #transactions or toggle
@@ -41,14 +40,18 @@
</div>
</div>
</div>
{% empty %}
<c-msg.empty
title="{% translate "No transactions found" %}"
subtitle="{% translate "Try adding one" %}"></c-msg.empty>
{% endfor %}
{# Floating bar #}
<c-ui.transactions-action-bar></c-ui.transactions-action-bar>
{% if page_obj.has_other_pages %}
<div class="mt-auto">
<div class="my-3">
<input value="{{ page_obj.number }}" name="page" type="hidden" id="page">
<nav aria-label="{% translate 'Page navigation' %}">
@@ -86,7 +89,8 @@
hx-vals='{"page": {{ page_number }}}'
hx-include="#filter, #order"
hx-target="#transactions-list"
hx-swap="show:top">
hx-swap="outerHTML show:top"
hx-indicator="#transactions-list">
{{ page_number }}
</a>
</li>
@@ -102,10 +106,12 @@
</li>
<li>
<a class="join-item btn btn-sm"
hx-get="{% url 'transactions_all_list' %}" hx-target="#transactions-list"
hx-get="{% url 'transactions_all_list' %}"
hx-target="#transactions-list"
hx-vals='{"page": {{ page_obj.paginator.num_pages }}}'
hx-include="#filter, #order"
hx-swap="show:top"
hx-swap="outerHTML show:top"
hx-indicator="#transactions-list"
aria-label="Última página">
<span aria-hidden="true">{{ page_obj.paginator.num_pages }}</span>
</a>
@@ -116,8 +122,9 @@
hx-get="{% if page_obj.has_next %}{% url 'transactions_all_list' %}{% endif %}"
hx-vals='{"page": {{ page_obj.paginator.num_pages }}}'
hx-include="#filter, #order"
hx-swap="show:top"
hx-swap="outerHTML show:top"
hx-target="#transactions-list"
hx-indicator="#transactions-list"
aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
@@ -126,7 +133,4 @@
</nav>
</div>
{% endif %}
{# Floating bar#}
<c-ui.transactions-action-bar></c-ui.transactions-action-bar>
</div>

View File

@@ -1,47 +1,30 @@
{% load tools %}
{% load i18n %}
{% load currency_display %}
<ul class="nav nav-tabs" id="all-trasactions-tab" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="currency-tab" data-bs-toggle="tab" data-bs-target="#currency-tab-pane"
type="button" role="tab" aria-controls="currency-tab-pane"
aria-selected="true">{% trans 'Currencies' %}</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="account-tab" data-bs-toggle="tab" data-bs-target="#account-tab-pane" type="button"
role="tab" aria-controls="account-tab-pane" aria-selected="false">{% trans 'Accounts' %}</button>
</li>
</ul>
<div class="tab-content" id="all-transactions-content">
<div class="tab-pane fade show active" id="currency-tab-pane" role="tabpanel" aria-labelledby="currency-tab"
tabindex="0">
<div class="row row-cols-1 g-4 mt-2">
{% for currency_id, currency in currency_data.items %}
<div class="col">
<c-ui.currency_card :currency="currency" :currency_id="currency_id"
:percentages="currency_percentages"></c-ui.currency_card>
</div>
{% empty %}
<div class="col">
<c-msg.empty
title="{% translate "No information to display" %}"></c-msg.empty>
{% endfor %}
</div>
<div class="grid grid-cols-1 gap-4 mt-1 mb-3">
{% for currency_id, currency in currency_data.items %}
<div>
<c-ui.currency_card :currency="currency" :currency_id="currency_id"
:percentages="currency_percentages"></c-ui.currency_card>
</div>
</div>
<div class="tab-pane fade" id="account-tab-pane" role="tabpanel" aria-labelledby="account-tab" tabindex="0">
<div class="row row-cols-1 g-4 mt-2">
{% for account_id, account in account_data.items %}
<div class="col">
<c-ui.account_card :account="account" :account_id="account_id"
:percentages="account_percentages"></c-ui.account_card>
</div>
{% empty %}
<div class="col">
<c-msg.empty
title="{% translate "No information to display" %}"></c-msg.empty>
{% endfor %}
</div>
{% empty %}
<div>
<c-msg.empty
title="{% translate "No information to display" %}"></c-msg.empty>
</div>
{% endfor %}
</div>
<div class="grid grid-cols-1 gap-4 mt-1 mb-3">
{% for account_id, account in account_data.items %}
<div>
<c-ui.account_card :account="account" :account_id="account_id"
:percentages="account_percentages"></c-ui.account_card>
</div>
{% empty %}
<div>
<c-msg.empty
title="{% translate "No information to display" %}"></c-msg.empty>
{% endfor %}
</div>
</div>

View File

@@ -5,12 +5,45 @@
{% block title %}{% translate 'Transactions' %}{% endblock %}
{% block content %}
<div class="container px-md-3 py-3 column-gap-5 overflow-x-hidden">
<div class="flex flex-wrap gap-x-xl-4 gap-y-3">
<div class="w-full xl:w-8/12 order-2 xl:order-1">
<div class="mb-3">
<div class="container gap-y-3">
<div class="row gap-y-3">
<div class="col-12 lg:col-4 lg:order-last! order-first!">
<div role="tablist" class="tabs tabs-border">
<input type="radio" name="all-transactions-summary" class="tab" aria-label="{% trans 'Currencies' %}"
role="tab"
{% if summary_tab == 'currency' %}checked="checked"{% endif %}
_="on click fetch {% url 'transaction_all_summary_select' selected='currency' %}"
aria-controls="currency-tab-pane" />
<div class="tab-content" id="currency-tab-pane" role="tabpanel">
<div id="currency-summary"
hx-get="{% url 'transaction_all_currency_summary' %}"
class="show-loading"
hx-trigger="load, selective_update from:window, updated from:window, change from:#filter, submit from:#filter, search from:#filter"
hx-include="#filter">
</div>
</div>
<input type="radio" name="all-transactions-summary" class="tab" aria-label="{% trans 'Accounts' %}"
role="tab"
{% if summary_tab == 'account' %}checked="checked"{% endif %}
_="on click fetch {% url 'transaction_all_summary_select' selected='account' %}"
aria-controls="account-tab-pane" />
<div class="tab-content" id="account-tab-pane" role="tabpanel">
<div id="account-summary"
hx-get="{% url 'transaction_all_account_summary' %}"
class="show-loading"
hx-trigger="load, selective_update from:window, updated from:window, change from:#filter, submit from:#filter, search from:#filter"
hx-include="#filter">
</div>
</div>
</div>
</div>
<div class="col-12 lg:col-8 lg:order-first! order-last!">
<div>
{# Hidden select to hold the order value and preserve the original update trigger #}
<select name="order" id="order" class="hidden" _="on change trigger updated on window">
<select name="order" id="order" class="d-none" _="on change trigger updated on window">
<option value="default" {% if order == 'default' %}selected{% endif %}>{% translate 'Default' %}</option>
<option value="older" {% if order == 'older' %}selected{% endif %}>{% translate 'Oldest first' %}</option>
<option value="newer" {% if order == 'newer' %}selected{% endif %}>{% translate 'Newest first' %}</option>
@@ -19,7 +52,7 @@
{# Main control bar with filter, search, and ordering #}
<div class="join w-full">
<button class="btn btn-secondary join-item" type="button"
<button class="btn btn-secondary join-item relative" type="button"
data-bs-toggle="collapse" data-bs-target="#collapse-filter"
aria-expanded="false" aria-controls="collapse-filter" id="filter-button" hx-preserve
title="{% translate 'Filter transactions' %}">
@@ -27,10 +60,10 @@
</button>
{# Search box #}
<label for="quick-search" class="join-item flex-grow">
<label for="quick-search" class="hidden">
</label>
<input type="search"
class="input input-bordered join-item flex-grow"
class="input input-bordered join-item flex-1"
placeholder="{% translate 'Search' %}"
hx-preserve
id="quick-search"
@@ -46,34 +79,33 @@
{# Order by icon dropdown #}
<div class="dropdown dropdown-end">
<button class="btn btn-secondary join-item" type="button"
tabindex="0" role="button"
<button tabindex="0" class="btn btn-secondary join-item" type="button"
title="{% translate 'Order by' %}">
<i class="fa-solid fa-sort fa-fw"></i>
</button>
<ul class="dropdown-content menu bg-base-100 rounded-box z-[1] w-52 p-2 shadow" tabindex="0">
<ul tabindex="0" class="dropdown-content menu bg-base-300 rounded-box z-1 w-62 p-2 shadow-md mt-1">
<li>
<button class="{% if order == 'default' %}active{% endif %}" type="button"
_="on click remove .active from <button/> in the closest <ul/>
then add .active to me
<button class="{% if order == 'default' %}menu-active{% endif %}" type="button"
_="on click remove .menu-active from <li > button/> in the closest <ul/>
then add .menu-active to me
then set the value of #order to 'default'
then trigger change on #order">
{% translate 'Default' %}
</button>
</li>
<li>
<button class="{% if order == 'older' %}active{% endif %}" type="button"
_="on click remove .active from <button/> in the closest <ul/>
then add .active to me
<button class="{% if order == 'older' %}menu-active{% endif %}" type="button"
_="on click remove .menu-active from <li > button/> in the closest <ul/>
then add .menu-active to me
then set the value of #order to 'older'
then trigger change on #order">
{% translate 'Oldest first' %}
</button>
</li>
<li>
<button class="{% if order == 'newer' %}active{% endif %}" type="button"
_="on click remove .active from <button/> in the closest <ul/>
then add .active to me
<button class="{% if order == 'newer' %}menu-active{% endif %}" type="button"
_="on click remove .menu-active from <li > button/> in the closest <ul/>
then add .menu-active to me
then set the value of #order to 'newer'
then trigger change on #order">
{% translate 'Newest first' %}
@@ -84,9 +116,9 @@
</div>
{# Filter transactions form #}
<div class="collapse" id="collapse-filter" hx-preserve>
<div class="card card-body bg-base-100 shadow-xl">
<div class="text-end">
<div class="bs collapse overflow-visible" id="collapse-filter" hx-preserve>
<div class="card card-body bg-base-200 mt-2">
<div class="text-right">
<button class="btn btn-outline btn-error btn-sm w-fit"
_="on click call #filter.reset() then trigger change on #filter">{% translate 'Clear' %}</button>
</div>
@@ -98,46 +130,20 @@
{% crispy filter.form %}
</form>
<div class="text-end">
<div class="text-right">
<button class="btn btn-outline btn-error btn-sm w-fit"
_="on click call #filter.reset() then trigger change on #filter">{% translate 'Clear' %}</button>
</div>
</div>
</div>
</div>
{# Transactions list#}
<div id="transactions"
class="show-loading"
hx-get="{% url 'transactions_all_list' %}"
hx-trigger="load, updated from:window" hx-include="#filter, #page, #order">
</div>
</div>
<div class="w-full xl:w-4/12 order-1 xl:order-2">
<div role="tablist" class="tabs tabs-lifted">
<input type="radio" name="all-transactions-summary" role="tab" class="tab" aria-label="{% trans 'Currencies' %}"
{% if summary_tab == 'currency' %}checked="checked"{% endif %}
_="on change fetch {% url 'transaction_all_summary_select' selected='currency' %}" />
<div role="tabpanel" class="tab-content border-base-300 rounded-box p-6">
<div id="currency-summary"
hx-get="{% url 'transaction_all_currency_summary' %}"
class="show-loading"
hx-trigger="load, selective_update from:window, updated from:window, change from:#filter, submit from:#filter, search from:#filter"
hx-include="#filter">
</div>
</div>
<input type="radio" name="all-transactions-summary" role="tab" class="tab" aria-label="{% trans 'Accounts' %}"
{% if summary_tab == 'account' %}checked="checked"{% endif %}
_="on change fetch {% url 'transaction_all_summary_select' selected='account' %}" />
<div role="tabpanel" class="tab-content border-base-300 rounded-box p-6">
<div id="account-summary"
hx-get="{% url 'transaction_all_account_summary' %}"
class="show-loading"
hx-trigger="load, selective_update from:window, updated from:window, change from:#filter, submit from:#filter, search from:#filter"
hx-include="#filter">
</div>
</div>
</div>
</div>
</div>
</div>
<c-ui.transactions_fab></c-ui.transactions_fab>