mirror of
https://github.com/eitchtee/WYGIWYH.git
synced 2026-04-25 10:08:36 +02:00
feat: more changes and fixes
This commit is contained in:
@@ -3,7 +3,6 @@ from decimal import Decimal
|
|||||||
from django import template
|
from django import template
|
||||||
from django.utils.formats import number_format
|
from django.utils.formats import number_format
|
||||||
|
|
||||||
|
|
||||||
register = template.Library()
|
register = template.Library()
|
||||||
|
|
||||||
|
|
||||||
@@ -13,13 +12,24 @@ def _format_string(prefix, amount, decimal_places, suffix):
|
|||||||
value=abs(amount), decimal_pos=decimal_places, force_grouping=True
|
value=abs(amount), decimal_pos=decimal_places, force_grouping=True
|
||||||
)
|
)
|
||||||
if amount < 0:
|
if amount < 0:
|
||||||
|
return "-", prefix, formatted_amount, suffix
|
||||||
return f"-{prefix}{formatted_amount}{suffix}"
|
return f"-{prefix}{formatted_amount}{suffix}"
|
||||||
else:
|
else:
|
||||||
|
return "", prefix, formatted_amount, suffix
|
||||||
return f"{prefix}{formatted_amount}{suffix}"
|
return f"{prefix}{formatted_amount}{suffix}"
|
||||||
else:
|
else:
|
||||||
return "ERR"
|
return "", "", "ERR", ""
|
||||||
|
|
||||||
|
|
||||||
@register.simple_tag(name="currency_display")
|
@register.simple_tag(name="currency_display")
|
||||||
def currency_display(amount, prefix, suffix, decimal_places):
|
def currency_display(amount, prefix, suffix, decimal_places):
|
||||||
return _format_string(prefix, amount, decimal_places, suffix)
|
sign, prefix, amount, suffix = _format_string(
|
||||||
|
prefix, amount, decimal_places, suffix
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"sign": sign,
|
||||||
|
"prefix": prefix,
|
||||||
|
"amount": amount,
|
||||||
|
"suffix": suffix,
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,10 +1,15 @@
|
|||||||
{% load currency_display %}
|
{% load currency_display %}
|
||||||
|
|
||||||
|
{% currency_display amount=amount prefix=prefix suffix=suffix decimal_places=decimal_places as formatted_amount %}
|
||||||
|
|
||||||
{% if not divless %}
|
{% if not divless %}
|
||||||
<div class="{% if text_end %}text-end{% elif text_start %}text-start{% endif %}">
|
<div class="{% if text_end %}text-end{% elif text_start %}text-start{% endif %}">
|
||||||
{% 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{% endif %} font-medium {{ custom_class }}"
|
||||||
data-original-value="{% currency_display amount=amount prefix=prefix suffix=suffix decimal_places=decimal_places %}"
|
data-original-sign="{{ formatted_amount.sign }}"
|
||||||
|
data-original-prefix="{{ formatted_amount.prefix }}"
|
||||||
|
data-original-amount="{{ formatted_amount.amount }}"
|
||||||
|
data-original-suffix="{{ formatted_amount.suffix }}"
|
||||||
data-amount="{{ amount|floatformat:"-40u" }}">
|
data-amount="{{ amount|floatformat:"-40u" }}">
|
||||||
</span><span>{{ slot }}</span>
|
</span><span>{{ slot }}</span>
|
||||||
{% if not divless %}
|
{% if not divless %}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<i class="{% if icon %}{{ icon }}{% else %}fa-solid fa-circle-xmark{% endif %} text-6xl"></i>
|
<i class="{% if icon %}{{ icon }}{% else %}fa-solid fa-circle-xmark{% endif %} text-6xl"></i>
|
||||||
<p class="text-lg mt-4 mb-0">{{ title }}</p>
|
<p class="text-lg mt-4 mb-0">{{ title }}</p>
|
||||||
<p class="text-gray-500">{{ subtitle }}</p>
|
<p class="text-subtle">{{ subtitle }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{% load markdown %}
|
{% load markdown %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
<div
|
<div
|
||||||
class="transaction {% if transaction.type == "EX" %}expense{% else %}income{% endif %} group/transaction relative group-hover/transaction:z-50 hover:z-50">
|
class="transaction {% if transaction.type == "EX" %}expense{% else %}income{% endif %} group/transaction relative">
|
||||||
<div class="flex my-1">
|
<div class="flex my-1">
|
||||||
{% if not disable_selection or not dummy %}
|
{% if not disable_selection or not dummy %}
|
||||||
<label class="px-3 flex! items-center justify-center">
|
<label class="px-3 flex! items-center justify-center">
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
<div class="flex flex-wrap font-mono text-sm items-center">
|
<div class="flex flex-wrap font-mono text-sm items-center">
|
||||||
<div class="lg:w-auto w-full flex items-center text-2xl lg:text-xl lg:text-center text-center p-0 cursor-pointer">
|
<div class="lg:w-auto w-full flex items-center text-2xl lg:text-xl lg:text-center text-center p-0 cursor-pointer">
|
||||||
{% if not transaction.deleted %}
|
{% if not transaction.deleted %}
|
||||||
<a class="no-underline p-3 text-gray-500!"
|
<a class="no-underline p-3 text-base-content/50"
|
||||||
title="{% if transaction.is_paid %}{% trans 'Paid' %}{% else %}{% trans 'Projected' %}{% endif %}"
|
title="{% if transaction.is_paid %}{% trans 'Paid' %}{% else %}{% trans 'Projected' %}{% endif %}"
|
||||||
role="button"
|
role="button"
|
||||||
{% if not dummy %}
|
{% if not dummy %}
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
class="fa-regular fa-circle"></i>{% endif %}
|
class="fa-regular fa-circle"></i>{% endif %}
|
||||||
</a>
|
</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="no-underline p-3 text-gray-500!"
|
<div class="no-underline p-3 text-base-content/50"
|
||||||
title="{% if transaction.is_paid %}{% trans 'Paid' %}{% else %}{% trans 'Projected' %}{% endif %}">
|
title="{% if transaction.is_paid %}{% trans 'Paid' %}{% else %}{% trans 'Projected' %}{% endif %}">
|
||||||
{% if transaction.is_paid %}<i class="fa-regular fa-circle-check"></i>{% else %}<i
|
{% if transaction.is_paid %}<i class="fa-regular fa-circle-check"></i>{% else %}<i
|
||||||
class="fa-regular fa-circle"></i>{% endif %}
|
class="fa-regular fa-circle"></i>{% endif %}
|
||||||
@@ -138,16 +138,16 @@
|
|||||||
<div class="z-1000">
|
<div class="z-1000">
|
||||||
{# Item actions#}
|
{# Item actions#}
|
||||||
<div
|
<div
|
||||||
class="card transaction-actions absolute! left-1/2 -translate-x-1/2 -translate-y-1/2 top-0 invisible group-hover/transaction:visible! flex flex-row bg-base-300">
|
class="card card-border-base-100 transaction-actions absolute left-1/2 -translate-x-1/2 -translate-y-1/2 top-0 invisible group-hover/transaction:visible flex flex-row bg-base-200">
|
||||||
<div class="card-body p-1 shadow-lg flex flex-row gap-1">
|
<div class="card-body p-1 shadow-lg flex flex-row gap-1">
|
||||||
{% if not transaction.deleted %}
|
{% if not transaction.deleted %}
|
||||||
<a class="btn btn-neutral btn-sm transaction-action"
|
<a class="btn btn-soft btn-sm transaction-action"
|
||||||
role="button"
|
role="button"
|
||||||
hx-get="{% url 'transaction_edit' transaction_id=transaction.id %}"
|
hx-get="{% url 'transaction_edit' transaction_id=transaction.id %}"
|
||||||
hx-target="#generic-offcanvas" hx-swap="innerHTML"
|
hx-target="#generic-offcanvas" hx-swap="innerHTML"
|
||||||
data-tippy-content="{% translate "Edit" %}">
|
data-tippy-content="{% translate "Edit" %}">
|
||||||
<i class="fa-solid fa-pencil fa-fw"></i></a>
|
<i class="fa-solid fa-pencil fa-fw"></i></a>
|
||||||
<a class="btn btn-neutral btn-sm transaction-action"
|
<a class="btn btn-error btn-soft btn-sm transaction-action"
|
||||||
role="button"
|
role="button"
|
||||||
hx-delete="{% url 'transaction_delete' transaction_id=transaction.id %}"
|
hx-delete="{% url 'transaction_delete' transaction_id=transaction.id %}"
|
||||||
hx-trigger='confirmed'
|
hx-trigger='confirmed'
|
||||||
@@ -156,32 +156,32 @@
|
|||||||
data-title="{% translate "Are you sure?" %}"
|
data-title="{% translate "Are you sure?" %}"
|
||||||
data-text="{% translate "You won't be able to revert this!" %}"
|
data-text="{% translate "You won't be able to revert this!" %}"
|
||||||
data-confirm-text="{% translate "Yes, delete it!" %}"
|
data-confirm-text="{% translate "Yes, delete it!" %}"
|
||||||
_="install prompt_swal"><i class="fa-solid fa-trash fa-fw text-error"></i>
|
_="install prompt_swal"><i class="fa-solid fa-trash fa-fw"></i>
|
||||||
</a>
|
</a>
|
||||||
<button class="btn btn-neutral btn-sm transaction-action" data-bs-toggle="dropdown" data-bs-container="body" aria-expanded="false">
|
<button class="btn btn-soft btn-sm transaction-action" data-bs-toggle="dropdown" data-bs-container="body" aria-expanded="false">
|
||||||
<i class="fa-solid fa-ellipsis fa-fw"></i>
|
<i class="fa-solid fa-ellipsis fa-fw"></i>
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu dropdown-menu-end dropdown-menu-md-start menu w-max relative">
|
<ul class="dropdown-menu dropdown-menu-end dropdown-menu-md-start menu w-max relative">
|
||||||
<div class="absolute inset-[0rem_-3rem_-3rem_-3rem] pointer-events-auto -z-10"></div>
|
<div class="absolute inset-[0rem_-3rem_-3rem_-3rem] pointer-events-auto -z-10"></div>
|
||||||
{% if transaction.account.is_untracked_by %}
|
{% if transaction.account.is_untracked_by %}
|
||||||
<li>
|
<li class="menu-disabled" aria-disabled="true">
|
||||||
<a class="disabled flex items-center" aria-disabled="true">
|
<a class="flex items-center">
|
||||||
<i class="fa-solid fa-eye fa-fw mr-2"></i>
|
<i class="fa-solid fa-eye fa-fw mr-2"></i>
|
||||||
<div>
|
<div>
|
||||||
{% translate 'Show on summaries' %}
|
{% translate 'Show on summaries' %}
|
||||||
<div
|
<div
|
||||||
class="block text-gray-500 text-xs font-medium">{% translate 'Controlled by account' %}</div>
|
class="block text-base-content/60 text-xs font-medium">{% translate 'Controlled by account' %}</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% elif transaction.category.mute %}
|
{% elif transaction.category.mute %}
|
||||||
<li>
|
<li class="menu-disabled" aria-disabled="true">
|
||||||
<a class="disabled flex items-center" aria-disabled="true">
|
<a class="flex items-center">
|
||||||
<i class="fa-solid fa-eye fa-fw mr-2"></i>
|
<i class="fa-solid fa-eye fa-fw mr-2"></i>
|
||||||
<div>
|
<div>
|
||||||
{% translate 'Show on summaries' %}
|
{% translate 'Show on summaries' %}
|
||||||
<div
|
<div
|
||||||
class="block text-gray-500 text-xs font-medium">{% translate 'Controlled by category' %}</div>
|
class="block text-base-content/60 text-xs font-medium">{% translate 'Controlled by category' %}</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
@@ -218,13 +218,13 @@
|
|||||||
</ul>
|
</ul>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="tooltip" data-tippy-content="{% translate "Restore" %}">
|
<div class="tooltip" data-tippy-content="{% translate "Restore" %}">
|
||||||
<a class="btn btn-secondary btn-sm transaction-action"
|
<a class="btn btn-success btn-soft btn-sm transaction-action"
|
||||||
role="button"
|
role="button"
|
||||||
hx-get="{% url 'transaction_undelete' transaction_id=transaction.id %}"><i
|
hx-get="{% url 'transaction_undelete' transaction_id=transaction.id %}"><i
|
||||||
class="fa-solid fa-trash-arrow-up"></i></a>
|
class="fa-solid fa-trash-arrow-up"></i></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="tooltip" data-tippy-content="{% translate "Delete" %}">
|
<div class="tooltip" data-tippy-content="{% translate "Delete" %}">
|
||||||
<a class="btn btn-secondary btn-sm transaction-action"
|
<a class="btn btn-error btn-soft btn-sm transaction-action"
|
||||||
role="button"
|
role="button"
|
||||||
hx-delete="{% url 'transaction_delete' transaction_id=transaction.id %}"
|
hx-delete="{% url 'transaction_delete' transaction_id=transaction.id %}"
|
||||||
hx-trigger='confirmed'
|
hx-trigger='confirmed'
|
||||||
|
|||||||
@@ -2,204 +2,165 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
<div class="card bg-base-100 shadow-md card-border border-base-300">
|
<div class="card bg-base-100 shadow-md card-border border-base-300">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
{% if account.account.group %}
|
<h5 class="card-title mb-4">
|
||||||
<div class="text-sm mb-2">
|
{% if account.account.group %}<span class="badge badge-primary badge-outline">{{ account.account.group }}</span>{% endif %} {{ account.account.name }}
|
||||||
<span class="badge badge-primary">{{ account.account.group }}</span>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
<h5 class="card-title">
|
|
||||||
{{ account.account.name }}
|
|
||||||
</h5>
|
</h5>
|
||||||
<div class="flex justify-between items-baseline mt-2">
|
<div class="card-data-section">
|
||||||
<div class="text-end ">
|
<div class="card-data-row">
|
||||||
<div class="text-subtle">{% translate 'projected income' %}</div>
|
<span class="card-data-label">{% translate 'projected income' %}</span>
|
||||||
|
<div class="card-data-values">
|
||||||
|
{% if account.income_projected != 0 %}
|
||||||
|
<c-amount.display
|
||||||
|
:amount="account.income_projected"
|
||||||
|
:prefix="account.currency.prefix"
|
||||||
|
:suffix="account.currency.suffix"
|
||||||
|
:decimal_places="account.currency.decimal_places"
|
||||||
|
color="green"></c-amount.display>
|
||||||
|
{% if account.exchanged and account.exchanged.income_projected %}
|
||||||
|
<c-amount.display
|
||||||
|
:amount="account.exchanged.income_projected"
|
||||||
|
:prefix="account.exchanged.currency.prefix"
|
||||||
|
:suffix="account.exchanged.currency.suffix"
|
||||||
|
:decimal_places="account.exchanged.currency.decimal_places"
|
||||||
|
color="gray"></c-amount.display>
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
<span class="font-semibold">-</span>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="dotted-line grow"></div>
|
<div class="card-data-row">
|
||||||
{% if account.income_projected != 0 %}
|
<span class="card-data-label">{% translate 'projected expenses' %}</span>
|
||||||
<div class="text-end">
|
<div class="card-data-values">
|
||||||
<c-amount.display
|
{% if account.expense_projected != 0 %}
|
||||||
:amount="account.income_projected"
|
<c-amount.display
|
||||||
:prefix="account.currency.prefix"
|
:amount="account.expense_projected"
|
||||||
:suffix="account.currency.suffix"
|
:prefix="account.currency.prefix"
|
||||||
:decimal_places="account.currency.decimal_places"
|
:suffix="account.currency.suffix"
|
||||||
color="green"></c-amount.display>
|
:decimal_places="account.currency.decimal_places"
|
||||||
|
color="red"></c-amount.display>
|
||||||
|
{% if account.exchanged and account.exchanged.expense_projected %}
|
||||||
|
<c-amount.display
|
||||||
|
:amount="account.exchanged.expense_projected"
|
||||||
|
:prefix="account.exchanged.currency.prefix"
|
||||||
|
:suffix="account.exchanged.currency.suffix"
|
||||||
|
:decimal_places="account.exchanged.currency.decimal_places"
|
||||||
|
color="gray"></c-amount.display>
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
<span class="font-semibold">-</span>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
<div class="card-data-row">
|
||||||
<div class="text-end ">-</div>
|
<span class="card-data-label">{% translate 'projected total' %}</span>
|
||||||
{% endif %}
|
<div class="card-data-values">
|
||||||
</div>
|
|
||||||
{% if account.exchanged and account.exchanged.income_projected %}
|
|
||||||
<div class="text-end">
|
|
||||||
<c-amount.display
|
|
||||||
:amount="account.exchanged.income_projected"
|
|
||||||
:prefix="account.exchanged.currency.prefix"
|
|
||||||
:suffix="account.exchanged.currency.suffix"
|
|
||||||
:decimal_places="account.exchanged.currency.decimal_places"
|
|
||||||
color="gray"></c-amount.display>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
<div class="flex justify-between items-baseline mt-2">
|
|
||||||
<div class="text-end ">
|
|
||||||
<div class="text-subtle">{% translate 'projected expenses' %}</div>
|
|
||||||
</div>
|
|
||||||
<div class="dotted-line grow"></div>
|
|
||||||
<div>
|
|
||||||
{% if account.expense_projected != 0 %}
|
|
||||||
<div class="text-end">
|
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="account.expense_projected"
|
:amount="account.total_projected"
|
||||||
:prefix="account.currency.prefix"
|
:prefix="account.currency.prefix"
|
||||||
:suffix="account.currency.suffix"
|
:suffix="account.currency.suffix"
|
||||||
:decimal_places="account.currency.decimal_places"
|
:decimal_places="account.currency.decimal_places"
|
||||||
color="red"></c-amount.display>
|
color="{% if account.total_projected > 0 %}green{% elif account.total_projected < 0 %}red{% endif %}"></c-amount.display>
|
||||||
|
{% if account.exchanged.total_projected and account.exchanged.total_projected %}
|
||||||
|
<c-amount.display
|
||||||
|
:amount="account.exchanged.total_projected"
|
||||||
|
:prefix="account.exchanged.currency.prefix"
|
||||||
|
:suffix="account.exchanged.currency.suffix"
|
||||||
|
:decimal_places="account.exchanged.currency.decimal_places"
|
||||||
|
color="gray"></c-amount.display>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
|
||||||
<div class="text-end ">-</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% if account.exchanged and account.exchanged.expense_projected %}
|
<hr class="card-data-divider" />
|
||||||
<div class="text-end">
|
<div class="card-data-section">
|
||||||
<c-amount.display
|
<div class="card-data-row">
|
||||||
:amount="account.exchanged.expense_projected"
|
<span class="card-data-label">{% translate 'current income' %}</span>
|
||||||
:prefix="account.exchanged.currency.prefix"
|
<div class="card-data-values">
|
||||||
:suffix="account.exchanged.currency.suffix"
|
{% if account.income_current != 0 %}
|
||||||
:decimal_places="account.exchanged.currency.decimal_places"
|
<c-amount.display
|
||||||
color="gray"></c-amount.display>
|
:amount="account.income_current"
|
||||||
</div>
|
:prefix="account.currency.prefix"
|
||||||
{% endif %}
|
:suffix="account.currency.suffix"
|
||||||
<div class="flex justify-between items-baseline mt-2">
|
:decimal_places="account.currency.decimal_places"
|
||||||
<div class="text-end ">
|
color="green"></c-amount.display>
|
||||||
<div class="text-subtle">{% translate 'projected total' %}</div>
|
{% if account.exchanged and account.exchanged.income_current %}
|
||||||
</div>
|
<c-amount.display
|
||||||
<div class="dotted-line grow"></div>
|
:amount="account.exchanged.income_current"
|
||||||
<div
|
:prefix="account.exchanged.currency.prefix"
|
||||||
class="text-end ">
|
:suffix="account.exchanged.currency.suffix"
|
||||||
<c-amount.display
|
:decimal_places="account.exchanged.currency.decimal_places"
|
||||||
:amount="account.total_projected"
|
color="gray"></c-amount.display>
|
||||||
:prefix="account.currency.prefix"
|
{% endif %}
|
||||||
:suffix="account.currency.suffix"
|
{% else %}
|
||||||
:decimal_places="account.currency.decimal_places"
|
<span class="font-semibold">-</span>
|
||||||
color="{% if account.total_projected > 0 %}green{% elif account.total_projected < 0 %}red{% endif %}"></c-amount.display>
|
{% endif %}
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% if account.exchanged.total_projected and account.exchanged.total_projected %}
|
|
||||||
<div class="text-end">
|
|
||||||
<c-amount.display
|
|
||||||
:amount="account.exchanged.total_projected"
|
|
||||||
:prefix="account.exchanged.currency.prefix"
|
|
||||||
:suffix="account.exchanged.currency.suffix"
|
|
||||||
:decimal_places="account.exchanged.currency.decimal_places"
|
|
||||||
color="gray"></c-amount.display>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
<hr class="my-3">
|
|
||||||
<div class="flex justify-between items-baseline mt-2">
|
|
||||||
<div class="text-end ">
|
|
||||||
<div class="text-subtle">{% translate 'current income' %}</div>
|
|
||||||
</div>
|
|
||||||
<div class="dotted-line grow"></div>
|
|
||||||
{% if account.income_current != 0 %}
|
|
||||||
<div class="text-end">
|
|
||||||
<c-amount.display
|
|
||||||
:amount="account.income_current"
|
|
||||||
:prefix="account.currency.prefix"
|
|
||||||
:suffix="account.currency.suffix"
|
|
||||||
:decimal_places="account.currency.decimal_places"
|
|
||||||
color="green"></c-amount.display>
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
<div class="text-end ">-</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% if account.exchanged and account.exchanged.income_current %}
|
|
||||||
<div class="text-end">
|
|
||||||
<c-amount.display
|
|
||||||
:amount="account.exchanged.income_current"
|
|
||||||
:prefix="account.exchanged.currency.prefix"
|
|
||||||
:suffix="account.exchanged.currency.suffix"
|
|
||||||
:decimal_places="account.exchanged.currency.decimal_places"
|
|
||||||
color="gray"></c-amount.display>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
<div class="flex justify-between items-baseline mt-2">
|
|
||||||
<div class="text-end ">
|
|
||||||
<div class="text-subtle">{% translate 'current expenses' %}</div>
|
|
||||||
</div>
|
|
||||||
<div class="dotted-line"></div>
|
|
||||||
{% if account.expense_current != 0 %}
|
|
||||||
<div class="text-end">
|
|
||||||
<c-amount.display
|
|
||||||
:amount="account.expense_current"
|
|
||||||
:prefix="account.currency.prefix"
|
|
||||||
:suffix="account.currency.suffix"
|
|
||||||
:decimal_places="account.currency.decimal_places"
|
|
||||||
color="red"></c-amount.display>
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
<div class="text-end ">-</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% if account.exchanged and account.exchanged.expense_current %}
|
|
||||||
<div class="text-end">
|
|
||||||
<c-amount.display
|
|
||||||
:amount="account.exchanged.expense_current"
|
|
||||||
:prefix="account.exchanged.currency.prefix"
|
|
||||||
:suffix="account.exchanged.currency.suffix"
|
|
||||||
:decimal_places="account.exchanged.currency.decimal_places"
|
|
||||||
color="gray"></c-amount.display>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
<div class="flex justify-between items-baseline mt-2">
|
|
||||||
<div class="text-end ">
|
|
||||||
<div class="text-subtle">{% translate 'current total' %}</div>
|
|
||||||
</div>
|
|
||||||
<div class="dotted-linegrow"></div>
|
|
||||||
<div class="text-end ">
|
|
||||||
<c-amount.display
|
|
||||||
:amount="account.total_current"
|
|
||||||
:prefix="account.currency.prefix"
|
|
||||||
:suffix="account.currency.suffix"
|
|
||||||
:decimal_places="account.currency.decimal_places"
|
|
||||||
color="{% if account.total_current > 0 %}green{% elif account.total_current < 0 %}red{% endif %}"></c-amount.display>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% if account.exchanged and account.exchanged.total_current %}
|
|
||||||
<div class="text-end">
|
|
||||||
<c-amount.display
|
|
||||||
:amount="account.exchanged.total_current"
|
|
||||||
:prefix="account.exchanged.currency.prefix"
|
|
||||||
:suffix="account.exchanged.currency.suffix"
|
|
||||||
:decimal_places="account.exchanged.currency.decimal_places"
|
|
||||||
color="gray"></c-amount.display>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
<div>
|
|
||||||
<hr class="my-3">
|
|
||||||
<div class="flex justify-between items-baseline mt-2">
|
|
||||||
<div class="text-end ">
|
|
||||||
<div class="text-subtle">{% translate 'final total' %}</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="dotted-line grow"></div>
|
</div>
|
||||||
<div class="text-end ">
|
<div class="card-data-row">
|
||||||
|
<span class="card-data-label">{% translate 'current expenses' %}</span>
|
||||||
|
<div class="card-data-values">
|
||||||
|
{% if account.expense_current != 0 %}
|
||||||
|
<c-amount.display
|
||||||
|
:amount="account.expense_current"
|
||||||
|
:prefix="account.currency.prefix"
|
||||||
|
:suffix="account.currency.suffix"
|
||||||
|
:decimal_places="account.currency.decimal_places"
|
||||||
|
color="red"></c-amount.display>
|
||||||
|
{% if account.exchanged and account.exchanged.expense_current %}
|
||||||
|
<c-amount.display
|
||||||
|
:amount="account.exchanged.expense_current"
|
||||||
|
:prefix="account.exchanged.currency.prefix"
|
||||||
|
:suffix="account.exchanged.currency.suffix"
|
||||||
|
:decimal_places="account.exchanged.currency.decimal_places"
|
||||||
|
color="gray"></c-amount.display>
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
<span class="font-semibold">-</span>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-data-row">
|
||||||
|
<span class="card-data-label">{% translate 'current total' %}</span>
|
||||||
|
<div class="card-data-values">
|
||||||
|
<c-amount.display
|
||||||
|
:amount="account.total_current"
|
||||||
|
:prefix="account.currency.prefix"
|
||||||
|
:suffix="account.currency.suffix"
|
||||||
|
:decimal_places="account.currency.decimal_places"
|
||||||
|
color="{% if account.total_current > 0 %}green{% elif account.total_current < 0 %}red{% endif %}"></c-amount.display>
|
||||||
|
{% if account.exchanged and account.exchanged.total_current %}
|
||||||
|
<c-amount.display
|
||||||
|
:amount="account.exchanged.total_current"
|
||||||
|
:prefix="account.exchanged.currency.prefix"
|
||||||
|
:suffix="account.exchanged.currency.suffix"
|
||||||
|
:decimal_places="account.exchanged.currency.decimal_places"
|
||||||
|
color="gray"></c-amount.display>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr class="card-data-divider" />
|
||||||
|
<div class="card-data-section">
|
||||||
|
<div class="card-data-row">
|
||||||
|
<span class="card-data-label">{% translate 'final total' %}</span>
|
||||||
|
<div class="card-data-values">
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="account.total_final"
|
:amount="account.total_final"
|
||||||
:prefix="account.currency.prefix"
|
:prefix="account.currency.prefix"
|
||||||
:suffix="account.currency.suffix"
|
:suffix="account.currency.suffix"
|
||||||
:decimal_places="account.currency.decimal_places"
|
:decimal_places="account.currency.decimal_places"
|
||||||
color="{% if account.total_final > 0 %}green{% elif account.total_final < 0 %}red{% endif %}"></c-amount.display>
|
color="{% if account.total_final > 0 %}green{% elif account.total_final < 0 %}red{% endif %}"></c-amount.display>
|
||||||
|
{% if account.exchanged and account.exchanged.total_final %}
|
||||||
|
<c-amount.display
|
||||||
|
:amount="account.exchanged.total_final"
|
||||||
|
:prefix="account.exchanged.currency.prefix"
|
||||||
|
:suffix="account.exchanged.currency.suffix"
|
||||||
|
:decimal_places="account.exchanged.currency.decimal_places"
|
||||||
|
color="gray"></c-amount.display>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% if account.exchanged and account.exchanged.total_final %}
|
|
||||||
<div class="text-end">
|
|
||||||
<c-amount.display
|
|
||||||
:amount="account.exchanged.total_final"
|
|
||||||
:prefix="account.exchanged.currency.prefix"
|
|
||||||
:suffix="account.exchanged.currency.suffix"
|
|
||||||
:decimal_places="account.exchanged.currency.decimal_places"
|
|
||||||
color="gray"></c-amount.display>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
{% with p=percentages|get_dict_item:account_id %}
|
{% with p=percentages|get_dict_item:account_id %}
|
||||||
<div class="my-3">
|
<div class="my-3">
|
||||||
|
|||||||
@@ -2,198 +2,165 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
<div class="col card bg-base-100 shadow card-border">
|
<div class="col card bg-base-100 shadow card-border">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5 class="card-title">
|
<h5 class="card-title mb-4">
|
||||||
{{ currency.currency.name }}
|
{{ currency.currency.name }}
|
||||||
</h5>
|
</h5>
|
||||||
<div class="flex justify-between items-baseline mt-2">
|
<div class="card-data-section">
|
||||||
<div class="text-end">
|
<div class="card-data-row">
|
||||||
<div class="text-subtle">{% translate 'projected income' %}</div>
|
<span class="card-data-label">{% translate 'projected income' %}</span>
|
||||||
|
<div class="card-data-values">
|
||||||
|
{% if currency.income_projected != 0 %}
|
||||||
|
<c-amount.display
|
||||||
|
:amount="currency.income_projected"
|
||||||
|
:prefix="currency.currency.prefix"
|
||||||
|
:suffix="currency.currency.suffix"
|
||||||
|
:decimal_places="currency.currency.decimal_places"
|
||||||
|
color="green"></c-amount.display>
|
||||||
|
{% if currency.exchanged and currency.exchanged.income_projected %}
|
||||||
|
<c-amount.display
|
||||||
|
:amount="currency.exchanged.income_projected"
|
||||||
|
:prefix="currency.exchanged.currency.prefix"
|
||||||
|
:suffix="currency.exchanged.currency.suffix"
|
||||||
|
:decimal_places="currency.exchanged.currency.decimal_places"
|
||||||
|
color="gray"></c-amount.display>
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
<span class="font-semibold">-</span>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="dotted-line grow"></div>
|
<div class="card-data-row">
|
||||||
{% if currency.income_projected != 0 %}
|
<span class="card-data-label">{% translate 'projected expenses' %}</span>
|
||||||
<div class="text-end">
|
<div class="card-data-values">
|
||||||
<c-amount.display
|
{% if currency.expense_projected != 0 %}
|
||||||
:amount="currency.income_projected"
|
<c-amount.display
|
||||||
:prefix="currency.currency.prefix"
|
:amount="currency.expense_projected"
|
||||||
:suffix="currency.currency.suffix"
|
:prefix="currency.currency.prefix"
|
||||||
:decimal_places="currency.currency.decimal_places"
|
:suffix="currency.currency.suffix"
|
||||||
color="green"></c-amount.display>
|
:decimal_places="currency.currency.decimal_places"
|
||||||
|
color="red"></c-amount.display>
|
||||||
|
{% if currency.exchanged and currency.exchanged.expense_projected %}
|
||||||
|
<c-amount.display
|
||||||
|
:amount="currency.exchanged.expense_projected"
|
||||||
|
:prefix="currency.exchanged.currency.prefix"
|
||||||
|
:suffix="currency.exchanged.currency.suffix"
|
||||||
|
:decimal_places="currency.exchanged.currency.decimal_places"
|
||||||
|
color="gray"></c-amount.display>
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
<span class="font-semibold">-</span>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
<div class="card-data-row">
|
||||||
<div class="text-end">-</div>
|
<span class="card-data-label">{% translate 'projected total' %}</span>
|
||||||
{% endif %}
|
<div class="card-data-values">
|
||||||
</div>
|
|
||||||
{% if currency.exchanged and currency.exchanged.income_projected %}
|
|
||||||
<div class="text-end">
|
|
||||||
<c-amount.display
|
|
||||||
:amount="currency.exchanged.income_projected"
|
|
||||||
:prefix="currency.exchanged.currency.prefix"
|
|
||||||
:suffix="currency.exchanged.currency.suffix"
|
|
||||||
:decimal_places="currency.exchanged.currency.decimal_places"
|
|
||||||
color="gray"></c-amount.display>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
<div class="flex justify-between items-baseline mt-2">
|
|
||||||
<div class="text-end">
|
|
||||||
<div class="text-subtle">{% translate 'projected expenses' %}</div>
|
|
||||||
</div>
|
|
||||||
<div class="dotted-line grow"></div>
|
|
||||||
<div>
|
|
||||||
{% if currency.expense_projected != 0 %}
|
|
||||||
<div class="text-end">
|
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="currency.expense_projected"
|
:amount="currency.total_projected"
|
||||||
:prefix="currency.currency.prefix"
|
:prefix="currency.currency.prefix"
|
||||||
:suffix="currency.currency.suffix"
|
:suffix="currency.currency.suffix"
|
||||||
:decimal_places="currency.currency.decimal_places"
|
:decimal_places="currency.currency.decimal_places"
|
||||||
color="red"></c-amount.display>
|
color="{% if currency.total_projected > 0 %}green{% elif currency.total_projected < 0 %}red{% endif %}"></c-amount.display>
|
||||||
|
{% if currency.exchanged.total_projected and currency.exchanged.total_projected %}
|
||||||
|
<c-amount.display
|
||||||
|
:amount="currency.exchanged.total_projected"
|
||||||
|
:prefix="currency.exchanged.currency.prefix"
|
||||||
|
:suffix="currency.exchanged.currency.suffix"
|
||||||
|
:decimal_places="currency.exchanged.currency.decimal_places"
|
||||||
|
color="gray"></c-amount.display>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
|
||||||
<div class="text-end">-</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% if currency.exchanged and currency.exchanged.expense_projected %}
|
<hr class="card-data-divider" />
|
||||||
<div class="text-end">
|
<div class="card-data-section">
|
||||||
<c-amount.display
|
<div class="card-data-row">
|
||||||
:amount="currency.exchanged.expense_projected"
|
<span class="card-data-label">{% translate 'current income' %}</span>
|
||||||
:prefix="currency.exchanged.currency.prefix"
|
<div class="card-data-values">
|
||||||
:suffix="currency.exchanged.currency.suffix"
|
{% if currency.income_current != 0 %}
|
||||||
:decimal_places="currency.exchanged.currency.decimal_places"
|
<c-amount.display
|
||||||
color="gray"></c-amount.display>
|
:amount="currency.income_current"
|
||||||
</div>
|
:prefix="currency.currency.prefix"
|
||||||
{% endif %}
|
:suffix="currency.currency.suffix"
|
||||||
<div class="flex justify-between items-baseline mt-2">
|
:decimal_places="currency.currency.decimal_places"
|
||||||
<div class="text-end">
|
color="green"></c-amount.display>
|
||||||
<div class="text-subtle">{% translate 'projected total' %}</div>
|
{% if currency.exchanged and currency.exchanged.income_current %}
|
||||||
</div>
|
<c-amount.display
|
||||||
<div class="dotted-linegrow"></div>
|
:amount="currency.exchanged.income_current"
|
||||||
<div class="text-end">
|
:prefix="currency.exchanged.currency.prefix"
|
||||||
<c-amount.display
|
:suffix="currency.exchanged.currency.suffix"
|
||||||
:amount="currency.total_projected"
|
:decimal_places="currency.exchanged.currency.decimal_places"
|
||||||
:prefix="currency.currency.prefix"
|
color="gray"></c-amount.display>
|
||||||
:suffix="currency.currency.suffix"
|
{% endif %}
|
||||||
:decimal_places="currency.currency.decimal_places"
|
{% else %}
|
||||||
color="{% if currency.total_projected > 0 %}green{% elif currency.total_projected < 0 %}red{% endif %}"></c-amount.display>
|
<span class="font-semibold">-</span>
|
||||||
</div>
|
{% endif %}
|
||||||
</div>
|
|
||||||
{% if currency.exchanged.total_projected and currency.exchanged.total_projected %}
|
|
||||||
<div class="text-end">
|
|
||||||
<c-amount.display
|
|
||||||
:amount="currency.exchanged.total_projected"
|
|
||||||
:prefix="currency.exchanged.currency.prefix"
|
|
||||||
:suffix="currency.exchanged.currency.suffix"
|
|
||||||
:decimal_places="currency.exchanged.currency.decimal_places"
|
|
||||||
color="gray"></c-amount.display>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
<hr class="my-3 hr">
|
|
||||||
<div class="flex justify-between items-baseline mt-2">
|
|
||||||
<div class="text-end">
|
|
||||||
<div class="text-subtle">{% translate 'current income' %}</div>
|
|
||||||
</div>
|
|
||||||
<div class="dotted-line grow"></div>
|
|
||||||
{% if currency.income_current != 0 %}
|
|
||||||
<div class="text-end">
|
|
||||||
<c-amount.display
|
|
||||||
:amount="currency.income_current"
|
|
||||||
:prefix="currency.currency.prefix"
|
|
||||||
:suffix="currency.currency.suffix"
|
|
||||||
:decimal_places="currency.currency.decimal_places"
|
|
||||||
color="green"></c-amount.display>
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
<div class="text-end">-</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% if currency.exchanged and currency.exchanged.income_current %}
|
|
||||||
<div class="text-end">
|
|
||||||
<c-amount.display
|
|
||||||
:amount="currency.exchanged.income_current"
|
|
||||||
:prefix="currency.exchanged.currency.prefix"
|
|
||||||
:suffix="currency.exchanged.currency.suffix"
|
|
||||||
:decimal_places="currency.exchanged.currency.decimal_places"
|
|
||||||
color="gray"></c-amount.display>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
<div class="flex justify-between items-baseline mt-2">
|
|
||||||
<div class="text-end">
|
|
||||||
<div class="text-subtle">{% translate 'current expenses' %}</div>
|
|
||||||
</div>
|
|
||||||
<div class="dotted-line grow"></div>
|
|
||||||
{% if currency.expense_current != 0 %}
|
|
||||||
<div class="text-end">
|
|
||||||
<c-amount.display
|
|
||||||
:amount="currency.expense_current"
|
|
||||||
:prefix="currency.currency.prefix"
|
|
||||||
:suffix="currency.currency.suffix"
|
|
||||||
:decimal_places="currency.currency.decimal_places"
|
|
||||||
color="red"></c-amount.display>
|
|
||||||
</div>
|
|
||||||
{% else %}
|
|
||||||
<div class="text-end">-</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
||||||
{% if currency.exchanged and currency.exchanged.expense_current %}
|
|
||||||
<div class="text-end">
|
|
||||||
<c-amount.display
|
|
||||||
:amount="currency.exchanged.expense_current"
|
|
||||||
:prefix="currency.exchanged.currency.prefix"
|
|
||||||
:suffix="currency.exchanged.currency.suffix"
|
|
||||||
:decimal_places="currency.exchanged.currency.decimal_places"
|
|
||||||
color="gray"></c-amount.display>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
<div class="flex justify-between items-baseline mt-2">
|
|
||||||
<div class="text-end">
|
|
||||||
<div class="text-subtle">{% translate 'current total' %}</div>
|
|
||||||
</div>
|
|
||||||
<div class="dotted-line grow"></div>
|
|
||||||
<div class="text-end">
|
|
||||||
<c-amount.display
|
|
||||||
:amount="currency.total_current"
|
|
||||||
:prefix="currency.currency.prefix"
|
|
||||||
:suffix="currency.currency.suffix"
|
|
||||||
:decimal_places="currency.currency.decimal_places"
|
|
||||||
color="{% if currency.total_current > 0 %}green{% elif currency.total_current < 0 %}red{% endif %}"></c-amount.display>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% if currency.exchanged and currency.exchanged.total_current %}
|
|
||||||
<div class="text-end">
|
|
||||||
<c-amount.display
|
|
||||||
:amount="currency.exchanged.total_current"
|
|
||||||
:prefix="currency.exchanged.currency.prefix"
|
|
||||||
:suffix="currency.exchanged.currency.suffix"
|
|
||||||
:decimal_places="currency.exchanged.currency.decimal_places"
|
|
||||||
color="gray"></c-amount.display>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
<div>
|
|
||||||
<hr class="my-3 hr">
|
|
||||||
<div class="flex justify-between items-baseline mt-2">
|
|
||||||
<div class="text-end">
|
|
||||||
<div class="text-subtle">{% translate 'final total' %}</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="dotted-line grow"></div>
|
</div>
|
||||||
<div class="text-end">
|
<div class="card-data-row">
|
||||||
|
<span class="card-data-label">{% translate 'current expenses' %}</span>
|
||||||
|
<div class="card-data-values">
|
||||||
|
{% if currency.expense_current != 0 %}
|
||||||
|
<c-amount.display
|
||||||
|
:amount="currency.expense_current"
|
||||||
|
:prefix="currency.currency.prefix"
|
||||||
|
:suffix="currency.currency.suffix"
|
||||||
|
:decimal_places="currency.currency.decimal_places"
|
||||||
|
color="red"></c-amount.display>
|
||||||
|
{% if currency.exchanged and currency.exchanged.expense_current %}
|
||||||
|
<c-amount.display
|
||||||
|
:amount="currency.exchanged.expense_current"
|
||||||
|
:prefix="currency.exchanged.currency.prefix"
|
||||||
|
:suffix="currency.exchanged.currency.suffix"
|
||||||
|
:decimal_places="currency.exchanged.currency.decimal_places"
|
||||||
|
color="gray"></c-amount.display>
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
<span class="font-semibold">-</span>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-data-row">
|
||||||
|
<span class="card-data-label">{% translate 'current total' %}</span>
|
||||||
|
<div class="card-data-values">
|
||||||
|
<c-amount.display
|
||||||
|
:amount="currency.total_current"
|
||||||
|
:prefix="currency.currency.prefix"
|
||||||
|
:suffix="currency.currency.suffix"
|
||||||
|
:decimal_places="currency.currency.decimal_places"
|
||||||
|
color="{% if currency.total_current > 0 %}green{% elif currency.total_current < 0 %}red{% endif %}"></c-amount.display>
|
||||||
|
{% if currency.exchanged and currency.exchanged.total_current %}
|
||||||
|
<c-amount.display
|
||||||
|
:amount="currency.exchanged.total_current"
|
||||||
|
:prefix="currency.exchanged.currency.prefix"
|
||||||
|
:suffix="currency.exchanged.currency.suffix"
|
||||||
|
:decimal_places="currency.exchanged.currency.decimal_places"
|
||||||
|
color="gray"></c-amount.display>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr class="card-data-divider" />
|
||||||
|
<div class="card-data-section">
|
||||||
|
<div class="card-data-row">
|
||||||
|
<span class="card-data-label">{% translate 'final total' %}</span>
|
||||||
|
<div class="card-data-values">
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="currency.total_final"
|
:amount="currency.total_final"
|
||||||
:prefix="currency.currency.prefix"
|
:prefix="currency.currency.prefix"
|
||||||
:suffix="currency.currency.suffix"
|
:suffix="currency.currency.suffix"
|
||||||
:decimal_places="currency.currency.decimal_places"
|
:decimal_places="currency.currency.decimal_places"
|
||||||
color="{% if currency.total_final > 0 %}green{% elif currency.total_final < 0 %}red{% endif %}"></c-amount.display>
|
color="{% if currency.total_final > 0 %}green{% elif currency.total_final < 0 %}red{% endif %}"></c-amount.display>
|
||||||
|
{% if currency.exchanged and currency.exchanged.total_final %}
|
||||||
|
<c-amount.display
|
||||||
|
:amount="currency.exchanged.total_final"
|
||||||
|
:prefix="currency.exchanged.currency.prefix"
|
||||||
|
:suffix="currency.exchanged.currency.suffix"
|
||||||
|
:decimal_places="currency.exchanged.currency.decimal_places"
|
||||||
|
color="gray"></c-amount.display>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% if currency.exchanged and currency.exchanged.total_final %}
|
|
||||||
<div class="text-end">
|
|
||||||
<c-amount.display
|
|
||||||
:amount="currency.exchanged.total_final"
|
|
||||||
:prefix="currency.exchanged.currency.prefix"
|
|
||||||
:suffix="currency.exchanged.currency.suffix"
|
|
||||||
:decimal_places="currency.exchanged.currency.decimal_places"
|
|
||||||
color="gray"></c-amount.display>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
{% with p=percentages|get_dict_item:currency_id %}
|
{% with p=percentages|get_dict_item:currency_id %}
|
||||||
<div class="my-3">
|
<div class="my-3">
|
||||||
|
|||||||
@@ -80,7 +80,7 @@
|
|||||||
data-tippy-content="{% translate 'Duplicate' %}">
|
data-tippy-content="{% translate 'Duplicate' %}">
|
||||||
<i class="fa-solid fa-clone fa-fw"></i>
|
<i class="fa-solid fa-clone fa-fw"></i>
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-secondary btn-sm"
|
<button class="btn btn-error btn-sm"
|
||||||
hx-get="{% url 'transactions_bulk_delete' %}"
|
hx-get="{% url 'transactions_bulk_delete' %}"
|
||||||
hx-include=".transaction"
|
hx-include=".transaction"
|
||||||
hx-trigger="confirmed"
|
hx-trigger="confirmed"
|
||||||
@@ -90,7 +90,7 @@
|
|||||||
data-text="{% translate "You won't be able to revert this!" %}"
|
data-text="{% translate "You won't be able to revert this!" %}"
|
||||||
data-confirm-text="{% translate "Yes, delete them!" %}"
|
data-confirm-text="{% translate "Yes, delete them!" %}"
|
||||||
_="install prompt_swal">
|
_="install prompt_swal">
|
||||||
<i class="fa-solid fa-trash text-error"></i>
|
<i class="fa-solid fa-trash"></i>
|
||||||
</button>
|
</button>
|
||||||
<div class="divider divider-horizontal m-0"></div>
|
<div class="divider divider-horizontal m-0"></div>
|
||||||
<div class="join"
|
<div class="join"
|
||||||
@@ -139,7 +139,7 @@
|
|||||||
wait 1s
|
wait 1s
|
||||||
put original_value into #real-total-front's innerText
|
put original_value into #real-total-front's innerText
|
||||||
end">
|
end">
|
||||||
<i class="fa-solid fa-plus fa-fw me-md-2 text-primary"></i>
|
<i class="fa-solid fa-plus fa-fw me-md-2"></i>
|
||||||
<span class="hidden md:inline-block" id="real-total-front">0</span>
|
<span class="hidden md:inline-block" id="real-total-front">0</span>
|
||||||
</button>
|
</button>
|
||||||
<div class="dropdown dropdown-end dropdown-top">
|
<div class="dropdown dropdown-end dropdown-top">
|
||||||
@@ -147,7 +147,7 @@
|
|||||||
<i class="fa-solid fa-chevron-down fa-xs"></i>
|
<i class="fa-solid fa-chevron-down fa-xs"></i>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<ul tabindex="0" class="dropdown-content menu bg-base-300 rounded-box z-[1] w-full shadow fixed!">
|
<ul tabindex="0" class="dropdown-content menu bg-base-300 rounded-box w-full shadow fixed! flex flex-col gap-1">
|
||||||
<li class="cursor-pointer"
|
<li class="cursor-pointer"
|
||||||
_="on click
|
_="on click
|
||||||
set original_value to #calc-menu-flat-total's innerText
|
set original_value to #calc-menu-flat-total's innerText
|
||||||
@@ -156,13 +156,12 @@
|
|||||||
wait 1s
|
wait 1s
|
||||||
put original_value into #calc-menu-flat-total
|
put original_value into #calc-menu-flat-total
|
||||||
end">
|
end">
|
||||||
<div class="p-0">
|
<div class="py-1 px-3">
|
||||||
<div>
|
<div>
|
||||||
<div class="text-base-content/60 text-xs font-medium px-3">
|
<div class="text-base-content/60 text-xs font-medium">
|
||||||
{% trans "Flat Total" %}
|
{% trans "Flat Total" %}
|
||||||
</div>
|
</div>
|
||||||
<div class="px-3"
|
<div id="calc-menu-flat-total">
|
||||||
id="calc-menu-flat-total">
|
|
||||||
0
|
0
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -176,13 +175,12 @@
|
|||||||
wait 1s
|
wait 1s
|
||||||
put original_value into #calc-menu-real-total
|
put original_value into #calc-menu-real-total
|
||||||
end">
|
end">
|
||||||
<div class="p-0">
|
<div class="py-1 px-3">
|
||||||
<div>
|
<div>
|
||||||
<div class="text-base-content/60 text-xs font-medium px-3">
|
<div class="text-base-content/60 text-xs font-medium">
|
||||||
{% trans "Real Total" %}
|
{% trans "Real Total" %}
|
||||||
</div>
|
</div>
|
||||||
<div class="px-3"
|
<div id="calc-menu-real-total">
|
||||||
id="calc-menu-real-total">
|
|
||||||
0
|
0
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -196,13 +194,12 @@
|
|||||||
wait 1s
|
wait 1s
|
||||||
put original_value into #calc-menu-mean
|
put original_value into #calc-menu-mean
|
||||||
end">
|
end">
|
||||||
<div class="p-0">
|
<div class="p-1 px-3">
|
||||||
<div>
|
<div>
|
||||||
<div class="text-base-content/60 text-xs font-medium px-3">
|
<div class="text-base-content/60 text-xs font-medium">
|
||||||
{% trans "Mean" %}
|
{% trans "Mean" %}
|
||||||
</div>
|
</div>
|
||||||
<div class="px-3"
|
<div id="calc-menu-mean">
|
||||||
id="calc-menu-mean">
|
|
||||||
0
|
0
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -216,13 +213,12 @@
|
|||||||
wait 1s
|
wait 1s
|
||||||
put original_value into #calc-menu-max
|
put original_value into #calc-menu-max
|
||||||
end">
|
end">
|
||||||
<div class="p-0">
|
<div class="py-1 px-3">
|
||||||
<div>
|
<div>
|
||||||
<div class="text-base-content/60 text-xs font-medium px-3">
|
<div class="text-base-content/60 text-xs font-medium">
|
||||||
{% trans "Max" %}
|
{% trans "Max" %}
|
||||||
</div>
|
</div>
|
||||||
<div class="px-3"
|
<div id="calc-menu-max">
|
||||||
id="calc-menu-max">
|
|
||||||
0
|
0
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -236,13 +232,12 @@
|
|||||||
wait 1s
|
wait 1s
|
||||||
put original_value into #calc-menu-min
|
put original_value into #calc-menu-min
|
||||||
end">
|
end">
|
||||||
<div class="p-0">
|
<div class="py-1 px-3">
|
||||||
<div>
|
<div>
|
||||||
<div class="text-base-content/60 text-xs font-medium px-3">
|
<div class="text-base-content/60 text-xs font-medium">
|
||||||
{% trans "Min" %}
|
{% trans "Min" %}
|
||||||
</div>
|
</div>
|
||||||
<div class="px-3"
|
<div id="calc-menu-min">
|
||||||
id="calc-menu-min">
|
|
||||||
0
|
0
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -256,13 +251,12 @@
|
|||||||
wait 1s
|
wait 1s
|
||||||
put original_value into #calc-menu-count
|
put original_value into #calc-menu-count
|
||||||
end">
|
end">
|
||||||
<div class="p-0">
|
<div class="py-1 px-3">
|
||||||
<div>
|
<div>
|
||||||
<div class="text-base-content/60 text-xs font-medium px-3">
|
<div class="text-base-content/60 text-xs font-medium">
|
||||||
{% trans "Count" %}
|
{% trans "Count" %}
|
||||||
</div>
|
</div>
|
||||||
<div class="px-3"
|
<div id="calc-menu-count">
|
||||||
id="calc-menu-count">
|
|
||||||
0
|
0
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
{% vite_hmr_client %}
|
{% vite_hmr_client %}
|
||||||
|
|
||||||
{% vite_asset 'bootstrap.js' defer=True %}
|
{% vite_asset 'main.js' defer=True %}
|
||||||
{% vite_asset 'sweetalert2.js' defer=True %}
|
{% comment %} {% vite_asset 'sweetalert2.js' defer=True %}
|
||||||
{% vite_asset 'select.js' defer=True %}
|
{% vite_asset 'select.js' defer=True %}
|
||||||
{% vite_asset 'datepicker.js' %}
|
{% vite_asset 'datepicker.js' %}
|
||||||
{% vite_asset 'autosize.js' defer=True %}
|
{% vite_asset 'autosize.js' defer=True %} {% endcomment %}
|
||||||
|
|
||||||
{% include 'includes/scripts/hyperscript/init_tom_select.html' %}
|
{% include 'includes/scripts/hyperscript/init_tom_select.html' %}
|
||||||
{% include 'includes/scripts/hyperscript/init_date_picker.html' %}
|
{% include 'includes/scripts/hyperscript/init_date_picker.html' %}
|
||||||
@@ -16,10 +16,10 @@
|
|||||||
{% include 'includes/scripts/hyperscript/sounds.html' %}
|
{% include 'includes/scripts/hyperscript/sounds.html' %}
|
||||||
{% include 'includes/scripts/hyperscript/swal.html' %}
|
{% include 'includes/scripts/hyperscript/swal.html' %}
|
||||||
|
|
||||||
{% vite_asset 'htmx.js' defer=True %}
|
{% comment %} {% vite_asset 'htmx.js' defer=True %}
|
||||||
{% vite_asset 'charts.js' %}
|
{% vite_asset 'charts.js' %}
|
||||||
|
|
||||||
{% vite_asset 'style.js' %}
|
{% vite_asset 'style.js' %} {% endcomment %}
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
let tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
let tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||||
|
|||||||
@@ -11,13 +11,22 @@
|
|||||||
set elements to <.amount/> in me
|
set elements to <.amount/> in me
|
||||||
for el in elements
|
for el in elements
|
||||||
set el.textContent to el.dataset.originalValue
|
set el.textContent to el.dataset.originalValue
|
||||||
|
set el.innerHTML to `<span>${el.dataset.originalSign}</span><span>${el.dataset.originalPrefix}</span><span>${el.dataset.originalAmount}</span><span>${el.dataset.originalSuffix}</span>`
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
on click[target matches .amount] if I include #settings-hide-amounts
|
on click[target matches .amount or target.parentNode matches .amount] if I include #settings-hide-amounts
|
||||||
if event.target do not matches .revealed then set event.target.textContent to event.target.dataset.originalValue
|
if event.target matches .amount
|
||||||
else set event.target.textContent to '•••••••••••' end
|
set el to event.target
|
||||||
then toggle .revealed on event.target
|
else
|
||||||
|
set el to event.target.parentNode
|
||||||
|
end
|
||||||
|
|
||||||
|
if el do not matches .revealed
|
||||||
|
then set el.innerHTML to `<span>${el.dataset.originalSign}</span><span>${el.dataset.originalPrefix}</span><span>${el.dataset.originalAmount}</span><span>${el.dataset.originalSuffix}</span>`
|
||||||
|
else
|
||||||
|
set el.textContent to '•••••••••••' end
|
||||||
|
then toggle .revealed on el
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -59,7 +59,7 @@
|
|||||||
{
|
{
|
||||||
label: "{% trans 'Projected Expenses' %}",
|
label: "{% trans 'Projected Expenses' %}",
|
||||||
data: accountData.datasets[3].data,
|
data: accountData.datasets[3].data,
|
||||||
backgroundColor: '#f8717180', // Added transparency
|
backgroundColor: '#f8717180',
|
||||||
stack: 'stack0'
|
stack: 'stack0'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -77,7 +77,7 @@
|
|||||||
{
|
{
|
||||||
label: "{% trans 'Projected Income' %}",
|
label: "{% trans 'Projected Income' %}",
|
||||||
data: accountData.datasets[2].data,
|
data: accountData.datasets[2].data,
|
||||||
backgroundColor: '#4dde8080', // Added transparency
|
backgroundColor: '#4dde8080',
|
||||||
stack: 'stack0'
|
stack: 'stack0'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,7 @@
|
|||||||
{
|
{
|
||||||
label: "{% trans 'Projected Expenses' %}",
|
label: "{% trans 'Projected Expenses' %}",
|
||||||
data: currencyData.datasets[3].data,
|
data: currencyData.datasets[3].data,
|
||||||
backgroundColor: '#f8717180', // Added transparency
|
backgroundColor: '#f8717180',
|
||||||
stack: 'stack0'
|
stack: 'stack0'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -77,7 +77,7 @@
|
|||||||
{
|
{
|
||||||
label: "{% trans 'Projected Income' %}",
|
label: "{% trans 'Projected Income' %}",
|
||||||
data: currencyData.datasets[2].data,
|
data: currencyData.datasets[2].data,
|
||||||
backgroundColor: '#4dde8080', // Added transparency
|
backgroundColor: '#4dde8080',
|
||||||
stack: 'stack0'
|
stack: 'stack0'
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -1,37 +1,45 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load crispy_forms_tags %}
|
{% load crispy_forms_tags %}
|
||||||
|
|
||||||
<form _="install init_tom_select
|
<div class="flex flex-col gap-3">
|
||||||
on change trigger updated
|
<div class="row">
|
||||||
init trigger updated" id="category-form">
|
<div class="col-12">
|
||||||
{% crispy category_form %}
|
<div class="card card-border bg-base-100">
|
||||||
</form>
|
<div class="card-body">
|
||||||
|
<form _="install init_tom_select
|
||||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-3">
|
on change trigger updated
|
||||||
<div class="w-full">
|
init trigger updated" id="category-form">
|
||||||
<div class="card bg-base-100 shadow-xl h-full">
|
{% crispy category_form %}
|
||||||
<div class="card-header bg-base-200 p-4 font-semibold">
|
</form>
|
||||||
{% trans "Income/Expense by Account" %}
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<div id="account-card" class="show-loading" hx-get="{% url 'category_sum_by_account' %}"
|
|
||||||
hx-trigger="updated from:window" hx-include="#category-form, #picker-form, #picker-type">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="w-full">
|
|
||||||
<div class="card bg-base-100 shadow-xl h-full">
|
|
||||||
<div class="card-header bg-base-200 p-4 font-semibold">
|
|
||||||
{% trans "Income/Expense by Currency" %}
|
|
||||||
</div>
|
|
||||||
<div class="card-body">
|
|
||||||
<div id="currency-card" class="show-loading" hx-get="{% url 'category_sum_by_currency' %}"
|
|
||||||
hx-trigger="updated from:window" hx-include="#category-form, #picker-form, #picker-type">
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
</div>
|
<div class="col-12 lg:col-6">
|
||||||
|
<div class="card bg-base-100 shadow-xl h-full">
|
||||||
|
<div class="card-header bg-base-200 p-4 font-semibold rounded-box shadow">
|
||||||
|
{% trans "Income/Expense by Account" %}
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div id="account-card" class="show-loading" hx-get="{% url 'category_sum_by_account' %}"
|
||||||
|
hx-trigger="updated from:window" hx-include="#category-form, #picker-form, #picker-type">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 lg:col-6">
|
||||||
|
<div class="card bg-base-100 shadow-xl h-full">
|
||||||
|
<div class="card-header bg-base-200 p-4 font-semibold rounded-box shadow">
|
||||||
|
{% trans "Income/Expense by Currency" %}
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div id="currency-card" class="show-loading" hx-get="{% url 'category_sum_by_currency' %}"
|
||||||
|
hx-trigger="updated from:window" hx-include="#category-form, #picker-form, #picker-type">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -3,56 +3,58 @@
|
|||||||
<div hx-get="{% url 'category_overview' %}" hx-trigger="updated from:window" class="show-loading" hx-swap="outerHTML"
|
<div hx-get="{% url 'category_overview' %}" hx-trigger="updated from:window" class="show-loading" hx-swap="outerHTML"
|
||||||
hx-include="#picker-form, #picker-type, #view-type, #show-tags, #showing, #show-entities">
|
hx-include="#picker-form, #picker-type, #view-type, #show-tags, #showing, #show-entities">
|
||||||
<div class="h-full text-center mb-4">
|
<div class="h-full text-center mb-4">
|
||||||
<div class="join" role="group" id="view-type" _="on change trigger updated">
|
<div class="tabs tabs-box mx-auto w-fit" role="group" id="view-type" _="on change trigger updated">
|
||||||
<input type="radio" class="join-item btn btn-outline btn-primary rounded-full"
|
<label class="tab">
|
||||||
name="view_type"
|
<input type="radio"
|
||||||
id="table-view"
|
name="view_type"
|
||||||
autocomplete="off"
|
id="table-view"
|
||||||
value="table"
|
autocomplete="off"
|
||||||
aria-label="{% trans 'Table' %}"
|
value="table"
|
||||||
{% if view_type == "table" %}checked{% endif %}>
|
aria-label="{% trans 'Table' %}"
|
||||||
|
{% if view_type == "table" %}checked{% endif %}>
|
||||||
<input type="radio"
|
<i class="fa-solid fa-table fa-fw me-2"></i>
|
||||||
class="join-item btn btn-outline btn-primary rounded-full"
|
{% trans 'Table' %}
|
||||||
name="view_type"
|
</label>
|
||||||
id="bars-view"
|
<label class="tab">
|
||||||
autocomplete="off"
|
<input type="radio"
|
||||||
value="bars"
|
name="view_type"
|
||||||
aria-label="{% trans 'Bars' %}"
|
id="bars-view"
|
||||||
{% if view_type == "bars" %}checked{% endif %}>
|
autocomplete="off"
|
||||||
|
value="bars"
|
||||||
|
aria-label="{% trans 'Bars' %}"
|
||||||
|
{% if view_type == "bars" %}checked{% endif %}>
|
||||||
|
<i class="fa-solid fa-chart-bar fa-fw me-2"></i>
|
||||||
|
{% trans 'Bars' %}
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-3 mb-1 flex flex-col md:flex-row justify-between">
|
<div class="my-3 flex flex-col gap-3 md:flex-row justify-between">
|
||||||
<div class="flex gap-4">
|
<div class="flex gap-4">
|
||||||
{% if view_type == 'table' %}
|
{% if view_type == 'table' %}
|
||||||
<div class="form-control" id="show-tags">
|
<div id="show-tags">
|
||||||
<input type="hidden" name="show_tags" value="off">
|
<label class="label">
|
||||||
<label class="label cursor-pointer gap-2">
|
<input type="hidden" name="show_tags" value="off">
|
||||||
<input type="checkbox" class="toggle" id="show-tags-switch" name="show_tags"
|
<input type="checkbox" class="toggle toggle-primary toggle-sm" id="show-tags-switch" name="show_tags"
|
||||||
_="on change trigger updated" {% if show_tags %}checked{% endif %}>
|
_="on change trigger updated" {% if show_tags %}checked{% endif %}>
|
||||||
{% spaceless %}
|
<span>
|
||||||
<span class="label-text">
|
|
||||||
{% trans 'Tags' %}
|
{% trans 'Tags' %}
|
||||||
</span>
|
</span>
|
||||||
<c-ui.help-icon
|
<c-ui.help-icon
|
||||||
content="{% trans 'Transaction amounts associated with multiple tags will be counted once for each tag' %}"
|
content="{% trans 'Transaction amounts associated with multiple tags will be counted once for each tag' %}"
|
||||||
icon="fa-solid fa-circle-exclamation"></c-ui.help-icon>
|
icon="fa-solid fa-circle-exclamation"></c-ui.help-icon>
|
||||||
{% endspaceless %}
|
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-control" id="show-entities" {% if not show_tags %}style="display: none;"{% endif %}>
|
<div id="show-entities" class="{% if not show_tags %}hidden{% endif %}">
|
||||||
<input type="hidden" name="show_entities" value="off">
|
<label class="label">
|
||||||
<label class="label cursor-pointer gap-2">
|
<input type="hidden" name="show_entities" value="off">
|
||||||
<input type="checkbox" class="toggle" id="show-entities-switch" name="show_entities"
|
<input type="checkbox" class="toggle toggle-primary toggle-sm" id="show-entities-switch" name="show_entities"
|
||||||
_="on change trigger updated" {% if show_entities %}checked{% endif %}>
|
_="on change trigger updated" {% if show_entities %}checked{% endif %}>
|
||||||
{% spaceless %}
|
<span>
|
||||||
<span class="label-text">
|
|
||||||
{% trans 'Entities' %}
|
{% trans 'Entities' %}
|
||||||
</span>
|
</span>
|
||||||
<c-ui.help-icon
|
<c-ui.help-icon
|
||||||
content="{% trans 'Transaction amounts associated with multiple tags and entities will be counted once for each tag' %}"
|
content="{% trans 'Transaction amounts associated with multiple tags will be counted once for each tag' %}"
|
||||||
icon="fa-solid fa-circle-exclamation"></c-ui.help-icon>
|
icon="fa-solid fa-circle-exclamation"></c-ui.help-icon>
|
||||||
{% endspaceless %}
|
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@@ -70,8 +72,10 @@
|
|||||||
</div>
|
</div>
|
||||||
{% if total_table %}
|
{% if total_table %}
|
||||||
{% if view_type == "table" %}
|
{% if view_type == "table" %}
|
||||||
<div class="overflow-x-auto">
|
<div class="card bg-base-100 card-border">
|
||||||
<table class="table table-zebra">
|
<c-config.search></c-config.search>
|
||||||
|
<div class="overflow-x-auto">
|
||||||
|
<table class="table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col">{% trans 'Category' %}</th>
|
<th scope="col">{% trans 'Category' %}</th>
|
||||||
@@ -176,7 +180,7 @@
|
|||||||
{% for tag_id, tag in category.tags.items %}
|
{% for tag_id, tag in category.tags.items %}
|
||||||
{% if tag.name or not tag.name and category.tags.values|length > 1 %}
|
{% if tag.name or not tag.name and category.tags.values|length > 1 %}
|
||||||
<tr class="bg-base-200">
|
<tr class="bg-base-200">
|
||||||
<td class="ps-4">
|
<td class="ps-6">
|
||||||
<i class="fa-solid fa-hashtag fa-fw me-2 text-base-content/60"></i>{% if tag.name %}{{ tag.name }}{% else %}{% trans 'Untagged' %}{% endif %}
|
<i class="fa-solid fa-hashtag fa-fw me-2 text-base-content/60"></i>{% if tag.name %}{{ tag.name }}{% else %}{% trans 'Untagged' %}{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@@ -269,7 +273,7 @@
|
|||||||
{% for entity_id, entity in tag.entities.items %}
|
{% for entity_id, entity in tag.entities.items %}
|
||||||
{% if entity.name or not entity.name and tag.entities.values|length > 1 %}
|
{% if entity.name or not entity.name and tag.entities.values|length > 1 %}
|
||||||
<tr class="bg-base-300">
|
<tr class="bg-base-300">
|
||||||
<td class="ps-5">
|
<td class="ps-10">
|
||||||
<i class="fa-solid fa-user-group fa-fw me-2 text-base-content/60"></i>{% if entity.name %}{{ entity.name }}{% else %}{% trans 'No entity' %}{% endif %}
|
<i class="fa-solid fa-user-group fa-fw me-2 text-base-content/60"></i>{% if entity.name %}{{ entity.name }}{% else %}{% trans 'No entity' %}{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@@ -366,13 +370,16 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
{% elif view_type == "bars" %}
|
{% elif view_type == "bars" %}
|
||||||
<div>
|
<div class="card bg-base-100 card-border">
|
||||||
<div class="chart-container relative h-[78vh] w-full" _="init call setupChart() end">
|
<div class="card-body">
|
||||||
<canvas id="categoryChart"></canvas>
|
<div class="chart-container relative h-[75vh] w-full" _="init call setupChart() end">
|
||||||
|
<canvas id="categoryChart"></canvas>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
|
|
||||||
<div hx-get="{% url 'insights_late_transactions' %}" hx-trigger="updated from:window" class="show-loading"
|
<div hx-get="{% url 'insights_latest_transactions' %}" hx-trigger="updated from:window" class="show-loading"
|
||||||
id="transactions-list" hx-swap="outerHTML">
|
id="transactions-list" hx-swap="outerHTML">
|
||||||
{% if transactions %}
|
{% if transactions %}
|
||||||
{% for transaction in transactions %}
|
{% for transaction in transactions %}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<div class="show-loading" hx-get="{% url 'insights_sankey_by_currency' %}" hx-trigger="updated from:window"
|
<div class="show-loading" hx-get="{% url 'insights_sankey_by_currency' %}" hx-trigger="updated from:window"
|
||||||
hx-swap="outerHTML" hx-include="#picker-form, #picker-type">
|
hx-swap="outerHTML" hx-include="#picker-form, #picker-type">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="chart-container relative min-h-[85vh] max-h-[85vh] h-full w-full"
|
<div class="card bg-base-100 card-border chart-container relative min-h-[85vh] max-h-[85vh] h-full w-full"
|
||||||
id="sankeyContainer"
|
id="sankeyContainer"
|
||||||
_="init call setupSankeyChart() end">
|
_="init call setupSankeyChart() end">
|
||||||
<canvas id="sankeyChart"></canvas>
|
<canvas id="sankeyChart"></canvas>
|
||||||
@@ -15,7 +15,14 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
var style = getComputedStyle(document.body);
|
||||||
|
var incomeColor = style.getPropertyValue('--color-success');
|
||||||
|
var expenseColor = style.getPropertyValue('--color-error');
|
||||||
|
var primaryColor = style.getPropertyValue('--color-primary');
|
||||||
|
var contentColor = style.getPropertyValue('--color-base-content');
|
||||||
|
console.log('Sankey colors:', incomeColor, expenseColor, primaryColor, contentColor);
|
||||||
var data = {{ sankey_data|safe }};
|
var data = {{ sankey_data|safe }};
|
||||||
|
console.log(convertColorToRgba(incomeColor))
|
||||||
|
|
||||||
function setupSankeyChart(chartId = 'sankeyChart') {
|
function setupSankeyChart(chartId = 'sankeyChart') {
|
||||||
function formatCurrency(value, currency) {
|
function formatCurrency(value, currency) {
|
||||||
@@ -35,11 +42,11 @@
|
|||||||
const colors = {};
|
const colors = {};
|
||||||
data.nodes.forEach(node => {
|
data.nodes.forEach(node => {
|
||||||
if (node.id.startsWith('income_')) {
|
if (node.id.startsWith('income_')) {
|
||||||
colors[node.id] = '#4dde80'; // Green for income
|
colors[node.id] = convertColorToRgba(incomeColor); // Green for income
|
||||||
} else if (node.id.startsWith('expense_')) {
|
} else if (node.id.startsWith('expense_')) {
|
||||||
colors[node.id] = '#f87171'; // Red for expenses
|
colors[node.id] = convertColorToRgba(expenseColor); // Red for expenses
|
||||||
} else {
|
} else {
|
||||||
colors[node.id] = '#fbb700'; // Primary for others
|
colors[node.id] = convertColorToRgba(primaryColor); // Primary for others
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -63,7 +70,7 @@
|
|||||||
colorMode: 'gradient',
|
colorMode: 'gradient',
|
||||||
alpha: 0.5,
|
alpha: 0.5,
|
||||||
size: 'max',
|
size: 'max',
|
||||||
color: "white",
|
color: contentColor,
|
||||||
nodePadding: 30,
|
nodePadding: 30,
|
||||||
priority: data.nodes.reduce((acc, node) => {
|
priority: data.nodes.reduce((acc, node) => {
|
||||||
acc[node.id] = node.priority;
|
acc[node.id] = node.priority;
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div class="row">
|
<div class="row gy-3">
|
||||||
<div class="col-12 md:col-3">
|
<div class="col-12 md:col-3 gy-3">
|
||||||
<div class="flex flex-col gap-3">
|
<div class="flex flex-col gap-3">
|
||||||
<div class="card bg-base-100 card-borderS">
|
<div class="card bg-base-100 card-borderS">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
@@ -73,22 +73,22 @@
|
|||||||
remove .btn-active from <.insights-list button/>
|
remove .btn-active from <.insights-list button/>
|
||||||
add .btn-active to event.target
|
add .btn-active to event.target
|
||||||
set event.target's @aria-selected to 'true'">
|
set event.target's @aria-selected to 'true'">
|
||||||
<button class="btn btn-ghost justify-start"
|
<button class="btn btn-ghost justify-start text-start"
|
||||||
type="button" role="tab" aria-controls="v-pills-content" aria-selected="false"
|
type="button" role="tab" aria-controls="v-pills-content" aria-selected="false"
|
||||||
hx-get="{% url 'insights_sankey_by_account' %}">
|
hx-get="{% url 'insights_sankey_by_account' %}">
|
||||||
{% trans 'Account Flow' %}
|
{% trans 'Account Flow' %}
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-ghost justify-start" data-bs-target="#v-pills-content"
|
<button class="btn btn-ghost justify-start text-start" data-bs-target="#v-pills-content"
|
||||||
type="button" role="tab" aria-controls="v-pills-content" aria-selected="false"
|
type="button" role="tab" aria-controls="v-pills-content" aria-selected="false"
|
||||||
hx-get="{% url 'insights_sankey_by_currency' %}"
|
hx-get="{% url 'insights_sankey_by_currency' %}"
|
||||||
>{% trans 'Currency Flow' %}
|
>{% trans 'Currency Flow' %}
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-ghost justify-start" data-bs-target="#v-pills-content"
|
<button class="btn btn-ghost justify-start text-start" data-bs-target="#v-pills-content"
|
||||||
type="button" role="tab" aria-controls="v-pills-content" aria-selected="false"
|
type="button" role="tab" aria-controls="v-pills-content" aria-selected="false"
|
||||||
hx-get="{% url 'category_explorer_index' %}">
|
hx-get="{% url 'category_explorer_index' %}">
|
||||||
{% trans 'Category Explorer' %}
|
{% trans 'Category Explorer' %}
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-ghost justify-start" data-bs-target="#v-pills-content"
|
<button class="btn btn-ghost justify-start text-start" data-bs-target="#v-pills-content"
|
||||||
type="button" role="tab" aria-controls="v-pills-content" aria-selected="false"
|
type="button" role="tab" aria-controls="v-pills-content" aria-selected="false"
|
||||||
hx-get="{% url 'category_overview' %}"
|
hx-get="{% url 'category_overview' %}"
|
||||||
>{% trans 'Categories Overview' %}
|
>{% trans 'Categories Overview' %}
|
||||||
@@ -106,17 +106,17 @@
|
|||||||
remove .btn-active from <.insights-list button/>
|
remove .btn-active from <.insights-list button/>
|
||||||
add .btn-active to event.target
|
add .btn-active to event.target
|
||||||
set event.target's @aria-selected to 'true'">
|
set event.target's @aria-selected to 'true'">
|
||||||
<button class="btn btn-ghost justify-start" data-bs-target="#v-pills-content"
|
<button class="btn btn-ghost justify-start text-start" data-bs-target="#v-pills-content"
|
||||||
type="button" role="tab" aria-controls="v-pills-content" aria-selected="false"
|
type="button" role="tab" aria-controls="v-pills-content" aria-selected="false"
|
||||||
hx-get="{% url 'insights_late_transactions' %}">
|
hx-get="{% url 'insights_late_transactions' %}">
|
||||||
{% trans 'Late Transactions' %}
|
{% trans 'Late Transactions' %}
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-ghost justify-start" data-bs-target="#v-pills-content"
|
<button class="btn btn-ghost justify-start text-start" data-bs-target="#v-pills-content"
|
||||||
type="button" role="tab" aria-controls="v-pills-content" aria-selected="false"
|
type="button" role="tab" aria-controls="v-pills-content" aria-selected="false"
|
||||||
hx-get="{% url 'insights_latest_transactions' %}">
|
hx-get="{% url 'insights_latest_transactions' %}">
|
||||||
{% trans 'Latest Transactions' %}
|
{% trans 'Latest Transactions' %}
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-ghost justify-start" data-bs-target="#v-pills-content"
|
<button class="btn btn-ghost justify-start text-start" data-bs-target="#v-pills-content"
|
||||||
type="button" role="tab" aria-controls="v-pills-content" aria-selected="false"
|
type="button" role="tab" aria-controls="v-pills-content" aria-selected="false"
|
||||||
hx-get="{% url 'insights_emergency_fund' %}">
|
hx-get="{% url 'insights_emergency_fund' %}">
|
||||||
{% trans 'Emergency Fund' %}
|
{% trans 'Emergency Fund' %}
|
||||||
@@ -126,7 +126,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 md:col-9">
|
<div class="col-12 md:col-9 gy-3">
|
||||||
<div id="tab-content" class="show-loading"></div>
|
<div id="tab-content" class="show-loading"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -47,7 +47,7 @@
|
|||||||
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'>
|
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'>
|
||||||
{% include 'includes/mobile_navbar.html' %}
|
{% include 'includes/mobile_navbar.html' %}
|
||||||
{% include 'includes/sidebar.html' %}
|
{% include 'includes/sidebar.html' %}
|
||||||
<main class="my-4 px-3">
|
<main class="my-8 px-3">
|
||||||
{% settings "DEMO" as demo_mode %}
|
{% settings "DEMO" as demo_mode %}
|
||||||
{% if demo_mode %}
|
{% if demo_mode %}
|
||||||
<div class="px-3 m-0" id="demo-mode-alert" hx-preserve>
|
<div class="px-3 m-0" id="demo-mode-alert" hx-preserve>
|
||||||
|
|||||||
@@ -17,22 +17,31 @@
|
|||||||
class="show-loading"
|
class="show-loading"
|
||||||
hx-get=""
|
hx-get=""
|
||||||
hx-target="body">
|
hx-target="body">
|
||||||
<div class="h-full text-center mb-4 pt-2 w-full">
|
<div class="h-full text-center mb-4 w-full">
|
||||||
<div class="tabs tabs-box mx-auto w-fit"
|
<div class="tabs tabs-box mx-auto w-fit"
|
||||||
id="view-type"
|
id="view-type"
|
||||||
_="on change trigger updated">
|
_="on change trigger updated">
|
||||||
<input type="radio"
|
|
||||||
name="view_type"
|
<label class="tab">
|
||||||
class="tab"
|
<input type="radio"
|
||||||
aria-label="{% trans "Current" %}"
|
name="view_type"
|
||||||
value="current"
|
class="tab"
|
||||||
{% if type == "current" %}checked{% endif %} />
|
aria-label="{% trans "Current" %}"
|
||||||
<input type="radio"
|
value="current"
|
||||||
name="view_type"
|
{% if type == "current" %}checked{% endif %} />
|
||||||
class="tab"
|
<i class="fa-solid fa-sack-dollar fa-fw me-2"></i>
|
||||||
aria-label="{% trans "Projected" %}"
|
{% trans "Current" %}
|
||||||
value="projected"
|
</label>
|
||||||
{% if type == "projected" %}checked{% endif %} />
|
<label class="tab">
|
||||||
|
<input type="radio"
|
||||||
|
name="view_type"
|
||||||
|
class="tab"
|
||||||
|
aria-label="{% trans "Projected" %}"
|
||||||
|
value="projected"
|
||||||
|
{% if type == "projected" %}checked{% endif %} />
|
||||||
|
<i class="fa-solid fa-rocket fa-fw me-2"></i>
|
||||||
|
{% trans "Projected" %}
|
||||||
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="container px-md-3 py-3"
|
<div class="container px-md-3 py-3"
|
||||||
@@ -45,10 +54,10 @@
|
|||||||
{% for currency in currency_net_worth.values %}
|
{% for currency in currency_net_worth.values %}
|
||||||
<li>
|
<li>
|
||||||
{% if currency.consolidated and currency.consolidated.total_final != currency.total_final %}
|
{% if currency.consolidated and currency.consolidated.total_final != currency.total_final %}
|
||||||
<a class="cursor-pointer flex justify-between items-center w-full"
|
<a class="cursor-pointer select-auto flex justify-between items-center w-full"
|
||||||
_="on click showOnlyCurrencyDataset('{{ currency.currency.name }}')">
|
_="on click showOnlyCurrencyDataset('{{ currency.currency.name }}')">
|
||||||
<span class="currency-name text-start font-mono flex-shrink text-ellipsis">{{ currency.currency.name }}</span>
|
<span class="currency-name text-start font-mono shrink text-ellipsis">{{ currency.currency.name }}</span>
|
||||||
<span class="text-end flex-shrink-0">
|
<span class="text-end shrink-0">
|
||||||
<div>
|
<div>
|
||||||
<c-amount.display :amount="currency.total_final" :prefix="currency.currency.prefix" :suffix="currency.currency.suffix" :decimal_places="currency.currency.decimal_places" color="{% if currency.total_final > 0 %}green{% elif currency.total_final < 0 %}red{% endif %}" text-end></c-amount.display>
|
<c-amount.display :amount="currency.total_final" :prefix="currency.currency.prefix" :suffix="currency.currency.suffix" :decimal_places="currency.currency.decimal_places" color="{% if currency.total_final > 0 %}green{% elif currency.total_final < 0 %}red{% endif %}" text-end></c-amount.display>
|
||||||
</div>
|
</div>
|
||||||
@@ -61,19 +70,19 @@
|
|||||||
</a>
|
</a>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<a class="text-base-content/60">
|
<a class="text-base-content/60 select-auto">
|
||||||
<span class="text-start font-mono flex-shrink">{% trans "Consolidated" %}</span>
|
<span class="text-start shrink">{% trans "Consolidated" %}</span>
|
||||||
<span class="text-end flex-shrink-0">
|
<span class="text-end shrink-0">
|
||||||
<c-amount.display :amount="currency.consolidated.total_final" :prefix="currency.consolidated.currency.prefix" :suffix="currency.consolidated.currency.suffix" :decimal_places="currency.consolidated.currency.decimal_places" color="{% if currency.consolidated.total_final > 0 %}green{% elif currency.consolidated.total_final < 0 %}red{% endif %}" text-end></c-amount.display>
|
<c-amount.display :amount="currency.consolidated.total_final" :prefix="currency.consolidated.currency.prefix" :suffix="currency.consolidated.currency.suffix" :decimal_places="currency.consolidated.currency.decimal_places" color="{% if currency.consolidated.total_final > 0 %}green{% elif currency.consolidated.total_final < 0 %}red{% endif %}" text-end></c-amount.display>
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
{% else %}
|
{% else %}
|
||||||
<a class="cursor-pointer flex justify-between items-center w-full"
|
<a class="cursor-pointer select-auto flex justify-between items-center w-full"
|
||||||
_="on click showOnlyCurrencyDataset('{{ currency.currency.name }}')">
|
_="on click showOnlyCurrencyDataset('{{ currency.currency.name }}')">
|
||||||
<span class="currency-name text-start font-mono flex-shrink">{{ currency.currency.name }}</span>
|
<span class="currency-name text-start font-mono shrink">{{ currency.currency.name }}</span>
|
||||||
<span class="text-end flex-shrink-0">
|
<span class="text-end shrink-0">
|
||||||
<div>
|
<div>
|
||||||
<c-amount.display :amount="currency.total_final" :prefix="currency.currency.prefix" :suffix="currency.currency.suffix" :decimal_places="currency.currency.decimal_places" color="{% if currency.total_final > 0 %}green{% elif currency.total_final < 0 %}red{% endif %}" text-end></c-amount.display>
|
<c-amount.display :amount="currency.total_final" :prefix="currency.currency.prefix" :suffix="currency.currency.suffix" :decimal_places="currency.currency.decimal_places" color="{% if currency.total_final > 0 %}green{% elif currency.total_final < 0 %}red{% endif %}" text-end></c-amount.display>
|
||||||
</div>
|
</div>
|
||||||
@@ -134,16 +143,16 @@
|
|||||||
{% if data.grouper %}
|
{% if data.grouper %}
|
||||||
<li>
|
<li>
|
||||||
<details open>
|
<details open>
|
||||||
<summary class="font-mono">
|
<summary class="select-auto">
|
||||||
<span class="badge badge-primary">{{ data.grouper }}</span>
|
<span class="badge badge-primary">{{ data.grouper }}</span>
|
||||||
</summary>
|
</summary>
|
||||||
<ul>
|
<ul>
|
||||||
{% for account in data.list %}
|
{% for account in data.list %}
|
||||||
<li>
|
<li>
|
||||||
<a class="cursor-pointer flex justify-between items-center w-full"
|
<a class="cursor-pointer select-auto flex justify-between items-center w-full"
|
||||||
_="on click showOnlyAccountDataset('{{ account.account.name }}')">
|
_="on click showOnlyAccountDataset('{{ account.account.name }}')">
|
||||||
<span class="account-name text-start font-mono flex-shrink text-ellipsis">{{ account.account.name }}</span>
|
<span class="account-name text-start font-mono shrink text-ellipsis">{{ account.account.name }}</span>
|
||||||
<span class="text-end flex-shrink-0">
|
<span class="text-end shrink-0">
|
||||||
<div>
|
<div>
|
||||||
<c-amount.display :amount="account.total_final" :prefix="account.currency.prefix" :suffix="account.currency.suffix" :decimal_places="account.currency.decimal_places" color="{% if account.total_final > 0 %}green{% elif account.total_final < 0 %}red{% endif %}"></c-amount.display>
|
<c-amount.display :amount="account.total_final" :prefix="account.currency.prefix" :suffix="account.currency.suffix" :decimal_places="account.currency.decimal_places" color="{% if account.total_final > 0 %}green{% elif account.total_final < 0 %}red{% endif %}"></c-amount.display>
|
||||||
</div>
|
</div>
|
||||||
@@ -162,10 +171,10 @@
|
|||||||
{% else %}
|
{% else %}
|
||||||
{% for account in data.list %}
|
{% for account in data.list %}
|
||||||
<li>
|
<li>
|
||||||
<a class="cursor-pointer flex justify-between items-center w-full"
|
<a class="cursor-pointer flex select-auto justify-between items-center w-full"
|
||||||
_="on click showOnlyAccountDataset('{{ account.account.name }}')">
|
_="on click showOnlyAccountDataset('{{ account.account.name }}')">
|
||||||
<span class="account-name text-start font-mono flex-shrink">{{ account.account.name }}</span>
|
<span class="account-name text-start font-mono shrink">{{ account.account.name }}</span>
|
||||||
<span class="text-end flex-shrink-0">
|
<span class="text-end shrink-0">
|
||||||
<div>
|
<div>
|
||||||
<c-amount.display :amount="account.total_final" :prefix="account.currency.prefix" :suffix="account.currency.suffix" :decimal_places="account.currency.decimal_places" color="{% if account.total_final > 0 %}green{% elif account.total_final < 0 %}red{% endif %}"></c-amount.display>
|
<c-amount.display :amount="account.total_final" :prefix="account.currency.prefix" :suffix="account.currency.suffix" :decimal_places="account.currency.decimal_places" color="{% if account.total_final > 0 %}green{% elif account.total_final < 0 %}red{% endif %}"></c-amount.display>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -44,7 +44,7 @@
|
|||||||
_="on click
|
_="on click
|
||||||
remove .btn-active from <button/> in #filter-pills
|
remove .btn-active from <button/> in #filter-pills
|
||||||
add .btn-active to me">
|
add .btn-active to me">
|
||||||
{% if account.group.name %}<span class="badge badge-primary me-2">{{ account.group.name }}</span>{% endif %} {{ account.name }}
|
{% if account.group.name %}<span class="badge badge-primary badge-outline">{{ account.group.name }}</span>{% endif %} {{ account.name }}
|
||||||
</button>
|
</button>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="h-full text-center mb-4 pt-2 w-full">
|
<div class="h-full text-center mb-4 w-full">
|
||||||
<div role="tablist" class="tabs tabs-box mx-auto w-fit">
|
<div role="tablist" class="tabs tabs-box mx-auto w-fit">
|
||||||
<a href="{% url 'yearly_overview_currency' year=year %}" class="tab {% if type == 'currency' %}tab-active{% endif %}" hx-boost>
|
<a href="{% url 'yearly_overview_currency' year=year %}" class="tab {% if type == 'currency' %}tab-active{% endif %}" hx-boost>
|
||||||
<i class="fa-solid fa-solid fa-coins fa-fw me-2"></i>{% trans 'Currency' %}
|
<i class="fa-solid fa-solid fa-coins fa-fw me-2"></i>{% trans 'Currency' %}
|
||||||
|
|||||||
37
frontend/src/js/_utils.js
Normal file
37
frontend/src/js/_utils.js
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* Converts ANY valid CSS color string (oklch, hex, hsl, etc.)
|
||||||
|
* into a standard RGBA string that Chart.js can understand.
|
||||||
|
* This method uses a canvas to force the browser to compute the color.
|
||||||
|
* @param {string} colorString The color string to convert.
|
||||||
|
* @returns {string} The computed 'rgba(r, g, b, a)' string.
|
||||||
|
*/
|
||||||
|
window.convertColorToRgba = function convertColorToRgba(colorString) {
|
||||||
|
if (!colorString) return 'rgba(0,0,0,0.1)'; // Fallback
|
||||||
|
|
||||||
|
console.log(colorString)
|
||||||
|
|
||||||
|
// Create a 1x1 pixel canvas
|
||||||
|
let canvas = document.createElement('canvas');
|
||||||
|
canvas.width = 1;
|
||||||
|
canvas.height = 1;
|
||||||
|
let ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
|
// Set the fillStyle to the color string
|
||||||
|
// The browser MUST parse the oklch string here
|
||||||
|
ctx.fillStyle = colorString.trim();
|
||||||
|
|
||||||
|
// Draw the pixel
|
||||||
|
ctx.fillRect(0, 0, 1, 1);
|
||||||
|
|
||||||
|
// Get the pixel data. This is ALWAYS returned as [R, G, B, A]
|
||||||
|
// with values from 0-255.
|
||||||
|
const data = ctx.getImageData(0, 0, 1, 1).data;
|
||||||
|
|
||||||
|
// Convert the 0-255 alpha to a 0-1 float
|
||||||
|
const a = data[3] / 255;
|
||||||
|
|
||||||
|
console.log(data)
|
||||||
|
|
||||||
|
// Return the standard rgba string
|
||||||
|
return `rgba(${data[0]}, ${data[1]}, ${data[2]}, ${a})`;
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import './js/_tooltip.js';
|
import './_tooltip.js';
|
||||||
import 'bootstrap/js/dist/dropdown';
|
import 'bootstrap/js/dist/dropdown';
|
||||||
import Toast from 'bootstrap/js/dist/toast';
|
import Toast from 'bootstrap/js/dist/toast';
|
||||||
import 'bootstrap/js/dist/dropdown';
|
import 'bootstrap/js/dist/dropdown';
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import '@fontsource-variable/jetbrains-mono/wght-italic.css';
|
import '@fontsource-variable/jetbrains-mono/wght-italic.css';
|
||||||
import '@fontsource-variable/jetbrains-mono';
|
import '@fontsource-variable/jetbrains-mono';
|
||||||
import './styles/tailwind.css';
|
import '../styles/tailwind.css';
|
||||||
import './styles/style.scss';
|
import '../styles/style.scss';
|
||||||
9
frontend/src/main.js
Normal file
9
frontend/src/main.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
import './js/bootstrap.js';
|
||||||
|
import './js/datepicker.js';
|
||||||
|
import './js/htmx.js';
|
||||||
|
import './js/select.js';
|
||||||
|
import './js/charts.js';
|
||||||
|
import './js/autosize.js';
|
||||||
|
import './js/sweetalert2.js';
|
||||||
|
import './js/style.js';
|
||||||
|
import './js/_utils.js';
|
||||||
@@ -139,24 +139,46 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.text-exchange-rate {
|
.text-exchange-rate {
|
||||||
@apply text-base-content/60;
|
@apply text-base-content/60 text-xs;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-subtle {
|
.text-subtle {
|
||||||
@apply text-base-content/80;
|
@apply text-base-content/80;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Card Data Display Styles */
|
||||||
|
.card-data-section {
|
||||||
|
@apply space-y-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-data-row {
|
||||||
|
@apply flex justify-between py-1 px-3 rounded-lg transition-colors duration-150 hover:bg-base-200/50 items-center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-data-label {
|
||||||
|
@apply text-base-content/80; /* .text-subtle */
|
||||||
|
@apply text-sm font-medium;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-data-values {
|
||||||
|
@apply flex flex-col items-end gap-0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-data-divider {
|
||||||
|
@apply text-base-content/60; /* .hr */
|
||||||
|
@apply my-3;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@layer components {
|
@layer components {
|
||||||
.fab {
|
.fab {
|
||||||
@layer daisyui.component {
|
@layer daisyui.component {
|
||||||
> :nth-child(n+7) {
|
> :nth-child(n+7) {
|
||||||
transition-delay: 150ms;
|
transition-delay: 150ms;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* === Sidebar styles === */
|
/* === Sidebar styles === */
|
||||||
.sidebar-active {
|
.sidebar-active {
|
||||||
@@ -173,7 +195,7 @@
|
|||||||
|
|
||||||
.sidebar-floating {
|
.sidebar-floating {
|
||||||
/* Establishes the hover group and sets the collapsed/hover widths for the container */
|
/* Establishes the hover group and sets the collapsed/hover widths for the container */
|
||||||
@apply lg:w-16 lg:hover:w-112;
|
@apply lg:w-16 lg:hover:w-md;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-floating #sidebar {
|
.sidebar-floating #sidebar {
|
||||||
|
|||||||
@@ -10,14 +10,7 @@ const __filename = fileURLToPath(import.meta.url);
|
|||||||
const __dirname = dirname(__filename);
|
const __dirname = dirname(__filename);
|
||||||
|
|
||||||
const rollupInputs = {
|
const rollupInputs = {
|
||||||
autosize: resolve(__dirname, 'src/autosize.js'),
|
main: resolve(__dirname, 'src/main.js'),
|
||||||
charts: resolve(__dirname, 'src/charts.js'),
|
|
||||||
datepicker: resolve(__dirname, 'src/datepicker.js'),
|
|
||||||
bootstrap: resolve(__dirname, 'src/bootstrap.js'),
|
|
||||||
htmx: resolve(__dirname, 'src/htmx.js'),
|
|
||||||
select: resolve(__dirname, 'src/select.js'),
|
|
||||||
style: resolve(__dirname, 'src/style.js'),
|
|
||||||
sweetalert2: resolve(__dirname, 'src/sweetalert2.js'),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -42,6 +35,7 @@ export default defineConfig({
|
|||||||
usePolling: true,
|
usePolling: true,
|
||||||
disableGlobbing: false,
|
disableGlobbing: false,
|
||||||
},
|
},
|
||||||
|
hmr: false,
|
||||||
cors: true,
|
cors: true,
|
||||||
origin: 'http://100.118.164.62:5173'
|
origin: 'http://100.118.164.62:5173'
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user