mirror of
https://github.com/eitchtee/WYGIWYH.git
synced 2026-04-24 17:48:41 +02:00
feat: automated replacement
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -160,3 +160,5 @@ cython_debug/
|
|||||||
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||||
.idea/
|
.idea/
|
||||||
|
|
||||||
|
node_modules/
|
||||||
7
.vscode/settings.json
vendored
Normal file
7
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"djlint.showInstallError": false,
|
||||||
|
"files.associations": {
|
||||||
|
"*.css": "tailwindcss"
|
||||||
|
},
|
||||||
|
"tailwindCSS.experimental.configFile": "frontend/src/styles/tailwind.css",
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@ https://docs.djangoproject.com/en/5.1/ref/settings/
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
@@ -46,7 +47,7 @@ INSTALLED_APPS = [
|
|||||||
"django.contrib.sites",
|
"django.contrib.sites",
|
||||||
"whitenoise.runserver_nostatic",
|
"whitenoise.runserver_nostatic",
|
||||||
"django.contrib.staticfiles",
|
"django.contrib.staticfiles",
|
||||||
"webpack_boilerplate",
|
"django_vite",
|
||||||
"django.contrib.humanize",
|
"django.contrib.humanize",
|
||||||
"django.contrib.postgres",
|
"django.contrib.postgres",
|
||||||
"django_browser_reload",
|
"django_browser_reload",
|
||||||
@@ -128,6 +129,14 @@ STORAGES = {
|
|||||||
|
|
||||||
WHITENOISE_MANIFEST_STRICT = False
|
WHITENOISE_MANIFEST_STRICT = False
|
||||||
|
|
||||||
|
|
||||||
|
def immutable_file_test(path, url):
|
||||||
|
# Match vite (rollup)-generated hashes, à la, `some_file-CSliV9zW.js`
|
||||||
|
return re.match(r"^.+[.-][0-9a-zA-Z_-]{8,12}\..+$", url)
|
||||||
|
|
||||||
|
|
||||||
|
WHITENOISE_IMMUTABLE_FILE_TEST = immutable_file_test
|
||||||
|
|
||||||
WSGI_APPLICATION = "WYGIWYH.wsgi.application"
|
WSGI_APPLICATION = "WYGIWYH.wsgi.application"
|
||||||
|
|
||||||
|
|
||||||
@@ -289,7 +298,7 @@ STATIC_URL = "static/"
|
|||||||
STATIC_ROOT = BASE_DIR / "static_files"
|
STATIC_ROOT = BASE_DIR / "static_files"
|
||||||
|
|
||||||
STATICFILES_DIRS = [
|
STATICFILES_DIRS = [
|
||||||
ROOT_DIR / "frontend/build",
|
ROOT_DIR / "frontend" / "build",
|
||||||
BASE_DIR / "static",
|
BASE_DIR / "static",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -305,9 +314,10 @@ CACHES = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WEBPACK_LOADER = {
|
DJANGO_VITE_ASSETS_PATH = ROOT_DIR / "frontend" / "build"
|
||||||
"MANIFEST_FILE": ROOT_DIR / "frontend/build/manifest.json",
|
DJANGO_VITE_MANIFEST_PATH = DJANGO_VITE_ASSETS_PATH / "manifest.json"
|
||||||
}
|
DJANGO_VITE_DEV_MODE = DEBUG
|
||||||
|
DJANGO_VITE_DEV_SERVER_PORT = 5173
|
||||||
|
|
||||||
# Default primary key field type
|
# Default primary key field type
|
||||||
# https://docs.djangoproject.com/en/5.1/ref/settings/#default-auto-field
|
# https://docs.djangoproject.com/en/5.1/ref/settings/#default-auto-field
|
||||||
@@ -354,8 +364,12 @@ ACCOUNT_ADAPTER = "allauth.account.adapter.DefaultAccountAdapter"
|
|||||||
SOCIALACCOUNT_ADAPTER = "allauth.socialaccount.adapter.DefaultSocialAccountAdapter"
|
SOCIALACCOUNT_ADAPTER = "allauth.socialaccount.adapter.DefaultSocialAccountAdapter"
|
||||||
|
|
||||||
# CRISPY FORMS
|
# CRISPY FORMS
|
||||||
CRISPY_ALLOWED_TEMPLATE_PACKS = ["bootstrap5", "crispy_forms/pure_text"]
|
CRISPY_ALLOWED_TEMPLATE_PACKS = [
|
||||||
CRISPY_TEMPLATE_PACK = "bootstrap5"
|
"bootstrap5",
|
||||||
|
"crispy_forms/pure_text",
|
||||||
|
"crispy-daisyui",
|
||||||
|
]
|
||||||
|
CRISPY_TEMPLATE_PACK = "crispy-daisyui"
|
||||||
|
|
||||||
SESSION_EXPIRE_AT_BROWSER_CLOSE = False
|
SESSION_EXPIRE_AT_BROWSER_CLOSE = False
|
||||||
SESSION_COOKIE_AGE = int(os.getenv("SESSION_EXPIRY_TIME", 2678400)) # 31 days
|
SESSION_COOKIE_AGE = int(os.getenv("SESSION_EXPIRY_TIME", 2678400)) # 31 days
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
<div class="container px-md-3 py-3 column-gap-5">
|
<div class="tw:container tw:px-md-3 tw:py-3 tw:column-gap-5">
|
||||||
<div class="tw:text-3xl fw-bold font-monospace tw:w-full mb-3">
|
<div class="tw:text-3xl tw:font-bold tw:font-mono tw:w-full tw:mb-3">
|
||||||
{% spaceless %}
|
{% spaceless %}
|
||||||
<div>{% translate 'Account Groups' %}<span>
|
<div>{% translate 'Account Groups' %}<span>
|
||||||
<a class="text-decoration-none tw:text-2xl p-1 category-action"
|
<a class="tw:no-underline tw:text-2xl tw:p-1 category-action"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Add" %}"
|
data-bs-title="{% translate "Add" %}"
|
||||||
@@ -14,30 +14,30 @@
|
|||||||
{% endspaceless %}
|
{% endspaceless %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card">
|
<div class="tw:card tw:bg-base-100 tw:shadow-xl">
|
||||||
<div class="card-body table-responsive">
|
<div class="tw:card-body tw:overflow-x-auto">
|
||||||
{% if account_groups %}
|
{% if account_groups %}
|
||||||
<c-config.search></c-config.search>
|
<c-config.search></c-config.search>
|
||||||
<table class="table table-hover">
|
<table class="tw:table tw:table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col" class="col-auto"></th>
|
<th scope="col" class="tw:w-auto"></th>
|
||||||
<th scope="col" class="col">{% translate 'Name' %}</th>
|
<th scope="col">{% translate 'Name' %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for account_group in account_groups %}
|
{% for account_group in account_groups %}
|
||||||
<tr class="account_group">
|
<tr class="account_group">
|
||||||
<td class="col-auto">
|
<td class="tw:w-auto">
|
||||||
<div class="btn-group" role="group" aria-label="{% translate 'Actions' %}">
|
<div class="tw:join" role="group" aria-label="{% translate 'Actions' %}">
|
||||||
<a class="btn btn-secondary btn-sm"
|
<a class="tw:btn tw:btn-secondary tw:btn-sm tw:join-item"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Edit" %}"
|
data-bs-title="{% translate "Edit" %}"
|
||||||
hx-get="{% url 'account_group_edit' pk=account_group.id %}"
|
hx-get="{% url 'account_group_edit' pk=account_group.id %}"
|
||||||
hx-target="#generic-offcanvas">
|
hx-target="#generic-offcanvas">
|
||||||
<i class="fa-solid fa-pencil fa-fw"></i></a>
|
<i class="fa-solid fa-pencil fa-fw"></i></a>
|
||||||
<a class="btn btn-secondary btn-sm text-danger"
|
<a class="tw:btn tw:btn-secondary tw:btn-sm tw:join-item tw:text-error"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Delete" %}"
|
data-bs-title="{% translate "Delete" %}"
|
||||||
@@ -49,7 +49,7 @@
|
|||||||
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"></i></a>
|
_="install prompt_swal"><i class="fa-solid fa-trash fa-fw"></i></a>
|
||||||
{% if not account_group.owner %}
|
{% if not account_group.owner %}
|
||||||
<a class="btn btn-secondary btn-sm text-warning"
|
<a class="tw:btn tw:btn-secondary tw:btn-sm tw:join-item tw:text-warning"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Take ownership" %}"
|
data-bs-title="{% translate "Take ownership" %}"
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
<i class="fa-solid fa-crown fa-fw"></i></a>
|
<i class="fa-solid fa-crown fa-fw"></i></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if user == account_group.owner %}
|
{% if user == account_group.owner %}
|
||||||
<a class="btn btn-secondary btn-sm text-primary"
|
<a class="tw:btn tw:btn-secondary tw:btn-sm tw:join-item tw:text-primary"
|
||||||
role="button"
|
role="button"
|
||||||
hx-target="#generic-offcanvas"
|
hx-target="#generic-offcanvas"
|
||||||
hx-swap="innerHTML"
|
hx-swap="innerHTML"
|
||||||
@@ -68,7 +68,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="col">{{ account_group.name }}</td>
|
<td>{{ account_group.name }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -9,65 +9,60 @@
|
|||||||
<form hx-post="{% url 'account_reconciliation' %}">
|
<form hx-post="{% url 'account_reconciliation' %}">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ form.management_form }}
|
{{ form.management_form }}
|
||||||
<div class="accordion accordion-flush" id="balanceAccordionFlush">
|
<div class="tw:space-y-2" id="balanceAccordionFlush">
|
||||||
{% for form in form.forms %}
|
{% for form in form.forms %}
|
||||||
<div class="accordion-item">
|
<div class="tw:collapse tw:collapse-arrow tw:bg-base-200">
|
||||||
<h2 class="accordion-header">
|
<input type="radio" name="my-accordion-flush" id="accordion-{{ forloop.counter0 }}" />
|
||||||
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse"
|
<label for="accordion-{{ forloop.counter0 }}" class="tw:collapse-title tw:text-base tw:font-medium">
|
||||||
data-bs-target="#flush-collapse-{{ forloop.counter0 }}" aria-expanded="false"
|
{% if form.account_group %}<span class="tw:badge tw:badge-primary tw:me-2">{{ form.account_group.name }}</span>{% endif %}{{ form.account_name }}
|
||||||
aria-controls="flush-collapseOne">
|
</label>
|
||||||
{% if form.account_group %}<span class="badge text-bg-primary me-2">{{ form.account_group.name }}</span>{% endif %}{{ form.account_name }}
|
<div class="tw:collapse-content">
|
||||||
</button>
|
<div class="tw:mb-3">
|
||||||
</h2>
|
<div class="tw:label">
|
||||||
<div id="flush-collapse-{{ forloop.counter0 }}" class="accordion-collapse collapse">
|
<span class="tw:label-text">{% translate 'Current balance' %}</span>
|
||||||
<div class="accordion-body">
|
|
||||||
<div class="mb-3">
|
|
||||||
<div class="form-label">
|
|
||||||
{% translate 'Current balance' %}
|
|
||||||
</div>
|
|
||||||
<div data-amount="{{ form.current_balance|floatformat:"-40u" }}"
|
|
||||||
data-decimal-places="{{ form.currency_decimal_places }}"
|
|
||||||
id="amount-{{ forloop.counter0 }}">
|
|
||||||
{% currency_display amount=form.current_balance prefix=form.currency_prefix suffix=form.currency_suffix decimal_places=form.currency_decimal_places %}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div data-amount="{{ form.current_balance|floatformat:"-40u" }}"
|
||||||
{% crispy form %}
|
data-decimal-places="{{ form.currency_decimal_places }}"
|
||||||
|
id="amount-{{ forloop.counter0 }}">
|
||||||
|
{% currency_display amount=form.current_balance prefix=form.currency_prefix suffix=form.currency_suffix decimal_places=form.currency_decimal_places %}
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-3">
|
</div>
|
||||||
<div class="form-label">
|
<div>
|
||||||
{% translate 'Difference' %}
|
{% crispy form %}
|
||||||
</div>
|
</div>
|
||||||
<div _="on input from #id_form-{{ forloop.counter0 }}-new_balance
|
<div class="tw:mb-3">
|
||||||
set original_amount to parseFloat('{{ form.current_balance|floatformat:"-40u" }}')
|
<div class="tw:label">
|
||||||
then set prefix to '{{ form.currency_prefix }}'
|
<span class="tw:label-text">{% translate 'Difference' %}</span>
|
||||||
then set suffix to '{{ form.currency_suffix }}'
|
|
||||||
then set decimal_places to {{ form.currency_decimal_places }}
|
|
||||||
then call parseLocaleNumber(#id_form-{{ forloop.counter0 }}-new_balance.value)
|
|
||||||
then set new_amount to result
|
|
||||||
then set diff to (Math.round((new_amount - original_amount) * Math.pow(10, decimal_places))) / Math.pow(10, decimal_places)
|
|
||||||
then log diff
|
|
||||||
then set format_new_amount to
|
|
||||||
Intl.NumberFormat(
|
|
||||||
undefined,
|
|
||||||
{
|
|
||||||
minimumFractionDigits: decimal_places,
|
|
||||||
maximumFractionDigits: decimal_places,
|
|
||||||
roundingMode: 'trunc'
|
|
||||||
}
|
|
||||||
).format(diff)
|
|
||||||
then set formatted_string to `${prefix}${format_new_amount}${suffix}`
|
|
||||||
then put formatted_string into me if diff else
|
|
||||||
put '-' into me">-</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div _="on input from #id_form-{{ forloop.counter0 }}-new_balance
|
||||||
|
set original_amount to parseFloat('{{ form.current_balance|floatformat:"-40u" }}')
|
||||||
|
then set prefix to '{{ form.currency_prefix }}'
|
||||||
|
then set suffix to '{{ form.currency_suffix }}'
|
||||||
|
then set decimal_places to {{ form.currency_decimal_places }}
|
||||||
|
then call parseLocaleNumber(#id_form-{{ forloop.counter0 }}-new_balance.value)
|
||||||
|
then set new_amount to result
|
||||||
|
then set diff to (Math.round((new_amount - original_amount) * Math.pow(10, decimal_places))) / Math.pow(10, decimal_places)
|
||||||
|
then log diff
|
||||||
|
then set format_new_amount to
|
||||||
|
Intl.NumberFormat(
|
||||||
|
undefined,
|
||||||
|
{
|
||||||
|
minimumFractionDigits: decimal_places,
|
||||||
|
maximumFractionDigits: decimal_places,
|
||||||
|
roundingMode: 'trunc'
|
||||||
|
}
|
||||||
|
).format(diff)
|
||||||
|
then set formatted_string to `${prefix}${format_new_amount}${suffix}`
|
||||||
|
then put formatted_string into me if diff else
|
||||||
|
put '-' into me">-</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-3">
|
<div class="tw:mt-3">
|
||||||
<div>
|
<div>
|
||||||
<input type="submit" name="submit" value="{% translate 'Reconcile balances' %}" class="btn btn-outline-primary w-100" id="submit-id-submit">
|
<input type="submit" name="submit" value="{% translate 'Reconcile balances' %}" class="tw:btn tw:btn-outline tw:btn-primary tw:w-full" id="submit-id-submit">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
<div class="container px-md-3 py-3 column-gap-5">
|
<div class="tw:container tw:px-md-3 tw:py-3 tw:column-gap-5">
|
||||||
<div class="tw:text-3xl fw-bold font-monospace tw:w-full mb-3">
|
<div class="tw:text-3xl tw:font-bold tw:font-mono tw:w-full tw:mb-3">
|
||||||
{% spaceless %}
|
{% spaceless %}
|
||||||
<div>{% translate 'Accounts' %}<span>
|
<div>{% translate 'Accounts' %}<span>
|
||||||
<a class="text-decoration-none tw:text-2xl p-1 category-action"
|
<a class="tw:no-underline tw:text-2xl tw:p-1 category-action"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Add" %}"
|
data-bs-title="{% translate "Add" %}"
|
||||||
@@ -14,35 +14,35 @@
|
|||||||
{% endspaceless %}
|
{% endspaceless %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card">
|
<div class="tw:card tw:bg-base-100 tw:shadow-xl">
|
||||||
<div class="card-body table-responsive">
|
<div class="tw:card-body tw:overflow-x-auto">
|
||||||
{% if accounts %}
|
{% if accounts %}
|
||||||
<c-config.search></c-config.search>
|
<c-config.search></c-config.search>
|
||||||
<table class="table table-hover text-nowrap">
|
<table class="tw:table tw:table-hover tw:whitespace-nowrap">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col" class="col-auto"></th>
|
<th scope="col" class="tw:w-auto"></th>
|
||||||
<th scope="col" class="col">{% translate 'Name' %}</th>
|
<th scope="col">{% translate 'Name' %}</th>
|
||||||
<th scope="col" class="col">{% translate 'Group' %}</th>
|
<th scope="col">{% translate 'Group' %}</th>
|
||||||
<th scope="col" class="col">{% translate 'Currency' %}</th>
|
<th scope="col">{% translate 'Currency' %}</th>
|
||||||
<th scope="col" class="col">{% translate 'Exchange Currency' %}</th>
|
<th scope="col">{% translate 'Exchange Currency' %}</th>
|
||||||
<th scope="col" class="col">{% translate 'Is Asset' %}</th>
|
<th scope="col">{% translate 'Is Asset' %}</th>
|
||||||
<th scope="col" class="col">{% translate 'Archived' %}</th>
|
<th scope="col">{% translate 'Archived' %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for account in accounts %}
|
{% for account in accounts %}
|
||||||
<tr class="account">
|
<tr class="account">
|
||||||
<td class="col-auto">
|
<td class="tw:w-auto">
|
||||||
<div class="btn-group" role="group" aria-label="{% translate 'Actions' %}">
|
<div class="tw:join" role="group" aria-label="{% translate 'Actions' %}">
|
||||||
<a class="btn btn-secondary btn-sm"
|
<a class="tw:btn tw:btn-secondary tw:btn-sm tw:join-item"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Edit" %}"
|
data-bs-title="{% translate "Edit" %}"
|
||||||
hx-get="{% url 'account_edit' pk=account.id %}"
|
hx-get="{% url 'account_edit' pk=account.id %}"
|
||||||
hx-target="#generic-offcanvas">
|
hx-target="#generic-offcanvas">
|
||||||
<i class="fa-solid fa-pencil fa-fw"></i></a>
|
<i class="fa-solid fa-pencil fa-fw"></i></a>
|
||||||
<a class="btn btn-secondary btn-sm text-danger"
|
<a class="tw:btn tw:btn-secondary tw:btn-sm tw:join-item tw:text-error"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Delete" %}"
|
data-bs-title="{% translate "Delete" %}"
|
||||||
@@ -54,7 +54,7 @@
|
|||||||
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"></i></a>
|
_="install prompt_swal"><i class="fa-solid fa-trash fa-fw"></i></a>
|
||||||
{% if not account.owner %}
|
{% if not account.owner %}
|
||||||
<a class="btn btn-secondary btn-sm text-primary"
|
<a class="tw:btn tw:btn-secondary tw:btn-sm tw:join-item tw:text-primary"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Take ownership" %}"
|
data-bs-title="{% translate "Take ownership" %}"
|
||||||
@@ -62,7 +62,7 @@
|
|||||||
<i class="fa-solid fa-crown fa-fw"></i></a>
|
<i class="fa-solid fa-crown fa-fw"></i></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if user == account.owner %}
|
{% if user == account.owner %}
|
||||||
<a class="btn btn-secondary btn-sm text-primary"
|
<a class="tw:btn tw:btn-secondary tw:btn-sm tw:join-item tw:text-primary"
|
||||||
role="button"
|
role="button"
|
||||||
hx-target="#generic-offcanvas"
|
hx-target="#generic-offcanvas"
|
||||||
hx-swap="innerHTML"
|
hx-swap="innerHTML"
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
hx-get="{% url 'account_share_settings' pk=account.id %}">
|
hx-get="{% url 'account_share_settings' pk=account.id %}">
|
||||||
<i class="fa-solid fa-share fa-fw"></i></a>
|
<i class="fa-solid fa-share fa-fw"></i></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a class="btn btn-secondary btn-sm"
|
<a class="tw:btn tw:btn-secondary tw:btn-sm tw:join-item"
|
||||||
role="button"
|
role="button"
|
||||||
hx-get="{% url 'account_toggle_untracked' pk=account.id %}"
|
hx-get="{% url 'account_toggle_untracked' pk=account.id %}"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
@@ -84,12 +84,12 @@
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="col">{{ account.name }}</td>
|
<td>{{ account.name }}</td>
|
||||||
<td class="col">{{ account.group.name }}</td>
|
<td>{{ account.group.name }}</td>
|
||||||
<td class="col">{{ account.currency }}</td>
|
<td>{{ account.currency }}</td>
|
||||||
<td class="col">{% if account.exchange_currency %}{{ account.exchange_currency }}{% else %}-{% endif %}</td>
|
<td>{% if account.exchange_currency %}{{ account.exchange_currency }}{% else %}-{% endif %}</td>
|
||||||
<td class="col">{% if account.is_asset %}<i class="fa-solid fa-solid fa-check text-success"></i>{% endif %}</td>
|
<td>{% if account.is_asset %}<i class="fa-solid fa-solid fa-check tw:text-success"></i>{% endif %}</td>
|
||||||
<td class="col">{% if account.is_archived %}<i class="fa-solid fa-solid fa-check text-success"></i>{% endif %}</td>
|
<td>{% if account.is_archived %}<i class="fa-solid fa-solid fa-check tw:text-success"></i>{% endif %}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -2,40 +2,40 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div class="tw:hidden tw:lg:grid tw:lg:grid-cols-7 tw:gap-4 tw:lg:gap-0">
|
<div class="tw:hidden tw:lg:grid tw:lg:grid-cols-7 tw:gap-4 tw:lg:gap-0 bg-base-300">
|
||||||
<div class="border-start border-top border-bottom p-2 text-center">
|
<div class="tw:border-l tw:border-t tw:border-b tw:border-base-100 tw:p-2 tw:text-center">
|
||||||
{% translate 'MON' %}
|
{% translate 'MON' %}
|
||||||
</div>
|
</div>
|
||||||
<div class="border-top border-bottom p-2 text-center">
|
<div class="tw:border-t tw:border-b tw:border-base-300 tw:p-2 tw:text-center">
|
||||||
{% translate 'TUE' %}
|
{% translate 'TUE' %}
|
||||||
</div>
|
</div>
|
||||||
<div class="border-top border-bottom p-2 text-center">
|
<div class="tw:border-t tw:border-b tw:border-base-300 tw:p-2 tw:text-center">
|
||||||
{% translate 'WED' %}
|
{% translate 'WED' %}
|
||||||
</div>
|
</div>
|
||||||
<div class="border-top border-bottom p-2 text-center">
|
<div class="tw:border-t tw:border-b tw:border-base-300 tw:p-2 tw:text-center">
|
||||||
{% translate 'THU' %}
|
{% translate 'THU' %}
|
||||||
</div>
|
</div>
|
||||||
<div class="border-top border-bottom p-2 text-center">
|
<div class="tw:border-t tw:border-b tw:border-base-300 tw:p-2 tw:text-center">
|
||||||
{% translate 'FRI' %}
|
{% translate 'FRI' %}
|
||||||
</div>
|
</div>
|
||||||
<div class="border-top border-bottom p-2 text-center">
|
<div class="tw:border-t tw:border-b tw:border-base-300 tw:p-2 tw:text-center">
|
||||||
{% translate 'SAT' %}
|
{% translate 'SAT' %}
|
||||||
</div>
|
</div>
|
||||||
<div class="border-end border-top border-bottom p-2 text-center">
|
<div class="tw:border-r tw:border-t tw:border-b tw:border-base-300 tw:p-2 tw:text-center">
|
||||||
{% translate 'SUN' %}
|
{% translate 'SUN' %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="tw:grid tw:grid-cols-1 tw:grid-rows-1 tw:lg:grid-cols-7 tw:lg:grid-rows-6 tw:gap-4 tw:lg:gap-0">
|
<div class="tw:grid tw:grid-cols-1 tw:grid-rows-1 tw:lg:grid-cols-7 tw:lg:grid-rows-6 tw:gap-4 tw:lg:gap-0">
|
||||||
{% for date in dates %}
|
{% for date in dates %}
|
||||||
{% if date %}
|
{% if date %}
|
||||||
<div class="card h-100 tw:hover:bg-zinc-900! rounded-0{% if not date.transactions %} tw:hidden! tw:lg:flex!{% endif %}{% if today == date.date %} tw:border-yellow-300 border-primary{% endif %} " role="button"
|
<div class="tw:card tw:bg-base-200 tw:h-full tw:hover:bg-base-300! tw:rounded-none tw:card-border tw:border-base-content/50 {% if not date.transactions %}tw:hidden! tw:lg:flex!{% endif %}{% if today == date.date %} tw:card-border tw:border-2 tw:border-primary{% endif %}" role="button"
|
||||||
hx-get="{% url 'calendar_transactions_list' day=date.date.day month=date.date.month year=date.date.year %}"
|
hx-get="{% url 'calendar_transactions_list' day=date.date.day month=date.date.month year=date.date.year %}"
|
||||||
hx-target="#persistent-generic-offcanvas-left">
|
hx-target="#persistent-generic-offcanvas-left">
|
||||||
<div class="card-header border-0 bg-transparent text-end tw:flex justify-content-between p-2 w-100">
|
<div class="tw:card-header tw:border-0 tw:bg-transparent tw:text-end tw:flex tw:justify-between tw:p-2 tw:w-full">
|
||||||
<div class="tw:lg:hidden text-start w-100">{{ date.date|date:"l"|lower }}</div>
|
<div class="tw:lg:hidden tw:text-start tw:w-full">{{ date.date|date:"l"|lower }}</div>
|
||||||
<div class="text-end w-100">{{ date.day }}</div>
|
<div class="tw:text-end tw:w-full">{{ date.day }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body p-2">
|
<div class="tw:card-body tw:p-2">
|
||||||
{% for transaction in date.transactions %}
|
{% for transaction in date.transactions %}
|
||||||
{% if transaction.is_paid %}
|
{% if transaction.is_paid %}
|
||||||
{% if transaction.type == "IN" and not transaction.account.is_asset %}
|
{% if transaction.type == "IN" and not transaction.account.is_asset %}
|
||||||
@@ -62,7 +62,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="tw:hidden! tw:lg:block! card h-100 rounded-0"></div>
|
<div class="tw:hidden! tw:lg:block! tw:card tw:bg-base-100 tw:h-full tw:rounded-none"></div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load month_name %}
|
{% load month_name %}
|
||||||
{% load static %}
|
{% load static %}
|
||||||
{% load webpack_loader %}
|
|
||||||
|
|
||||||
{% block title %}{% translate 'Monthly Overview' %} :: {{ month|month_name }}/{{ year }}{% endblock %}
|
{% block title %}{% translate 'Monthly Overview' %} :: {{ month|month_name }}/{{ year }}{% endblock %}
|
||||||
|
|
||||||
@@ -13,28 +12,28 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="container px-md-3 py-3 column-gap-5">
|
<div class="tw:container tw:px-md-3 tw:py-3 tw:gap-x-5">
|
||||||
<div class="row mb-3 gx-xl-4 gy-3 mb-4">
|
<div class="tw:flex tw:flex-wrap tw:mb-4 tw:gap-x-xl-4 tw:gap-y-3">
|
||||||
{# Date picker#}
|
{# Date picker#}
|
||||||
<div class="col-12 col-xl-4 flex-row align-items-center d-flex">
|
<div class="tw:w-full tw:xl:w-4/12 tw:flex-row tw:items-center tw:flex">
|
||||||
<div class="tw:text-base h-100 align-items-center d-flex">
|
<div class="tw:text-base tw:h-full tw:items-center tw:flex">
|
||||||
<a role="button"
|
<a role="button"
|
||||||
class="pe-4 py-2"
|
class="tw:pe-4 tw:py-2"
|
||||||
hx-boost="true"
|
hx-boost="true"
|
||||||
hx-trigger="click, previous_month from:window"
|
hx-trigger="click, previous_month from:window"
|
||||||
href="{% url 'calendar' month=previous_month year=previous_year %}"><i
|
href="{% url 'calendar' month=previous_month year=previous_year %}"><i
|
||||||
class="fa-solid fa-chevron-left"></i></a>
|
class="fa-solid fa-chevron-left"></i></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="tw:text-3xl fw-bold font-monospace tw:w-full text-center"
|
<div class="tw:text-3xl tw:font-bold tw:font-mono tw:w-full tw:text-center"
|
||||||
hx-get="{% url 'month_year_picker' %}"
|
hx-get="{% url 'month_year_picker' %}"
|
||||||
hx-target="#generic-offcanvas-left"
|
hx-target="#generic-offcanvas-left"
|
||||||
hx-trigger="click, date_picker from:window"
|
hx-trigger="click, date_picker from:window"
|
||||||
hx-vals='{"month": {{ month }}, "year": {{ year }}, "for": "calendar", "field": "date"}' role="button">
|
hx-vals='{"month": {{ month }}, "year": {{ year }}, "for": "calendar", "field": "date"}' role="button">
|
||||||
{{ month|month_name }} {{ year }}
|
{{ month|month_name }} {{ year }}
|
||||||
</div>
|
</div>
|
||||||
<div class="tw:text-base mx-2 h-100 align-items-center d-flex">
|
<div class="tw:text-base tw:mx-2 tw:h-full tw:items-center tw:flex">
|
||||||
<a role="button"
|
<a role="button"
|
||||||
class="ps-3 py-2"
|
class="tw:ps-3 tw:py-2"
|
||||||
hx-boost="true"
|
hx-boost="true"
|
||||||
hx-trigger="click, next_month from:window"
|
hx-trigger="click, next_month from:window"
|
||||||
href="{% url 'calendar' month=next_month year=next_year %}">
|
href="{% url 'calendar' month=next_month year=next_year %}">
|
||||||
@@ -43,15 +42,15 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{# Action buttons#}
|
{# Action buttons#}
|
||||||
<div class="col-12 col-xl-8">
|
<div class="tw:w-full tw:xl:w-8/12">
|
||||||
{# <c-ui.quick-transactions-buttons#}
|
{# <c-ui.quick-transactions-buttons#}
|
||||||
{# :year="year"#}
|
{# :year="year"#}
|
||||||
{# :month="month"#}
|
{# :month="month"#}
|
||||||
{# ></c-ui.quick-transactions-buttons>#}
|
{# ></c-ui.quick-transactions-buttons>#}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="tw:flex tw:flex-wrap">
|
||||||
<div class="show-loading" hx-get="{% url 'calendar_list' month=month year=year %}"
|
<div class="show-loading tw:w-full" hx-get="{% url 'calendar_list' month=month year=year %}"
|
||||||
hx-trigger="load, updated from:window, selective_update from:window, every 10m"></div>
|
hx-trigger="load, updated from:window, selective_update from:window, every 10m"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
<div class="container px-md-3 py-3 column-gap-5">
|
<div class="tw:container tw:px-md-3 tw:py-3 tw:column-gap-5">
|
||||||
<div class="tw:text-3xl fw-bold font-monospace tw:w-full mb-3">
|
<div class="tw:text-3xl tw:font-bold tw:font-mono tw:w-full tw:mb-3">
|
||||||
{% spaceless %}
|
{% spaceless %}
|
||||||
<div>{% translate 'Categories' %}<span>
|
<div>{% translate 'Categories' %}<span>
|
||||||
<a class="text-decoration-none tw:text-2xl p-1 category-action"
|
<a class="tw:no-underline tw:text-2xl tw:p-1 category-action"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Add" %}"
|
data-bs-title="{% translate "Add" %}"
|
||||||
@@ -14,18 +14,14 @@
|
|||||||
{% endspaceless %}
|
{% endspaceless %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card">
|
<div class="tw:card tw:bg-base-100 tw:shadow-xl">
|
||||||
<div class="card-header">
|
<div class="tw:card-header tw:bg-base-200 tw:p-4">
|
||||||
<ul class="nav nav-pills card-header-pills" id="myTab" role="tablist">
|
<div role="tablist" class="tw:tabs tw:tabs-lifted">
|
||||||
<li class="nav-item" role="presentation">
|
<button class="tw:tab tw:tab-active" data-bs-toggle="tab" type="button" role="tab" aria-selected="true" hx-get="{% url 'categories_table_active' %}" hx-trigger="load, click" hx-target="#categories-table">{% translate 'Active' %}</button>
|
||||||
<button class="nav-link active" data-bs-toggle="tab" type="button" role="tab" aria-selected="true" hx-get="{% url 'categories_table_active' %}" hx-trigger="load, click" hx-target="#categories-table">{% translate 'Active' %}</button>
|
<button class="tw:tab" hx-get="{% url 'categories_table_archived' %}" hx-target="#categories-table" data-bs-toggle="tab" type="button" role="tab" aria-selected="false">{% translate 'Archived' %}</button>
|
||||||
</li>
|
</div>
|
||||||
<li class="nav-item" role="presentation">
|
|
||||||
<button class="nav-link" hx-get="{% url 'categories_table_archived' %}" hx-target="#categories-table" data-bs-toggle="tab" type="button" role="tab" aria-selected="false">{% translate 'Archived' %}</button>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="tw:card-body">
|
||||||
<div id="categories-table"></div>
|
<div id="categories-table"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -7,22 +7,22 @@
|
|||||||
hx-swap="outerHTML">
|
hx-swap="outerHTML">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if categories %}
|
{% if categories %}
|
||||||
<div class="table-responsive">
|
<div class="tw:overflow-x-auto">
|
||||||
<c-config.search></c-config.search>
|
<c-config.search></c-config.search>
|
||||||
<table class="table table-hover">
|
<table class="tw:table tw:table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col" class="col-auto"></th>
|
<th scope="col" class="tw:w-auto"></th>
|
||||||
<th scope="col" class="col">{% translate 'Name' %}</th>
|
<th scope="col">{% translate 'Name' %}</th>
|
||||||
<th scope="col" class="col">{% translate 'Muted' %}</th>
|
<th scope="col">{% translate 'Muted' %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for category in categories %}
|
{% for category in categories %}
|
||||||
<tr class="category">
|
<tr class="category">
|
||||||
<td class="col-auto text-center">
|
<td class="tw:w-auto tw:text-center">
|
||||||
<div class="btn-group" role="group" aria-label="{% translate 'Actions' %}">
|
<div class="tw:join" role="group" aria-label="{% translate 'Actions' %}">
|
||||||
<a class="btn btn-secondary btn-sm"
|
<a class="tw:btn tw:btn-secondary tw:btn-sm tw:join-item"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
hx-swap="innerHTML"
|
hx-swap="innerHTML"
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
hx-get="{% url 'category_edit' category_id=category.id %}"
|
hx-get="{% url 'category_edit' category_id=category.id %}"
|
||||||
hx-target="#generic-offcanvas">
|
hx-target="#generic-offcanvas">
|
||||||
<i class="fa-solid fa-pencil fa-fw"></i></a>
|
<i class="fa-solid fa-pencil fa-fw"></i></a>
|
||||||
<a class="btn btn-secondary btn-sm text-danger"
|
<a class="tw:btn tw:btn-secondary tw:btn-sm tw:join-item tw:text-error"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Delete" %}"
|
data-bs-title="{% translate "Delete" %}"
|
||||||
@@ -43,7 +43,7 @@
|
|||||||
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"></i></a>
|
_="install prompt_swal"><i class="fa-solid fa-trash fa-fw"></i></a>
|
||||||
{% if not category.owner %}
|
{% if not category.owner %}
|
||||||
<a class="btn btn-secondary btn-sm text-primary"
|
<a class="tw:btn tw:btn-secondary tw:btn-sm tw:join-item tw:text-primary"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Take ownership" %}"
|
data-bs-title="{% translate "Take ownership" %}"
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
<i class="fa-solid fa-crown fa-fw"></i></a>
|
<i class="fa-solid fa-crown fa-fw"></i></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if user == category.owner %}
|
{% if user == category.owner %}
|
||||||
<a class="btn btn-secondary btn-sm text-primary"
|
<a class="tw:btn tw:btn-secondary tw:btn-sm tw:join-item tw:text-primary"
|
||||||
role="button"
|
role="button"
|
||||||
hx-target="#generic-offcanvas"
|
hx-target="#generic-offcanvas"
|
||||||
hx-swap="innerHTML"
|
hx-swap="innerHTML"
|
||||||
@@ -62,9 +62,9 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="col">{{ category.name }}</td>
|
<td>{{ category.name }}</td>
|
||||||
<td class="col">
|
<td>
|
||||||
{% if category.mute %}<i class="fa-solid fa-check text-success"></i>{% endif %}
|
{% if category.mute %}<i class="fa-solid fa-check tw:text-success"></i>{% endif %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|||||||
@@ -7,49 +7,33 @@
|
|||||||
{% block body %}
|
{% block body %}
|
||||||
{% regroup month_year_data by year as years_list %}
|
{% regroup month_year_data by year as years_list %}
|
||||||
|
|
||||||
<ul class="nav nav-pills nav-fill" id="yearTabs" role="tablist">
|
<div role="tablist" class="tw:tabs tw:tabs-bordered tw:w-full" id="yearTabs">
|
||||||
{% for x in years_list %}
|
{% for x in years_list %}
|
||||||
<li class="nav-item" role="presentation">
|
<input type="radio"
|
||||||
<button class="nav-link{% if x.grouper == current_year %} active{% endif %}"
|
name="year_tabs"
|
||||||
id="{{ x.grouper }}"
|
role="tab"
|
||||||
data-bs-toggle="tab"
|
class="tw:tab"
|
||||||
data-bs-target="#{{ x.grouper }}-pane"
|
aria-label="{{ x.grouper }}"
|
||||||
type="button"
|
id="tab-{{ x.grouper }}"
|
||||||
role="tab"
|
{% if x.grouper == current_year %}checked="checked"{% endif %} />
|
||||||
aria-controls="{{ x.grouper }}-pane"
|
<div role="tabpanel" class="tw:tab-content tw:p-4" id="{{ x.grouper }}-pane">
|
||||||
aria-selected="{% if x.grouper == current_year %}true{% else %}false{% endif %}">
|
<ul class="tw:menu tw:bg-base-100 tw:w-full" id="month-year-list" hx-boost="true">
|
||||||
{{ x.grouper }}
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
<div class="tab-content" id="yearTabsContent" hx-boost="true">
|
|
||||||
{% for x in years_list %}
|
|
||||||
<div class="tab-pane fade{% if x.grouper == current_year %} show active{% endif %} mt-2"
|
|
||||||
id="{{ x.grouper }}-pane"
|
|
||||||
role="tabpanel"
|
|
||||||
aria-labelledby="{{ x.grouper }}"
|
|
||||||
tabindex="0">
|
|
||||||
<ul class="list-group list-group-flush" id="month-year-list">
|
|
||||||
{% for month_data in x.list %}
|
{% for month_data in x.list %}
|
||||||
<li class="list-group-item tw:hover:bg-zinc-900
|
<li {% if month_data.month == current_month and month_data.year == current_year %}class="tw:disabled"{% endif %}>
|
||||||
{% if month_data.month == current_month and month_data.year == current_year %} disabled bg-primary{% endif %}"
|
<a class="{% if month_data.month == current_month and month_data.year == current_year %}tw:active{% endif %}"
|
||||||
{% if month_data.month == current_month and month_data.year == current_year %}aria-disabled="true"{% endif %}>
|
href={{ month_data.url }}
|
||||||
<div class="d-flex justify-content-between">
|
{% if month_data.month == current_month and month_data.year == current_year %}aria-disabled="true"{% endif %}>
|
||||||
<a class="text-decoration-none stretched-link {% if month_data.month == current_month and month_data.year == current_year %} text-black{% endif %}"
|
<span class="tw:flex-1">{{ month_data.month|month_name }}</span>
|
||||||
href={{ month_data.url }}>
|
<span class="tw:badge tw:badge-primary">{{ month_data.transaction_count }}</span>
|
||||||
{{ month_data.month|month_name }}</a>
|
</a>
|
||||||
<span class="badge text-bg-secondary">{{ month_data.transaction_count }}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr class="tw:border-base-300">
|
||||||
<div class="w-full text-end">
|
<div class="tw:w-full tw:text-end">
|
||||||
<a class="btn btn-outline-primary btn-sm" href="{{ today_url }}" role="button" hx-boost="true">{% trans 'Today' %}</a>
|
<a class="tw:btn tw:btn-outline tw:btn-primary tw:btn-sm" href="{{ today_url }}" role="button" hx-boost="true">{% trans 'Today' %}</a>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -2,19 +2,25 @@
|
|||||||
{% load toast_bg %}
|
{% load toast_bg %}
|
||||||
{% if messages %}
|
{% if messages %}
|
||||||
{% for message in messages %}
|
{% for message in messages %}
|
||||||
<div class="toast align-items-center text-bg-{{ message.tags | toast_bg }} border-0"
|
<div class="tw:alert tw:alert-{{ message.tags | toast_bg }}"
|
||||||
role="alert"
|
role="alert"
|
||||||
aria-live="assertive"
|
aria-live="assertive"
|
||||||
aria-atomic="true">
|
aria-atomic="true">
|
||||||
<div class="toast-header">
|
<div class="tw:flex tw:items-center tw:justify-between tw:w-full">
|
||||||
<i class="{{ message.tags | toast_icon }} fa-fw me-1"></i>
|
<div class="tw:flex tw:items-center tw:gap-2">
|
||||||
<strong class="me-auto">{{ message.tags | toast_title }}</strong>
|
<i class="{{ message.tags | toast_icon }} fa-fw"></i>
|
||||||
|
<div>
|
||||||
|
<strong>{{ message.tags | toast_title }}</strong>
|
||||||
|
<div>{{ message }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<button type="button"
|
<button type="button"
|
||||||
class="btn-close"
|
class="tw:btn tw:btn-ghost tw:btn-sm tw:btn-circle"
|
||||||
data-bs-dismiss="toast"
|
data-bs-dismiss="toast"
|
||||||
aria-label={% translate 'Close' %}></button>
|
aria-label={% translate 'Close' %}>
|
||||||
|
<i class="fa-solid fa-xmark"></i>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="toast-body">{{ message }}</div>
|
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
{% load currency_display %}
|
{% load currency_display %}
|
||||||
|
|
||||||
{% if not divless %}
|
{% if not divless %}
|
||||||
<div class="{% if text_end %}text-end{% elif text_start %}text-start{% endif %}">
|
<div class="{% if text_end %}tw:text-end{% elif text_start %}tw:text-start{% endif %}">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<span class="amount{% if color == 'grey' or color == "gray" %} tw:text-gray-500{% elif color == 'green' %} tw:text-green-400{% elif color == 'red' %} tw:text-red-400{% endif %} {{ custom_class }}"
|
<span class="amount{% if color == 'grey' or color == "gray" %} tw:text-base-content/70{% elif color == 'green' %} tw:dark:text-green-400 tw:text-green-600 {% elif color == 'red' %} tw:dark:text-red-400 tw:text-red-600{% endif %} {{ custom_class }}"
|
||||||
data-original-value="{% currency_display amount=amount prefix=prefix suffix=suffix decimal_places=decimal_places %}"
|
data-original-value="{% currency_display amount=amount prefix=prefix suffix=suffix decimal_places=decimal_places %}"
|
||||||
data-amount="{{ amount|floatformat:"-40u" }}">
|
data-amount="{{ amount|floatformat:"-40u" }}">
|
||||||
</span><span>{{ slot }}</span>
|
</span><span>{{ slot }}</span>
|
||||||
|
|||||||
@@ -1,33 +1,14 @@
|
|||||||
<div class="tw:min-h-16">
|
{% load i18n%}
|
||||||
<div
|
|
||||||
id="fab-wrapper"
|
|
||||||
class="tw:fixed tw:bottom-5 tw:right-5 tw:ml-auto tw:w-max tw:flex tw:flex-col tw:items-end mt-5 tw:z-20">
|
|
||||||
<div
|
|
||||||
id="menu"
|
|
||||||
class="tw:flex tw:flex-col tw:items-end tw:space-y-6 tw:transition-all tw:duration-300 tw:ease-in-out tw:opacity-0 tw:invisible tw:hidden tw:mb-2">
|
|
||||||
|
|
||||||
{{ slot }}
|
<div class="tw:fab">
|
||||||
|
<div tabindex="0" role="button" class="tw:btn tw:btn-lg tw:btn-circle tw:btn-primary">
|
||||||
|
<i class="fa-solid fa-plus tw:text-2xl fa-fw"></i>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button
|
<div class="tw:fab-close">
|
||||||
class="btn btn-primary rounded-circle p-0 tw:w-12 tw:h-12 tw:flex tw:items-center tw:justify-center tw:shadow-lg tw:hover:shadow-xl tw:focus:shadow-xl tw:transition-all tw:duration-300 tw:ease-in-out"
|
{% trans 'Close' %} <span class="tw:btn tw:btn-circle tw:btn-lg tw:btn-error"><i class="fa-solid fa-xmark tw:text-2xl fa-fw"></i></span>
|
||||||
_="
|
</div>
|
||||||
on click or focusout
|
|
||||||
if #menu.classList.contains('tw:invisible') and event.type === 'click'
|
{{ slot }}
|
||||||
add .{'tw:rotate-45'} to #fab-icon
|
|
||||||
remove .{'tw:invisible'} from #menu
|
</div>
|
||||||
remove .{'tw:hidden'} from #menu
|
|
||||||
remove .{'tw:opacity-0'} from #menu
|
|
||||||
else
|
|
||||||
wait 0.2s
|
|
||||||
remove .{'tw:rotate-45'} from #fab-icon
|
|
||||||
add .{'tw:invisible'} to #menu
|
|
||||||
add .{'tw:hidden'} to #menu
|
|
||||||
add .{'tw:opacity-0'} to #menu
|
|
||||||
end
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<i id="fab-icon" class="fa-solid fa-plus tw:text-3xl tw:transition-transform tw:duration-300 tw:ease-in-out"></i>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,11 +1,6 @@
|
|||||||
{% load i18n %}
|
<div hx-get="{{ url }}"
|
||||||
<div class="tw:relative fab-item">
|
hx-trigger="{{ hx_trigger }}"
|
||||||
<button class="btn btn-sm btn-{{ color }}"
|
hx-target="{{ hx_target }}"
|
||||||
hx-get="{{ url }}"
|
hx-vals='{{ hx_vals }}'>
|
||||||
hx-trigger="{{ hx_trigger }}"
|
{{ title }}
|
||||||
hx-target="{{ hx_target }}"
|
<button class="tw:btn tw:btn-lg tw:btn-circle tw:btn-{{color}}"><i class="{{ icon }} fa-fw"></i></button></div>
|
||||||
hx-vals='{{ hx_vals }}'>
|
|
||||||
<i class="{{ icon }} me-2"></i>
|
|
||||||
{{ title }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
<li class="tw:lg:hidden tw:lg:group-hover:block">
|
<li class="tw:lg:hidden tw:lg:group-hover:block">
|
||||||
<div class="d-flex align-items-center" data-bs-toggle="collapse" href="#{{ title|slugify }}" role="button"
|
<div class="tw:flex tw:items-center" data-bs-toggle="collapse" href="#{{ title|slugify }}" role="button"
|
||||||
aria-expanded="false" aria-controls="{{ title|slugify }}">
|
aria-expanded="false" aria-controls="{{ title|slugify }}">
|
||||||
<span
|
<span
|
||||||
class="text-muted small fw-bold text-uppercase tw:lg:hidden tw:lg:group-hover:inline me-2">{{ title }}</span>
|
class="tw:text-base-content/60 tw:text-sm tw:font-bold tw:uppercase tw:lg:hidden tw:lg:group-hover:inline tw:me-2">{{ title }}</span>
|
||||||
<hr class="flex-grow-1"/>
|
<hr class="tw:flex-grow"/>
|
||||||
<i class="fas fa-chevron-down text-muted tw:lg:before:hidden tw:lg:group-hover:before:inline tw:ml-2 tw:lg:ml-0 tw:lg:group-hover:ml-2"></i>
|
<i class="fas fa-chevron-down tw:text-base-content/60 tw:lg:before:hidden tw:lg:group-hover:before:inline tw:ml-2 tw:lg:ml-0 tw:lg:group-hover:ml-2"></i>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<div class="collapse tw:lg:hidden tw:lg:group-hover:block" id="{{ title|slugify }}">
|
<div class="tw:collapse tw:lg:hidden tw:lg:group-hover:block" id="{{ title|slugify }}">
|
||||||
{{ slot }}
|
{{ slot }}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<li>
|
<li>
|
||||||
<div class="d-flex align-items-center">
|
<div class="tw:flex tw:items-center">
|
||||||
<span class="sidebar-menu-header text-muted small fw-bold text-uppercase me-2">{{ title }}</span>
|
<span class="sidebar-menu-header tw:text-base-content/60 tw:text-sm tw:font-bold tw:uppercase tw:mr-3">{{ title }}</span>
|
||||||
<hr class="flex-grow-1"/>
|
<hr class="tw:text-base-content/60 tw:flex-grow"/>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{% load active_link %}
|
{% load active_link %}
|
||||||
<li>
|
<li>
|
||||||
<a href="{% url url %}"
|
<a href="{% url url %}"
|
||||||
class="tw:lg:text-sm d-flex align-items-center text-decoration-none p-2 rounded-3 sidebar-item {% active_link views=active css_class="sidebar-active" %}"
|
class="tw:lg:text-sm tw:flex tw:items-center tw:no-underline tw:p-2 tw:rounded-3xl sidebar-item {% active_link views=active css_class="sidebar-active" %}"
|
||||||
{% if tooltip %}
|
{% if tooltip %}
|
||||||
data-bs-placement="right"
|
data-bs-placement="right"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
@@ -9,6 +9,6 @@
|
|||||||
{% endif %}>
|
{% endif %}>
|
||||||
<i class="{{ icon }} fa-fw"></i>
|
<i class="{{ icon }} fa-fw"></i>
|
||||||
<span
|
<span
|
||||||
class="ms-3 fw-medium tw:lg:group-hover:truncate tw:lg:group-focus:truncate tw:lg:group-hover:text-ellipsis tw:lg:group-focus:text-ellipsis">{{ title }}</span>
|
class="tw:ms-3 tw:font-medium tw:lg:group-hover:truncate tw:lg:group-focus:truncate tw:lg:group-hover:text-ellipsis tw:lg:group-focus:text-ellipsis">{{ title }}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<li>
|
<li>
|
||||||
<a href="{{ url }}"
|
<a href="{{ url }}"
|
||||||
hx-boost="false"
|
hx-boost="false"
|
||||||
class="tw:lg:text-sm d-flex align-items-center text-decoration-none p-2 rounded-3 sidebar-item {% active_link views=active css_class="sidebar-active" %}"
|
class="tw:lg:text-sm tw:flex tw:items-center tw:no-underline tw:p-2 tw:rounded-3xl sidebar-item {% active_link views=active css_class="sidebar-active" %}"
|
||||||
{% if tooltip %}
|
{% if tooltip %}
|
||||||
data-bs-placement="right"
|
data-bs-placement="right"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
@@ -11,6 +11,6 @@
|
|||||||
|
|
||||||
<i class="{{ icon }} fa-fw"></i>
|
<i class="{{ icon }} fa-fw"></i>
|
||||||
<span
|
<span
|
||||||
class="ms-3 fw-medium tw:lg:group-hover:truncate tw:lg:group-focus:truncate tw:lg:group-hover:text-ellipsis tw:lg:group-focus:text-ellipsis">{{ title }}</span>
|
class="tw:ms-3 tw:font-medium tw:lg:group-hover:truncate tw:lg:group-focus:truncate tw:lg:group-hover:text-ellipsis tw:lg:group-focus:text-ellipsis">{{ title }}</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
<div id="search" class="mb-3">
|
<div id="search" class="tw:mb-3">
|
||||||
<label class="w-100">
|
<label class="tw:w-full">
|
||||||
<input type="search"
|
<input type="search"
|
||||||
class="form-control"
|
class="tw:input tw:input-bordered tw:w-full"
|
||||||
placeholder="{% translate 'Search' %}"
|
placeholder="{% translate 'Search' %}"
|
||||||
_="on input or search
|
_="on input or search
|
||||||
show < tbody>tr /> in <table/>
|
show < tbody>tr /> in <table/>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<div class="row {% if not remove_padding %}p-5{% endif %}">
|
<div class="tw:grid tw:grid-cols-1 {% if not remove_padding %}tw:p-5{% endif %}">
|
||||||
<div class="col {% if not remove_padding %}p-5{% endif %}">
|
<div class="{% if not remove_padding %}tw:p-5{% endif %}">
|
||||||
<div class="text-center">
|
<div class="tw:text-center">
|
||||||
<i class="{% if icon %}{{ icon }}{% else %}fa-solid fa-circle-xmark{% endif %} tw:text-6xl"></i>
|
<i class="{% if icon %}{{ icon }}{% else %}fa-solid fa-circle-xmark{% endif %} tw:text-6xl"></i>
|
||||||
<p class="lead mt-4 mb-0">{{ title }}</p>
|
<p class="tw:text-lg tw:mt-4 tw:mb-0">{{ title }}</p>
|
||||||
<p class="tw:text-gray-500">{{ subtitle }}</p>
|
<p class="tw:text-gray-500">{{ subtitle }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,22 +2,21 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
<div
|
<div
|
||||||
class="transaction {% if transaction.type == "EX" %}expense{% else %}income{% endif %} tw:group/transaction tw:relative tw:hover:z-10">
|
class="transaction {% if transaction.type == "EX" %}expense{% else %}income{% endif %} tw:group/transaction tw:relative tw:hover:z-10">
|
||||||
<div class="d-flex my-1">
|
<div class="tw:flex tw:my-1">
|
||||||
{% if not disable_selection or not dummy %}
|
{% if not disable_selection or not dummy %}
|
||||||
<label class="px-3 d-flex align-items-center justify-content-center">
|
<label class="tw:px-3 tw:flex! tw:items-center tw:justify-center">
|
||||||
<input class="form-check-input" type="checkbox" name="transactions" value="{{ transaction.id }}"
|
<input class="tw:checkbox" type="checkbox" name="transactions" value="{{ transaction.id }}"
|
||||||
id="check-{{ transaction.id }}" aria-label="{% translate 'Select' %}" hx-preserve>
|
id="check-{{ transaction.id }}" aria-label="{% translate 'Select' %}" hx-preserve>
|
||||||
</label>
|
</label>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="tw:border-s-4 tw:border-e-0 tw:border-t-0 tw:border-b-0 border-bottom
|
<div class="tw:border-s-4 tw:border-e-0 tw:border-t-0
|
||||||
tw:hover:bg-zinc-900 p-2 {% if transaction.account.is_asset %}tw:border-dashed{% else %}tw:border-solid{% endif %}
|
tw:hover:bg-neutral-500/20 tw:p-2 {% if transaction.account.is_asset %}tw:border-l-dashed{% else %}tw:border-solid{% endif %}
|
||||||
{% if transaction.type == "EX" %}tw:border-red-500{% else %}tw:border-green-500{% endif %} tw:relative
|
{% if transaction.type == "EX" %}tw:border-l-red-500{% else %}tw:border-l-green-500{% endif %} tw:relative
|
||||||
w-100 transaction-item">
|
tw:w-full transaction-item tw:bg-base-200 tw:rounded">
|
||||||
<div class="row font-monospace tw:text-sm align-items-center">
|
<div class="tw:flex tw:flex-wrap tw:font-mono tw:text-sm tw:items-center">
|
||||||
<div
|
<div class="tw:lg:w-auto tw:w-full tw:flex tw:items-center tw:text-2xl tw:lg:text-xl tw:lg:text-center tw:text-center tw:p-0 tw:cursor-pointer">
|
||||||
class="col-lg-auto col-12 d-flex align-items-center tw:text-2xl tw:lg:text-xl text-lg-center text-center p-0 ps-1">
|
|
||||||
{% if not transaction.deleted %}
|
{% if not transaction.deleted %}
|
||||||
<a class="text-decoration-none p-3 tw:text-gray-500!"
|
<a class="tw:no-underline tw:p-3 tw:text-gray-500!"
|
||||||
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 %}
|
||||||
@@ -28,7 +27,7 @@
|
|||||||
class="fa-regular fa-circle"></i>{% endif %}
|
class="fa-regular fa-circle"></i>{% endif %}
|
||||||
</a>
|
</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="text-decoration-none p-3 tw:text-gray-500!"
|
<div class="tw:no-underline tw:p-3 tw:text-gray-500!"
|
||||||
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 %}
|
||||||
@@ -36,79 +35,79 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="col-lg col-12 {% if transaction.account.is_untracked_by or transaction.category.mute or transaction.mute %}tw:brightness-80{% endif %}">
|
class="tw:lg:flex-1 tw:w-full {% if transaction.account.is_untracked_by or transaction.category.mute or transaction.mute %}tw:brightness-80{% endif %}">
|
||||||
{# Date#}
|
{# Date#}
|
||||||
<div class="row mb-2 mb-lg-1 tw:text-gray-400">
|
<div class="tw:flex tw:flex-wrap tw:mb-2 tw:lg:mb-1 tw:text-base-content/70">
|
||||||
<div class="col-auto pe-1"><i class="fa-solid fa-calendar fa-fw me-1 fa-xs"></i></div>
|
<div class="tw:w-auto tw:pe-1"><i class="fa-solid fa-calendar fa-fw tw:mr-1 fa-xs"></i></div>
|
||||||
<div
|
<div
|
||||||
class="col ps-0">{{ transaction.date|date:"SHORT_DATE_FORMAT" }} • {{ transaction.reference_date|date:"b/Y" }}</div>
|
class="tw:flex-1 tw:ps-0">{{ transaction.date|date:"SHORT_DATE_FORMAT" }} • {{ transaction.reference_date|date:"b/Y" }}</div>
|
||||||
</div>
|
</div>
|
||||||
{# Description#}
|
{# Description#}
|
||||||
<div class="mb-2 mb-lg-1 text-body tw:text-base">
|
<div class="tw:mb-2 tw:lg:mb-1 tw:text-base-content tw:text-base">
|
||||||
{% spaceless %}
|
{% spaceless %}
|
||||||
<span class="{% if transaction.description %}me-2{% endif %}">{{ transaction.description }}</span>
|
<span class="{% if transaction.description %}tw:mr-2{% endif %}">{{ transaction.description }}</span>
|
||||||
{% if transaction.installment_plan and transaction.installment_id %}
|
{% if transaction.installment_plan and transaction.installment_id %}
|
||||||
<span
|
<span
|
||||||
class="badge text-bg-secondary mx-1">{{ transaction.installment_id }}/{{ transaction.installment_plan.installment_total_number }}</span>
|
class="tw:badge tw:badge-neutral tw:mx-1">{{ transaction.installment_id }}/{{ transaction.installment_plan.installment_total_number }}</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if transaction.recurring_transaction %}
|
{% if transaction.recurring_transaction %}
|
||||||
<span class="text-primary tw:text-xs mx-1"><i class="fa-solid fa-arrows-rotate fa-fw"></i></span>
|
<span class="tw:text-primary tw:text-xs tw:mx-1"><i class="fa-solid fa-arrows-rotate fa-fw"></i></span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if transaction.dca_expense_entries.all or transaction.dca_income_entries.all %}
|
{% if transaction.dca_expense_entries.all or transaction.dca_income_entries.all %}
|
||||||
<span class="badge text-bg-secondary mx-1">{% trans 'DCA' %}</span>
|
<span class="tw:badge tw:badge-neutral tw:mx-1">{% trans 'DCA' %}</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endspaceless %}
|
{% endspaceless %}
|
||||||
</div>
|
</div>
|
||||||
<div class="tw:text-gray-400 tw:text-sm">
|
<div class="tw:text-base-content/70 tw:text-sm">
|
||||||
{# Entities #}
|
{# Entities #}
|
||||||
{% comment %} First, check for the highest priority: a valid 'overriden_entities' list. {% endcomment %}
|
{% comment %} First, check for the highest priority: a valid 'overriden_entities' list. {% endcomment %}
|
||||||
{% if overriden_entities %}
|
{% if overriden_entities %}
|
||||||
<div class="row mb-2 mb-lg-1 tw:text-gray-400">
|
<div class="tw:flex tw:flex-wrap tw:mb-2 tw:lg:mb-1 tw:text-base-content/70">
|
||||||
<div class="col-auto pe-1"><i class="fa-solid fa-user-group fa-fw me-1 fa-xs"></i></div>
|
<div class="tw:w-auto tw:pe-1"><i class="fa-solid fa-user-group fa-fw tw:mr-1 fa-xs"></i></div>
|
||||||
<div class="col ps-0">{{ overriden_entities|join:", " }}</div>
|
<div class="tw:flex-1 tw:ps-0">{{ overriden_entities|join:", " }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% comment %} If no override, fall back to transaction entities, but ONLY if the transaction has an ID. {% endcomment %}
|
{% comment %} If no override, fall back to transaction entities, but ONLY if the transaction has an ID. {% endcomment %}
|
||||||
{% elif transaction.id and transaction.entities.all %}
|
{% elif transaction.id and transaction.entities.all %}
|
||||||
<div class="row mb-2 mb-lg-1 tw:text-gray-400">
|
<div class="tw:flex tw:flex-wrap tw:mb-2 tw:lg:mb-1 tw:text-base-content/70">
|
||||||
<div class="col-auto pe-1"><i class="fa-solid fa-user-group fa-fw me-1 fa-xs"></i></div>
|
<div class="tw:w-auto tw:pe-1"><i class="fa-solid fa-user-group fa-fw tw:mr-1 fa-xs"></i></div>
|
||||||
<div class="col ps-0">{{ transaction.entities.all|join:", " }}</div>
|
<div class="tw:flex-1 tw:ps-0">{{ transaction.entities.all|join:", " }}</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{# Notes#}
|
{# Notes#}
|
||||||
{% if transaction.notes %}
|
{% if transaction.notes %}
|
||||||
<div class="row mb-2 mb-lg-1 tw:text-gray-400">
|
<div class="tw:flex tw:flex-wrap tw:mb-2 tw:lg:mb-1 tw:text-base-content/70">
|
||||||
<div class="col-auto pe-1"><i class="fa-solid fa-align-left fa-fw me-1 fa-xs"></i></div>
|
<div class="tw:w-auto tw:pe-1"><i class="fa-solid fa-align-left fa-fw tw:mr-1 fa-xs"></i></div>
|
||||||
<div class="col ps-0">{{ transaction.notes | limited_markdown | linebreaksbr }}</div>
|
<div class="tw:flex-1 tw:ps-0">{{ transaction.notes | limited_markdown | linebreaksbr }}</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{# Category#}
|
{# Category#}
|
||||||
{% if transaction.category %}
|
{% if transaction.category %}
|
||||||
<div class="row mb-2 mb-lg-1 tw:text-gray-400">
|
<div class="tw:flex tw:flex-wrap tw:mb-2 tw:lg:mb-1 tw:text-base-content/70">
|
||||||
<div class="col-auto pe-1"><i class="fa-solid fa-icons fa-fw me-1 fa-xs"></i></div>
|
<div class="tw:w-auto tw:pe-1"><i class="fa-solid fa-icons fa-fw tw:mr-1 fa-xs"></i></div>
|
||||||
<div class="col ps-0">{{ transaction.category.name }}</div>
|
<div class="tw:flex-1 tw:ps-0">{{ transaction.category.name }}</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{# Tags#}
|
{# Tags#}
|
||||||
{% comment %} First, check for the highest priority: a valid 'overriden_tags' list. {% endcomment %}
|
{% comment %} First, check for the highest priority: a valid 'overriden_tags' list. {% endcomment %}
|
||||||
{% if overriden_tags %}
|
{% if overriden_tags %}
|
||||||
<div class="row mb-2 mb-lg-1 tw:text-gray-400">
|
<div class="tw:flex tw:flex-wrap tw:mb-2 tw:lg:mb-1 tw:text-base-content/70">
|
||||||
<div class="col-auto pe-1"><i class="fa-solid fa-hashtag fa-fw me-1 fa-xs"></i></div>
|
<div class="tw:w-auto tw:pe-1"><i class="fa-solid fa-hashtag fa-fw tw:mr-1 fa-xs"></i></div>
|
||||||
<div class="col ps-0">{{ overriden_tags|join:", " }}</div>
|
<div class="tw:flex-1 tw:ps-0">{{ overriden_tags|join:", " }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% comment %} If no override, fall back to transaction tags, but ONLY if the transaction has an ID. {% endcomment %}
|
{% comment %} If no override, fall back to transaction tags, but ONLY if the transaction has an ID. {% endcomment %}
|
||||||
{% elif transaction.id and transaction.tags.all %}
|
{% elif transaction.id and transaction.tags.all %}
|
||||||
<div class="row mb-2 mb-lg-1 tw:text-gray-400">
|
<div class="tw:flex tw:flex-wrap tw:mb-2 tw:lg:mb-1 tw:text-base-content/70">
|
||||||
<div class="col-auto pe-1"><i class="fa-solid fa-hashtag fa-fw me-1 fa-xs"></i></div>
|
<div class="tw:w-auto tw:pe-1"><i class="fa-solid fa-hashtag fa-fw tw:mr-1 fa-xs"></i></div>
|
||||||
<div class="col ps-0">{{ transaction.tags.all|join:", " }}</div>
|
<div class="tw:flex-1 tw:ps-0">{{ transaction.tags.all|join:", " }}</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="col-lg-auto col-12 text-lg-end align-self-end {% if transaction.account.is_untracked_by or transaction.category.mute or transaction.mute %}tw:brightness-80{% endif %}">
|
class="tw:lg:w-auto tw:w-full tw:lg:text-right tw:self-end {% if transaction.account.is_untracked_by or transaction.category.mute or transaction.mute %}tw:brightness-80{% endif %}">
|
||||||
<div class="main-amount mb-2 mb-lg-0">
|
<div class="main-amount tw:mb-2 tw:lg:mb-0">
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="transaction.amount"
|
:amount="transaction.amount"
|
||||||
:prefix="transaction.account.currency.prefix"
|
:prefix="transaction.account.currency.prefix"
|
||||||
@@ -120,7 +119,7 @@
|
|||||||
{% if not dummy %}
|
{% if not dummy %}
|
||||||
{% with exchanged=transaction.exchanged_amount %}
|
{% with exchanged=transaction.exchanged_amount %}
|
||||||
{% if exchanged %}
|
{% if exchanged %}
|
||||||
<div class="exchanged-amount mb-2 mb-lg-0">
|
<div class="exchanged-amount tw:mb-2 tw:lg:mb-0">
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="exchanged.amount"
|
:amount="exchanged.amount"
|
||||||
:prefix="exchanged.prefix"
|
:prefix="exchanged.prefix"
|
||||||
@@ -139,109 +138,106 @@
|
|||||||
<div>
|
<div>
|
||||||
{# Item actions#}
|
{# Item actions#}
|
||||||
<div
|
<div
|
||||||
class="transaction-actions tw:absolute! tw:left-1/2 tw:top-0 tw:-translate-x-1/2 tw:-translate-y-1/2 tw:invisible tw:group-hover/transaction:visible d-flex flex-row card">
|
class="transaction-actions tw:absolute! tw:left-1/2 tw:top-0 tw:-translate-x-1/2 tw:-translate-y-1/2 tw:invisible tw:group-hover/transaction:visible tw:flex tw:flex-row tw:card tw:bg-base-300">
|
||||||
<div class="card-body p-1 shadow-lg d-flex flex-row gap-1">
|
<div class="tw:card-body tw:p-1 tw:shadow-lg tw:flex tw:flex-row tw:gap-1">
|
||||||
{% if not transaction.deleted %}
|
{% if not transaction.deleted %}
|
||||||
<a class="btn btn-secondary btn-sm transaction-action"
|
<div class="tw:tooltip" data-tip="{% translate "Edit" %}">
|
||||||
role="button"
|
<a class="tw:btn btn-neutral tw:btn-sm transaction-action"
|
||||||
data-bs-toggle="tooltip"
|
role="button"
|
||||||
data-bs-title="{% translate "Edit" %}"
|
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">
|
<i class="fa-solid fa-pencil fa-fw"></i></a>
|
||||||
<i class="fa-solid fa-pencil fa-fw"></i></a>
|
</div>
|
||||||
<a class="btn btn-secondary btn-sm transaction-action"
|
<div class="tw:tooltip" data-tip="{% translate "Delete" %}">
|
||||||
role="button"
|
<a class="tw:btn btn-neutral tw:btn-sm transaction-action"
|
||||||
data-bs-toggle="tooltip"
|
role="button"
|
||||||
data-bs-title="{% translate "Delete" %}"
|
hx-delete="{% url 'transaction_delete' transaction_id=transaction.id %}"
|
||||||
hx-delete="{% url 'transaction_delete' transaction_id=transaction.id %}"
|
hx-trigger='confirmed'
|
||||||
hx-trigger='confirmed'
|
data-bypass-on-ctrl="true"
|
||||||
data-bypass-on-ctrl="true"
|
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 tw:text-red-500"></i>
|
||||||
_="install prompt_swal"><i class="fa-solid fa-trash fa-fw text-danger"></i>
|
</a>
|
||||||
</a>
|
</div>
|
||||||
<button class="btn btn-secondary btn-sm transaction-action" type="button" data-bs-toggle="dropdown"
|
<div class="tw:dropdown tw:dropdown-end">
|
||||||
aria-expanded="false">
|
<button type="button" tabindex="0" role="button" class="tw:btn btn-neutral tw:btn-sm transaction-action">
|
||||||
<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">
|
<ul tabindex="0" class="tw:dropdown-content tw:menu tw:p-2 tw:shadow tw:bg-base-200 tw:rounded-box tw:w-72 z-[1]">
|
||||||
{% if transaction.account.is_untracked_by %}
|
{% if transaction.account.is_untracked_by %}
|
||||||
<li>
|
<li>
|
||||||
<a class="dropdown-item disabled d-flex align-items-center" aria-disabled="true">
|
<a class="tw:disabled tw:flex tw:items-center" aria-disabled="true">
|
||||||
<i class="fa-solid fa-eye fa-fw me-2"></i>
|
<i class="fa-solid fa-eye fa-fw tw:mr-2"></i>
|
||||||
<div>
|
<div>
|
||||||
{% translate 'Show on summaries' %}
|
{% translate 'Show on summaries' %}
|
||||||
<div
|
<div
|
||||||
class="d-block text-body-secondary tw:text-xs tw:font-medium">{% translate 'Controlled by account' %}</div>
|
class="tw:block tw:text-gray-500 tw:text-xs tw:font-medium">{% translate 'Controlled by account' %}</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
</li>
|
||||||
|
{% elif transaction.category.mute %}
|
||||||
|
<li>
|
||||||
|
<a class="tw:disabled tw:flex tw:items-center" aria-disabled="true">
|
||||||
|
<i class="fa-solid fa-eye fa-fw tw:mr-2"></i>
|
||||||
|
<div>
|
||||||
|
{% translate 'Show on summaries' %}
|
||||||
|
<div
|
||||||
|
class="tw:block tw:text-gray-500 tw:text-xs tw:font-medium">{% translate 'Controlled by category' %}</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% elif transaction.mute %}
|
||||||
|
<li><a href="#"
|
||||||
|
hx-get="{% url 'transaction_mute' transaction_id=transaction.id %}"
|
||||||
|
hx-target="closest .transaction" hx-swap="outerHTML"><i
|
||||||
|
class="fa-solid fa-eye fa-fw tw:mr-2"></i>{% translate 'Show on summaries' %}</a></li>
|
||||||
|
{% else %}
|
||||||
|
<li><a href="#"
|
||||||
|
hx-get="{% url 'transaction_mute' transaction_id=transaction.id %}"
|
||||||
|
hx-target="closest .transaction" hx-swap="outerHTML"><i
|
||||||
|
class="fa-solid fa-eye-slash fa-fw tw:mr-2"></i>{% translate 'Hide from summaries' %}</a></li>
|
||||||
|
{% endif %}
|
||||||
|
<li><a href="#"
|
||||||
|
hx-get="{% url 'quick_transaction_add_as_quick_transaction' transaction_id=transaction.id %}"><i
|
||||||
|
class="fa-solid fa-person-running fa-fw tw:mr-2"></i>{% translate 'Add as quick transaction' %}</a>
|
||||||
</li>
|
</li>
|
||||||
{% elif transaction.category.mute %}
|
<hr class="tw:my-1 tw:text-base-content/60">
|
||||||
<li>
|
<li><a href="#"
|
||||||
<a class="dropdown-item disabled d-flex align-items-center" aria-disabled="true">
|
hx-get="{% url 'transaction_change_month' transaction_id=transaction.id change_type='previous' %}"><i
|
||||||
<i class="fa-solid fa-eye fa-fw me-2"></i>
|
class="fa-solid fa-calendar-minus fa-fw tw:mr-2"></i>{% translate 'Move to previous month' %}</a>
|
||||||
<div>
|
|
||||||
{% translate 'Show on summaries' %}
|
|
||||||
<div
|
|
||||||
class="d-block text-body-secondary tw:text-xs tw:font-medium">{% translate 'Controlled by category' %}</div>
|
|
||||||
</div>
|
|
||||||
</a>
|
|
||||||
</li>
|
</li>
|
||||||
{% elif transaction.mute %}
|
<li><a href="#"
|
||||||
<li><a class="dropdown-item" href="#"
|
hx-get="{% url 'transaction_change_month' transaction_id=transaction.id change_type='next' %}"><i
|
||||||
hx-get="{% url 'transaction_mute' transaction_id=transaction.id %}"
|
class="fa-solid fa-calendar-plus fa-fw tw:mr-2"></i>{% translate 'Move to next month' %}</a></li>
|
||||||
hx-target="closest .transaction" hx-swap="outerHTML"><i
|
<li><a href="#"
|
||||||
class="fa-solid fa-eye fa-fw me-2"></i>{% translate 'Show on summaries' %}</a></li>
|
hx-get="{% url 'transaction_move_to_today' transaction_id=transaction.id %}"><i
|
||||||
{% else %}
|
class="fa-solid fa-calendar-day fa-fw tw:mr-2"></i>{% translate 'Move to today' %}</a></li>
|
||||||
<li><a class="dropdown-item" href="#"
|
<hr class="tw:my-1 tw:text-base-content/60">
|
||||||
hx-get="{% url 'transaction_mute' transaction_id=transaction.id %}"
|
<li><a href="#"
|
||||||
hx-target="closest .transaction" hx-swap="outerHTML"><i
|
hx-get="{% url 'transaction_clone' transaction_id=transaction.id %}"><i
|
||||||
class="fa-solid fa-eye-slash fa-fw me-2"></i>{% translate 'Hide from summaries' %}</a></li>
|
class="fa-solid fa-clone fa-fw tw:mr-2"></i>{% translate 'Duplicate' %}</a></li>
|
||||||
{% endif %}
|
</ul>
|
||||||
<li><a class="dropdown-item" href="#"
|
</div>
|
||||||
hx-get="{% url 'quick_transaction_add_as_quick_transaction' transaction_id=transaction.id %}"><i
|
|
||||||
class="fa-solid fa-person-running fa-fw me-2"></i>{% translate 'Add as quick transaction' %}</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<hr class="dropdown-divider">
|
|
||||||
</li>
|
|
||||||
<li><a class="dropdown-item" href="#"
|
|
||||||
hx-get="{% url 'transaction_change_month' transaction_id=transaction.id change_type='previous' %}"><i
|
|
||||||
class="fa-solid fa-calendar-minus fa-fw me-2"></i>{% translate 'Move to previous month' %}</a>
|
|
||||||
</li>
|
|
||||||
<li><a class="dropdown-item" href="#"
|
|
||||||
hx-get="{% url 'transaction_change_month' transaction_id=transaction.id change_type='next' %}"><i
|
|
||||||
class="fa-solid fa-calendar-plus fa-fw me-2"></i>{% translate 'Move to next month' %}</a></li>
|
|
||||||
<li><a class="dropdown-item" href="#"
|
|
||||||
hx-get="{% url 'transaction_move_to_today' transaction_id=transaction.id %}"><i
|
|
||||||
class="fa-solid fa-calendar-day fa-fw me-2"></i>{% translate 'Move to today' %}</a></li>
|
|
||||||
<li>
|
|
||||||
<hr class="dropdown-divider">
|
|
||||||
</li>
|
|
||||||
<li><a class="dropdown-item" href="#"
|
|
||||||
hx-get="{% url 'transaction_clone' transaction_id=transaction.id %}"><i
|
|
||||||
class="fa-solid fa-clone fa-fw me-2"></i>{% translate 'Duplicate' %}</a></li>
|
|
||||||
</ul>
|
|
||||||
{% else %}
|
{% else %}
|
||||||
<a class="btn btn-secondary btn-sm transaction-action"
|
<div class="tw:tooltip" data-tip="{% translate "Restore" %}">
|
||||||
role="button"
|
<a class="tw:btn tw:btn-secondary tw:btn-sm transaction-action"
|
||||||
data-bs-toggle="tooltip"
|
role="button"
|
||||||
data-bs-title="{% translate "Restore" %}"
|
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>
|
||||||
<a class="btn btn-secondary btn-sm transaction-action"
|
<div class="tw:tooltip" data-tip="{% translate "Delete" %}">
|
||||||
role="button"
|
<a class="tw:btn tw:btn-secondary tw:btn-sm transaction-action"
|
||||||
data-bs-toggle="tooltip"
|
role="button"
|
||||||
data-bs-title="{% translate "Delete" %}"
|
hx-delete="{% url 'transaction_delete' transaction_id=transaction.id %}"
|
||||||
hx-delete="{% url 'transaction_delete' transaction_id=transaction.id %}"
|
hx-trigger='confirmed'
|
||||||
hx-trigger='confirmed'
|
data-bypass-on-ctrl="true"
|
||||||
data-bypass-on-ctrl="true"
|
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 tw:text-red-500"></i>
|
||||||
_="install prompt_swal"><i class="fa-solid fa-trash fa-fw text-danger"></i>
|
</a>
|
||||||
</a>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,22 +1,22 @@
|
|||||||
<div class="card mb-2 transaction-item">
|
<div class="tw:card tw:bg-base-100 tw:shadow-xl tw:mb-2 transaction-item">
|
||||||
<div class="card-body p-2 tw:flex tw:items-center tw:gap-3" data-bs-toggle="collapse" data-bs-target="#{{ transaction.id }}" role="button" aria-expanded="false" aria-controls="{{ transaction.id }}">
|
<div class="tw:card-body tw:p-2 tw:flex tw:items-center tw:gap-3" data-bs-toggle="collapse" data-bs-target="#{{ transaction.id }}" role="button" aria-expanded="false" aria-controls="{{ transaction.id }}">
|
||||||
<!-- Main visible content -->
|
<!-- Main visible content -->
|
||||||
<div class="tw:flex flex-lg-row flex-column tw:lg:items-center tw:w-full tw:gap-3">
|
<div class="tw:flex tw:flex-col tw:lg:flex-row tw:lg:items-center tw:w-full tw:gap-3">
|
||||||
<!-- Type indicator -->
|
<!-- Type indicator -->
|
||||||
<div class="tw:w-8">
|
<div class="tw:w-8">
|
||||||
{% if transaction.type == 'IN' %}
|
{% if transaction.type == 'IN' %}
|
||||||
<span class="badge bg-success">↑</span>
|
<span class="tw:badge tw:badge-success">↑</span>
|
||||||
{% else %}
|
{% else %}
|
||||||
<span class="badge bg-danger">↓</span>
|
<span class="tw:badge tw:badge-error">↓</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Payment status -->
|
<!-- Payment status -->
|
||||||
<div class="tw:w-8">
|
<div class="tw:w-8">
|
||||||
{% if transaction.is_paid %}
|
{% if transaction.is_paid %}
|
||||||
<span class="badge bg-success">✓</span>
|
<span class="tw:badge tw:badge-success">✓</span>
|
||||||
{% else %}
|
{% else %}
|
||||||
<span class="badge bg-warning">○</span>
|
<span class="tw:badge tw:badge-warning">○</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
</span>
|
</span>
|
||||||
{% if transaction.exchanged_amount %}
|
{% if transaction.exchanged_amount %}
|
||||||
<br>
|
<br>
|
||||||
<small class="text-muted">
|
<small class="tw:text-base-content/60">
|
||||||
{{ transaction.exchanged_amount.prefix }}{{ transaction.exchanged_amount.amount }}{{ transaction.exchanged_amount.suffix }}
|
{{ transaction.exchanged_amount.prefix }}{{ transaction.exchanged_amount.amount }}{{ transaction.exchanged_amount.suffix }}
|
||||||
</small>
|
</small>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@@ -41,50 +41,50 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Expandable details -->
|
<!-- Expandable details -->
|
||||||
<div class="collapse" id="{{ transaction.id }}">
|
<div class="tw:collapse" id="{{ transaction.id }}">
|
||||||
<div class="card-body p-3 transaction-details">
|
<div class="tw:card-body tw:p-3 transaction-details">
|
||||||
<div class="row">
|
<div class="tw:grid tw:grid-cols-1 tw:md:grid-cols-2">
|
||||||
<div class="col-md-6">
|
<div>
|
||||||
<dl class="row">
|
<dl class="tw:grid tw:grid-cols-3">
|
||||||
<dt class="col-sm-4">Date</dt>
|
<dt class="tw:col-span-1">Date</dt>
|
||||||
<dd class="col-sm-8">{{ transaction.date|date:"Y-m-d" }}</dd>
|
<dd class="tw:col-span-2">{{ transaction.date|date:"Y-m-d" }}</dd>
|
||||||
|
|
||||||
<dt class="col-sm-4">Reference Date</dt>
|
<dt class="tw:col-span-1">Reference Date</dt>
|
||||||
<dd class="col-sm-8">{{ transaction.reference_date|date:"Y-m" }}</dd>
|
<dd class="tw:col-span-2">{{ transaction.reference_date|date:"Y-m" }}</dd>
|
||||||
|
|
||||||
<dt class="col-sm-4">Account</dt>
|
<dt class="tw:col-span-1">Account</dt>
|
||||||
<dd class="col-sm-8">{{ transaction.account.name }}</dd>
|
<dd class="tw:col-span-2">{{ transaction.account.name }}</dd>
|
||||||
|
|
||||||
<dt class="col-sm-4">Category</dt>
|
<dt class="tw:col-span-1">Category</dt>
|
||||||
<dd class="col-sm-8">{{ transaction.category|default:"-" }}</dd>
|
<dd class="tw:col-span-2">{{ transaction.category|default:"-" }}</dd>
|
||||||
</dl>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6">
|
<div>
|
||||||
<dl class="row">
|
<dl class="tw:grid tw:grid-cols-3">
|
||||||
{% if transaction.tags.exists %}
|
{% if transaction.tags.exists %}
|
||||||
<dt class="col-sm-4">Tags</dt>
|
<dt class="tw:col-span-1">Tags</dt>
|
||||||
<dd class="col-sm-8">
|
<dd class="tw:col-span-2">
|
||||||
{% for tag in transaction.tags.all %}
|
{% for tag in transaction.tags.all %}
|
||||||
<span class="badge bg-secondary">{{ tag.name }}</span>
|
<span class="tw:badge tw:badge-secondary">{{ tag.name }}</span>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</dd>
|
</dd>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if transaction.installment_plan %}
|
{% if transaction.installment_plan %}
|
||||||
<dt class="col-sm-4">Installment</dt>
|
<dt class="tw:col-span-1">Installment</dt>
|
||||||
<dd class="col-sm-8">
|
<dd class="tw:col-span-2">
|
||||||
{{ transaction.installment_id }} of {{ transaction.installment_plan.total_installments }}
|
{{ transaction.installment_id }} of {{ transaction.installment_plan.total_installments }}
|
||||||
</dd>
|
</dd>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if transaction.recurring_transaction %}
|
{% if transaction.recurring_transaction %}
|
||||||
<dt class="col-sm-4">Recurring</dt>
|
<dt class="tw:col-span-1">Recurring</dt>
|
||||||
<dd class="col-sm-8">Yes</dd>
|
<dd class="tw:col-span-2">Yes</dd>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if transaction.notes %}
|
{% if transaction.notes %}
|
||||||
<dt class="col-sm-4">Notes</dt>
|
<dt class="tw:col-span-1">Notes</dt>
|
||||||
<dd class="col-sm-8">{{ transaction.notes }}</dd>
|
<dd class="tw:col-span-2">{{ transaction.notes }}</dd>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</dl>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,22 +1,22 @@
|
|||||||
{% load tools %}
|
{% load tools %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
<div class="col card shadow">
|
<div class="col tw:card tw:bg-base-100 tw:shadow-xl">
|
||||||
<div class="card-body">
|
<div class="tw:card-body">
|
||||||
{% if account.account.group %}
|
{% if account.account.group %}
|
||||||
<div class="tw:text-sm mb-2">
|
<div class="tw:text-sm tw:mb-2">
|
||||||
<span class="badge text-bg-primary ">{{ account.account.group }}</span>
|
<span class="tw:badge tw:badge-primary">{{ account.account.group }}</span>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<h5 class="card-title">
|
<h5 class="tw:card-title">
|
||||||
{{ account.account.name }}
|
{{ account.account.name }}
|
||||||
</h5>
|
</h5>
|
||||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
<div class="tw:flex tw:justify-between tw:items-baseline tw:mt-2">
|
||||||
<div class="text-end font-monospace">
|
<div class="tw:text-end tw:font-mono">
|
||||||
<div class="tw:text-gray-400">{% translate 'projected income' %}</div>
|
<div class="tw:text-gray-400">{% translate 'projected income' %}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="dotted-line flex-grow-1"></div>
|
<div class="dotted-line tw:flex-grow"></div>
|
||||||
{% if account.income_projected != 0 %}
|
{% if account.income_projected != 0 %}
|
||||||
<div class="text-end font-monospace tw:text-green-400">
|
<div class="tw:text-end tw:font-mono tw:text-green-400">
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="account.income_projected"
|
:amount="account.income_projected"
|
||||||
:prefix="account.currency.prefix"
|
:prefix="account.currency.prefix"
|
||||||
@@ -24,11 +24,11 @@
|
|||||||
:decimal_places="account.currency.decimal_places"></c-amount.display>
|
:decimal_places="account.currency.decimal_places"></c-amount.display>
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="text-end font-monospace">-</div>
|
<div class="tw:text-end tw:font-mono">-</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% if account.exchanged and account.exchanged.income_projected %}
|
{% if account.exchanged and account.exchanged.income_projected %}
|
||||||
<div class="text-end font-monospace tw:text-gray-500">
|
<div class="tw:text-end tw:font-mono tw:text-gray-500">
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="account.exchanged.income_projected"
|
:amount="account.exchanged.income_projected"
|
||||||
:prefix="account.exchanged.currency.prefix"
|
:prefix="account.exchanged.currency.prefix"
|
||||||
@@ -36,14 +36,14 @@
|
|||||||
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display>
|
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
<div class="tw:flex tw:justify-between tw:items-baseline tw:mt-2">
|
||||||
<div class="text-end font-monospace">
|
<div class="tw:text-end tw:font-mono">
|
||||||
<div class="tw:text-gray-400">{% translate 'projected expenses' %}</div>
|
<div class="tw:text-gray-400">{% translate 'projected expenses' %}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="dotted-line flex-grow-1"></div>
|
<div class="dotted-line tw:flex-grow"></div>
|
||||||
<div>
|
<div>
|
||||||
{% if account.expense_projected != 0 %}
|
{% if account.expense_projected != 0 %}
|
||||||
<div class="text-end font-monospace tw:text-red-400">
|
<div class="tw:text-end tw:font-mono tw:text-red-400">
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="account.expense_projected"
|
:amount="account.expense_projected"
|
||||||
:prefix="account.currency.prefix"
|
:prefix="account.currency.prefix"
|
||||||
@@ -51,12 +51,12 @@
|
|||||||
:decimal_places="account.currency.decimal_places"></c-amount.display>
|
:decimal_places="account.currency.decimal_places"></c-amount.display>
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="text-end font-monospace">-</div>
|
<div class="tw:text-end tw:font-mono">-</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% if account.exchanged and account.exchanged.expense_projected %}
|
{% if account.exchanged and account.exchanged.expense_projected %}
|
||||||
<div class="text-end font-monospace tw:text-gray-500">
|
<div class="tw:text-end tw:font-mono tw:text-gray-500">
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="account.exchanged.expense_projected"
|
:amount="account.exchanged.expense_projected"
|
||||||
:prefix="account.exchanged.currency.prefix"
|
:prefix="account.exchanged.currency.prefix"
|
||||||
@@ -64,13 +64,13 @@
|
|||||||
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display>
|
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
<div class="tw:flex tw:justify-between tw:items-baseline tw:mt-2">
|
||||||
<div class="text-end font-monospace">
|
<div class="tw:text-end tw:font-mono">
|
||||||
<div class="tw:text-gray-400">{% translate 'projected total' %}</div>
|
<div class="tw:text-gray-400">{% translate 'projected total' %}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="dotted-line flex-grow-1"></div>
|
<div class="dotted-line tw:flex-grow"></div>
|
||||||
<div
|
<div
|
||||||
class="text-end font-monospace">
|
class="tw:text-end tw:font-mono">
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="account.total_projected"
|
:amount="account.total_projected"
|
||||||
:prefix="account.currency.prefix"
|
:prefix="account.currency.prefix"
|
||||||
@@ -80,7 +80,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% if account.exchanged.total_projected and account.exchanged.total_projected %}
|
{% if account.exchanged.total_projected and account.exchanged.total_projected %}
|
||||||
<div class="text-end font-monospace tw:text-gray-500">
|
<div class="tw:text-end tw:font-mono tw:text-gray-500">
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="account.exchanged.total_projected"
|
:amount="account.exchanged.total_projected"
|
||||||
:prefix="account.exchanged.currency.prefix"
|
:prefix="account.exchanged.currency.prefix"
|
||||||
@@ -88,14 +88,14 @@
|
|||||||
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display>
|
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<hr class="my-3">
|
<hr class="tw:my-3">
|
||||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
<div class="tw:flex tw:justify-between tw:items-baseline tw:mt-2">
|
||||||
<div class="text-end font-monospace">
|
<div class="tw:text-end tw:font-mono">
|
||||||
<div class="tw:text-gray-400">{% translate 'current income' %}</div>
|
<div class="tw:text-gray-400">{% translate 'current income' %}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="dotted-line flex-grow-1"></div>
|
<div class="dotted-line tw:flex-grow"></div>
|
||||||
{% if account.income_current != 0 %}
|
{% if account.income_current != 0 %}
|
||||||
<div class="text-end font-monospace tw:text-green-400">
|
<div class="tw:text-end tw:font-mono tw:text-green-400">
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="account.income_current"
|
:amount="account.income_current"
|
||||||
:prefix="account.currency.prefix"
|
:prefix="account.currency.prefix"
|
||||||
@@ -103,11 +103,11 @@
|
|||||||
:decimal_places="account.currency.decimal_places"></c-amount.display>
|
:decimal_places="account.currency.decimal_places"></c-amount.display>
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="text-end font-monospace">-</div>
|
<div class="tw:text-end tw:font-mono">-</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% if account.exchanged and account.exchanged.income_current %}
|
{% if account.exchanged and account.exchanged.income_current %}
|
||||||
<div class="text-end font-monospace tw:text-gray-500">
|
<div class="tw:text-end tw:font-mono tw:text-gray-500">
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="account.exchanged.income_current"
|
:amount="account.exchanged.income_current"
|
||||||
:prefix="account.exchanged.currency.prefix"
|
:prefix="account.exchanged.currency.prefix"
|
||||||
@@ -115,13 +115,13 @@
|
|||||||
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display>
|
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
<div class="tw:flex tw:justify-between tw:items-baseline tw:mt-2">
|
||||||
<div class="text-end font-monospace">
|
<div class="tw:text-end tw:font-mono">
|
||||||
<div class="tw:text-gray-400">{% translate 'current expenses' %}</div>
|
<div class="tw:text-gray-400">{% translate 'current expenses' %}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="dotted-line flex-grow-1"></div>
|
<div class="dotted-line tw:flex-grow"></div>
|
||||||
{% if account.expense_current != 0 %}
|
{% if account.expense_current != 0 %}
|
||||||
<div class="text-end font-monospace tw:text-red-400">
|
<div class="tw:text-end tw:font-mono tw:text-red-400">
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="account.expense_current"
|
:amount="account.expense_current"
|
||||||
:prefix="account.currency.prefix"
|
:prefix="account.currency.prefix"
|
||||||
@@ -129,11 +129,11 @@
|
|||||||
:decimal_places="account.currency.decimal_places"></c-amount.display>
|
:decimal_places="account.currency.decimal_places"></c-amount.display>
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="text-end font-monospace">-</div>
|
<div class="tw:text-end tw:font-mono">-</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% if account.exchanged and account.exchanged.expense_current %}
|
{% if account.exchanged and account.exchanged.expense_current %}
|
||||||
<div class="text-end font-monospace tw:text-gray-500">
|
<div class="tw:text-end tw:font-mono tw:text-gray-500">
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="account.exchanged.expense_current"
|
:amount="account.exchanged.expense_current"
|
||||||
:prefix="account.exchanged.currency.prefix"
|
:prefix="account.exchanged.currency.prefix"
|
||||||
@@ -141,12 +141,12 @@
|
|||||||
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display>
|
:decimal_places="account.exchanged.currency.decimal_places"></c-amount.display>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
<div class="tw:flex tw:justify-between tw:items-baseline tw:mt-2">
|
||||||
<div class="text-end font-monospace">
|
<div class="tw:text-end tw:font-mono">
|
||||||
<div class="tw:text-gray-400">{% translate 'current total' %}</div>
|
<div class="tw:text-gray-400">{% translate 'current total' %}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="dotted-line flex-grow-1"></div>
|
<div class="dotted-line tw:flex-grow"></div>
|
||||||
<div class="text-end font-monospace">
|
<div class="tw:text-end tw:font-mono">
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="account.total_current"
|
:amount="account.total_current"
|
||||||
:prefix="account.currency.prefix"
|
:prefix="account.currency.prefix"
|
||||||
@@ -156,7 +156,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% if account.exchanged and account.exchanged.total_current %}
|
{% if account.exchanged and account.exchanged.total_current %}
|
||||||
<div class="text-end font-monospace tw:text-gray-500">
|
<div class="tw:text-end tw:font-mono tw:text-gray-500">
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="account.exchanged.total_current"
|
:amount="account.exchanged.total_current"
|
||||||
:prefix="account.exchanged.currency.prefix"
|
:prefix="account.exchanged.currency.prefix"
|
||||||
@@ -165,13 +165,13 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div>
|
<div>
|
||||||
<hr class="my-3">
|
<hr class="tw:my-3">
|
||||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
<div class="tw:flex tw:justify-between tw:items-baseline tw:mt-2">
|
||||||
<div class="text-end font-monospace">
|
<div class="tw:text-end tw:font-mono">
|
||||||
<div class="tw:text-gray-400">{% translate 'final total' %}</div>
|
<div class="tw:text-gray-400">{% translate 'final total' %}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="dotted-line flex-grow-1"></div>
|
<div class="dotted-line tw:flex-grow"></div>
|
||||||
<div class="text-end font-monospace">
|
<div class="tw:text-end tw:font-mono">
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="account.total_final"
|
:amount="account.total_final"
|
||||||
:prefix="account.currency.prefix"
|
:prefix="account.currency.prefix"
|
||||||
@@ -181,7 +181,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% if account.exchanged and account.exchanged.total_final %}
|
{% if account.exchanged and account.exchanged.total_final %}
|
||||||
<div class="text-end font-monospace tw:text-gray-500">
|
<div class="tw:text-end tw:font-mono tw:text-gray-500">
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="account.exchanged.total_final"
|
:amount="account.exchanged.total_final"
|
||||||
:prefix="account.exchanged.currency.prefix"
|
:prefix="account.exchanged.currency.prefix"
|
||||||
@@ -191,7 +191,7 @@
|
|||||||
{% endif %}
|
{% 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="tw:my-3">
|
||||||
<c-ui.percentage-distribution :percentage="p"></c-ui.percentage-distribution>
|
<c-ui.percentage-distribution :percentage="p"></c-ui.percentage-distribution>
|
||||||
</div>
|
</div>
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<div class="card tw:relative h-100 shadow">
|
<div class="tw:card tw:bg-base-100 tw:shadow-xl tw:relative tw:h-full">
|
||||||
<div class="card-body">
|
<div class="tw:card-body">
|
||||||
{{ slot }}
|
{{ slot }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
{% load tools %}
|
{% load tools %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
<div class="col card shadow">
|
<div class="col tw:card tw:bg-base-100 tw:shadow-xl">
|
||||||
<div class="card-body">
|
<div class="tw:card-body">
|
||||||
<h5 class="card-title">
|
<h5 class="tw:card-title">
|
||||||
{{ currency.currency.name }}
|
{{ currency.currency.name }}
|
||||||
</h5>
|
</h5>
|
||||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
<div class="tw:flex tw:justify-between tw:items-baseline tw:mt-2">
|
||||||
<div class="text-end font-monospace">
|
<div class="tw:text-end tw:font-mono">
|
||||||
<div class="tw:text-gray-400">{% translate 'projected income' %}</div>
|
<div class="tw:text-gray-400">{% translate 'projected income' %}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="dotted-line flex-grow-1"></div>
|
<div class="dotted-line tw:flex-grow"></div>
|
||||||
{% if currency.income_projected != 0 %}
|
{% if currency.income_projected != 0 %}
|
||||||
<div class="text-end font-monospace tw:text-green-400">
|
<div class="tw:text-end tw:font-mono tw:text-green-400">
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="currency.income_projected"
|
:amount="currency.income_projected"
|
||||||
:prefix="currency.currency.prefix"
|
:prefix="currency.currency.prefix"
|
||||||
@@ -19,11 +19,11 @@
|
|||||||
:decimal_places="currency.currency.decimal_places"></c-amount.display>
|
:decimal_places="currency.currency.decimal_places"></c-amount.display>
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="text-end font-monospace">-</div>
|
<div class="tw:text-end tw:font-mono">-</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% if currency.exchanged and currency.exchanged.income_projected %}
|
{% if currency.exchanged and currency.exchanged.income_projected %}
|
||||||
<div class="text-end font-monospace tw:text-gray-500">
|
<div class="tw:text-end tw:font-mono tw:text-gray-500">
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="currency.exchanged.income_projected"
|
:amount="currency.exchanged.income_projected"
|
||||||
:prefix="currency.exchanged.currency.prefix"
|
:prefix="currency.exchanged.currency.prefix"
|
||||||
@@ -31,14 +31,14 @@
|
|||||||
:decimal_places="currency.exchanged.currency.decimal_places"></c-amount.display>
|
:decimal_places="currency.exchanged.currency.decimal_places"></c-amount.display>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
<div class="tw:flex tw:justify-between tw:items-baseline tw:mt-2">
|
||||||
<div class="text-end font-monospace">
|
<div class="tw:text-end tw:font-mono">
|
||||||
<div class="tw:text-gray-400">{% translate 'projected expenses' %}</div>
|
<div class="tw:text-gray-400">{% translate 'projected expenses' %}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="dotted-line flex-grow-1"></div>
|
<div class="dotted-line tw:flex-grow"></div>
|
||||||
<div>
|
<div>
|
||||||
{% if currency.expense_projected != 0 %}
|
{% if currency.expense_projected != 0 %}
|
||||||
<div class="text-end font-monospace tw:text-red-400">
|
<div class="tw:text-end tw:font-mono tw:text-red-400">
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="currency.expense_projected"
|
:amount="currency.expense_projected"
|
||||||
:prefix="currency.currency.prefix"
|
:prefix="currency.currency.prefix"
|
||||||
@@ -46,12 +46,12 @@
|
|||||||
:decimal_places="currency.currency.decimal_places"></c-amount.display>
|
:decimal_places="currency.currency.decimal_places"></c-amount.display>
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="text-end font-monospace">-</div>
|
<div class="tw:text-end tw:font-mono">-</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% if currency.exchanged and currency.exchanged.expense_projected %}
|
{% if currency.exchanged and currency.exchanged.expense_projected %}
|
||||||
<div class="text-end font-monospace tw:text-gray-500">
|
<div class="tw:text-end tw:font-mono tw:text-gray-500">
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="currency.exchanged.expense_projected"
|
:amount="currency.exchanged.expense_projected"
|
||||||
:prefix="currency.exchanged.currency.prefix"
|
:prefix="currency.exchanged.currency.prefix"
|
||||||
@@ -59,12 +59,12 @@
|
|||||||
:decimal_places="currency.exchanged.currency.decimal_places"></c-amount.display>
|
:decimal_places="currency.exchanged.currency.decimal_places"></c-amount.display>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
<div class="tw:flex tw:justify-between tw:items-baseline tw:mt-2">
|
||||||
<div class="text-end font-monospace">
|
<div class="tw:text-end tw:font-mono">
|
||||||
<div class="tw:text-gray-400">{% translate 'projected total' %}</div>
|
<div class="tw:text-gray-400">{% translate 'projected total' %}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="dotted-line flex-grow-1"></div>
|
<div class="dotted-line tw:flex-grow"></div>
|
||||||
<div class="text-end font-monospace">
|
<div class="tw:text-end tw:font-mono">
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="currency.total_projected"
|
:amount="currency.total_projected"
|
||||||
:prefix="currency.currency.prefix"
|
:prefix="currency.currency.prefix"
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% if currency.exchanged.total_projected and currency.exchanged.total_projected %}
|
{% if currency.exchanged.total_projected and currency.exchanged.total_projected %}
|
||||||
<div class="text-end font-monospace tw:text-gray-500">
|
<div class="tw:text-end tw:font-mono tw:text-gray-500">
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="currency.exchanged.total_projected"
|
:amount="currency.exchanged.total_projected"
|
||||||
:prefix="currency.exchanged.currency.prefix"
|
:prefix="currency.exchanged.currency.prefix"
|
||||||
@@ -82,14 +82,14 @@
|
|||||||
:decimal_places="currency.exchanged.currency.decimal_places"></c-amount.display>
|
:decimal_places="currency.exchanged.currency.decimal_places"></c-amount.display>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<hr class="my-3">
|
<hr class="tw:my-3">
|
||||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
<div class="tw:flex tw:justify-between tw:items-baseline tw:mt-2">
|
||||||
<div class="text-end font-monospace">
|
<div class="tw:text-end tw:font-mono">
|
||||||
<div class="tw:text-gray-400">{% translate 'current income' %}</div>
|
<div class="tw:text-gray-400">{% translate 'current income' %}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="dotted-line flex-grow-1"></div>
|
<div class="dotted-line tw:flex-grow"></div>
|
||||||
{% if currency.income_current != 0 %}
|
{% if currency.income_current != 0 %}
|
||||||
<div class="text-end font-monospace tw:text-green-400">
|
<div class="tw:text-end tw:font-mono tw:text-green-400">
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="currency.income_current"
|
:amount="currency.income_current"
|
||||||
:prefix="currency.currency.prefix"
|
:prefix="currency.currency.prefix"
|
||||||
@@ -97,11 +97,11 @@
|
|||||||
:decimal_places="currency.currency.decimal_places"></c-amount.display>
|
:decimal_places="currency.currency.decimal_places"></c-amount.display>
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="text-end font-monospace">-</div>
|
<div class="tw:text-end tw:font-mono">-</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% if currency.exchanged and currency.exchanged.income_current %}
|
{% if currency.exchanged and currency.exchanged.income_current %}
|
||||||
<div class="text-end font-monospace tw:text-gray-500">
|
<div class="tw:text-end tw:font-mono tw:text-gray-500">
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="currency.exchanged.income_current"
|
:amount="currency.exchanged.income_current"
|
||||||
:prefix="currency.exchanged.currency.prefix"
|
:prefix="currency.exchanged.currency.prefix"
|
||||||
@@ -109,13 +109,13 @@
|
|||||||
:decimal_places="currency.exchanged.currency.decimal_places"></c-amount.display>
|
:decimal_places="currency.exchanged.currency.decimal_places"></c-amount.display>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
<div class="tw:flex tw:justify-between tw:items-baseline tw:mt-2">
|
||||||
<div class="text-end font-monospace">
|
<div class="tw:text-end tw:font-mono">
|
||||||
<div class="tw:text-gray-400">{% translate 'current expenses' %}</div>
|
<div class="tw:text-gray-400">{% translate 'current expenses' %}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="dotted-line flex-grow-1"></div>
|
<div class="dotted-line tw:flex-grow"></div>
|
||||||
{% if currency.expense_current != 0 %}
|
{% if currency.expense_current != 0 %}
|
||||||
<div class="text-end font-monospace tw:text-red-400">
|
<div class="tw:text-end tw:font-mono tw:text-red-400">
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="currency.expense_current"
|
:amount="currency.expense_current"
|
||||||
:prefix="currency.currency.prefix"
|
:prefix="currency.currency.prefix"
|
||||||
@@ -123,11 +123,11 @@
|
|||||||
:decimal_places="currency.currency.decimal_places"></c-amount.display>
|
:decimal_places="currency.currency.decimal_places"></c-amount.display>
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="text-end font-monospace">-</div>
|
<div class="tw:text-end tw:font-mono">-</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% if currency.exchanged and currency.exchanged.expense_current %}
|
{% if currency.exchanged and currency.exchanged.expense_current %}
|
||||||
<div class="text-end font-monospace tw:text-gray-500">
|
<div class="tw:text-end tw:font-mono tw:text-gray-500">
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="currency.exchanged.expense_current"
|
:amount="currency.exchanged.expense_current"
|
||||||
:prefix="currency.exchanged.currency.prefix"
|
:prefix="currency.exchanged.currency.prefix"
|
||||||
@@ -135,12 +135,12 @@
|
|||||||
:decimal_places="currency.exchanged.currency.decimal_places"></c-amount.display>
|
:decimal_places="currency.exchanged.currency.decimal_places"></c-amount.display>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
<div class="tw:flex tw:justify-between tw:items-baseline tw:mt-2">
|
||||||
<div class="text-end font-monospace">
|
<div class="tw:text-end tw:font-mono">
|
||||||
<div class="tw:text-gray-400">{% translate 'current total' %}</div>
|
<div class="tw:text-gray-400">{% translate 'current total' %}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="dotted-line flex-grow-1"></div>
|
<div class="dotted-line tw:flex-grow"></div>
|
||||||
<div class="text-end font-monospace">
|
<div class="tw:text-end tw:font-mono">
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="currency.total_current"
|
:amount="currency.total_current"
|
||||||
:prefix="currency.currency.prefix"
|
:prefix="currency.currency.prefix"
|
||||||
@@ -150,7 +150,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% if currency.exchanged and currency.exchanged.total_current %}
|
{% if currency.exchanged and currency.exchanged.total_current %}
|
||||||
<div class="text-end font-monospace tw:text-gray-500">
|
<div class="tw:text-end tw:font-mono tw:text-gray-500">
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="currency.exchanged.total_current"
|
:amount="currency.exchanged.total_current"
|
||||||
:prefix="currency.exchanged.currency.prefix"
|
:prefix="currency.exchanged.currency.prefix"
|
||||||
@@ -159,13 +159,13 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div>
|
<div>
|
||||||
<hr class="my-3">
|
<hr class="tw:my-3">
|
||||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
<div class="tw:flex tw:justify-between tw:items-baseline tw:mt-2">
|
||||||
<div class="text-end font-monospace">
|
<div class="tw:text-end tw:font-mono">
|
||||||
<div class="tw:text-gray-400">{% translate 'final total' %}</div>
|
<div class="tw:text-gray-400">{% translate 'final total' %}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="dotted-line flex-grow-1"></div>
|
<div class="dotted-line tw:flex-grow"></div>
|
||||||
<div class="text-end font-monospace">
|
<div class="tw:text-end tw:font-mono">
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="currency.total_final"
|
:amount="currency.total_final"
|
||||||
:prefix="currency.currency.prefix"
|
:prefix="currency.currency.prefix"
|
||||||
@@ -175,7 +175,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% if currency.exchanged and currency.exchanged.total_final %}
|
{% if currency.exchanged and currency.exchanged.total_final %}
|
||||||
<div class="text-end font-monospace tw:text-gray-500">
|
<div class="tw:text-end tw:font-mono tw:text-gray-500">
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="currency.exchanged.total_final"
|
:amount="currency.exchanged.total_final"
|
||||||
:prefix="currency.exchanged.currency.prefix"
|
:prefix="currency.exchanged.currency.prefix"
|
||||||
@@ -185,7 +185,7 @@
|
|||||||
{% endif %}
|
{% 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="tw:my-3">
|
||||||
<c-ui.percentage-distribution :percentage="p"></c-ui.percentage-distribution>
|
<c-ui.percentage-distribution :percentage="p"></c-ui.percentage-distribution>
|
||||||
</div>
|
</div>
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
<div class="tw:sticky tw:bottom-4 tw:left-0 tw:right-0 tw:z-50 tw:hidden mx-auto tw:w-fit" id="actions-bar"
|
<div class="tw:sticky tw:bottom-4 tw:left-0 tw:right-0 tw:z-50 tw:hidden tw:mx-auto tw:w-fit" id="actions-bar"
|
||||||
_="on change from #transactions-list or htmx:afterSettle from window
|
_="on change from #transactions-list or htmx:afterSettle from window
|
||||||
if #actions-bar then
|
if #actions-bar then
|
||||||
if no <input[type='checkbox']:checked/> in #transactions-list
|
if no <input[type='checkbox']:checked/> in #transactions-list
|
||||||
@@ -16,38 +16,38 @@
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end">
|
end">
|
||||||
<div class="card slide-in-bottom">
|
<div class="tw:card tw:bg-base-100 tw:shadow slide-in-bottom">
|
||||||
<div class="card-body p-2 d-flex justify-content-between align-items-center gap-3">
|
<div class="tw:card-body tw:p-2 tw:flex tw:justify-between tw:items-center tw:gap-3">
|
||||||
{% spaceless %}
|
{% spaceless %}
|
||||||
<div class="dropdown">
|
<div class="tw:dropdown">
|
||||||
<button class="btn btn-secondary btn-sm dropdown-toggle" type="button" data-bs-toggle="dropdown"
|
<button tabindex="0" role="button" class="tw:btn tw:btn-secondary tw:btn-sm" type="button">
|
||||||
aria-expanded="false">
|
|
||||||
<i class="fa-regular fa-square-check fa-fw"></i>
|
<i class="fa-regular fa-square-check fa-fw"></i>
|
||||||
|
<i class="fa-solid fa-chevron-down fa-xs"></i>
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu">
|
<ul tabindex="0" class="tw:dropdown-content tw:menu tw:bg-base-100 tw:rounded-box tw:z-[1] tw:w-52 tw:p-2 tw:shadow">
|
||||||
<li>
|
<li>
|
||||||
<div class="dropdown-item px-3 tw:cursor-pointer"
|
<a class="tw:cursor-pointer"
|
||||||
_="on click set <#transactions-list input[type='checkbox']/>'s checked to true then call me.blur() then trigger change">
|
_="on click set <#transactions-list input[type='checkbox']/>'s checked to true then call me.blur() then trigger change">
|
||||||
<i class="fa-regular fa-square-check tw:text-green-400 me-3"></i>{% translate 'Select All' %}
|
<i class="fa-regular fa-square-check tw:text-green-400 tw:me-3"></i>{% translate 'Select All' %}
|
||||||
</div>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<div class="dropdown-item px-3 tw:cursor-pointer"
|
<a class="tw:cursor-pointer"
|
||||||
_="on click set <#transactions-list input[type='checkbox']/>'s checked to false then call me.blur() then trigger change">
|
_="on click set <#transactions-list input[type='checkbox']/>'s checked to false then call me.blur() then trigger change">
|
||||||
<i class="fa-regular fa-square tw:text-red-400 me-3"></i>{% translate 'Unselect All' %}
|
<i class="fa-regular fa-square tw:text-red-400 tw:me-3"></i>{% translate 'Unselect All' %}
|
||||||
</div>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="vr tw:align-middle"></div>
|
<div class="tw:divider tw:divider-horizontal tw:m-0"></div>
|
||||||
<button class="btn btn-secondary btn-sm"
|
<button class="tw:btn tw:btn-secondary tw:btn-sm"
|
||||||
hx-get="{% url 'transactions_bulk_undelete' %}"
|
hx-get="{% url 'transactions_bulk_undelete' %}"
|
||||||
hx-include=".transaction"
|
hx-include=".transaction"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate 'Restore' %}">
|
data-bs-title="{% translate 'Restore' %}">
|
||||||
<i class="fa-solid fa-trash-arrow-up fa-fw"></i>
|
<i class="fa-solid fa-trash-arrow-up fa-fw"></i>
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-secondary btn-sm"
|
<button class="tw:btn tw:btn-secondary tw: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"
|
||||||
@@ -58,10 +58,10 @@
|
|||||||
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-danger"></i>
|
<i class="fa-solid fa-trash tw:text-error"></i>
|
||||||
</button>
|
</button>
|
||||||
<div class="vr tw:align-middle"></div>
|
<div class="tw:divider tw:divider-horizontal tw:m-0"></div>
|
||||||
<div class="btn-group"
|
<div class="tw:dropdown tw:dropdown-end"
|
||||||
_="on selected_transactions_updated from #actions-bar
|
_="on selected_transactions_updated from #actions-bar
|
||||||
set realTotal to math.bignumber(0)
|
set realTotal to math.bignumber(0)
|
||||||
set flatTotal to math.bignumber(0)
|
set flatTotal to math.bignumber(0)
|
||||||
@@ -99,29 +99,28 @@
|
|||||||
put mean.toLocaleString(undefined, {minimumFractionDigits: 0, maximumFractionDigits: 40}) into #calc-menu-mean's innerText
|
put mean.toLocaleString(undefined, {minimumFractionDigits: 0, maximumFractionDigits: 40}) into #calc-menu-mean's innerText
|
||||||
put flatAmountValues.length.toLocaleString(undefined, {minimumFractionDigits: 0, maximumFractionDigits: 40}) into #calc-menu-count's innerText
|
put flatAmountValues.length.toLocaleString(undefined, {minimumFractionDigits: 0, maximumFractionDigits: 40}) into #calc-menu-count's innerText
|
||||||
end">
|
end">
|
||||||
<button class="btn btn-secondary btn-sm" _="on click
|
<button class="tw:btn tw:btn-secondary tw:btn-sm" _="on click
|
||||||
set original_value to #real-total-front's innerText
|
set original_value to #real-total-front's innerText
|
||||||
writeText(original_value) on navigator.clipboard
|
writeText(original_value) on navigator.clipboard
|
||||||
put '{% translate "copied!" %}' into #real-total-front's innerText
|
put '{% translate "copied!" %}' into #real-total-front's innerText
|
||||||
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 tw:me-md-2 tw:text-primary"></i>
|
||||||
<span class="d-none d-md-inline-block" id="real-total-front">0</span>
|
<span class="tw:hidden tw:md:inline-block" id="real-total-front">0</span>
|
||||||
</button>
|
</button>
|
||||||
<button type="button" class="btn btn-sm btn-secondary dropdown-toggle dropdown-toggle-split"
|
<button type="button" tabindex="0" role="button" class="tw:btn tw:btn-sm tw:btn-secondary">
|
||||||
data-bs-toggle="dropdown" aria-expanded="false" data-bs-auto-close="outside">
|
<i class="fa-solid fa-chevron-down fa-xs"></i>
|
||||||
<span class="visually-hidden">{% trans "Toggle Dropdown" %}</span>
|
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<ul class="dropdown-menu">
|
<ul tabindex="0" class="tw:dropdown-content tw:menu tw:bg-base-100 tw:rounded-box tw:z-[1] tw:w-52 tw:shadow">
|
||||||
<li>
|
<li>
|
||||||
<div class="dropdown-item-text p-0">
|
<div class="tw:p-0">
|
||||||
<div>
|
<div>
|
||||||
<div class="text-body-secondary tw:text-xs tw:font-medium px-3">
|
<div class="tw:text-base-content/60 tw:text-xs tw:font-medium tw:px-3">
|
||||||
{% trans "Flat Total" %}
|
{% trans "Flat Total" %}
|
||||||
</div>
|
</div>
|
||||||
<div class="dropdown-item px-3 tw:cursor-pointer"
|
<a class="tw:px-3 tw:cursor-pointer"
|
||||||
id="calc-menu-flat-total"
|
id="calc-menu-flat-total"
|
||||||
_="on click
|
_="on click
|
||||||
set original_value to my innerText
|
set original_value to my innerText
|
||||||
@@ -131,17 +130,17 @@
|
|||||||
put original_value into me
|
put original_value into me
|
||||||
end">
|
end">
|
||||||
0
|
0
|
||||||
</div>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<div class="dropdown-item-text p-0">
|
<div class="tw:p-0">
|
||||||
<div>
|
<div>
|
||||||
<div class="text-body-secondary tw:text-xs tw:font-medium px-3">
|
<div class="tw:text-base-content/60 tw:text-xs tw:font-medium tw:px-3">
|
||||||
{% trans "Real Total" %}
|
{% trans "Real Total" %}
|
||||||
</div>
|
</div>
|
||||||
<div class="dropdown-item px-3 tw:cursor-pointer"
|
<a class="tw:px-3 tw:cursor-pointer"
|
||||||
id="calc-menu-real-total"
|
id="calc-menu-real-total"
|
||||||
_="on click
|
_="on click
|
||||||
set original_value to my innerText
|
set original_value to my innerText
|
||||||
@@ -151,17 +150,17 @@
|
|||||||
put original_value into me
|
put original_value into me
|
||||||
end">
|
end">
|
||||||
0
|
0
|
||||||
</div>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<div class="dropdown-item-text p-0">
|
<div class="tw:p-0">
|
||||||
<div>
|
<div>
|
||||||
<div class="text-body-secondary tw:text-xs tw:font-medium px-3">
|
<div class="tw:text-base-content/60 tw:text-xs tw:font-medium tw:px-3">
|
||||||
{% trans "Mean" %}
|
{% trans "Mean" %}
|
||||||
</div>
|
</div>
|
||||||
<div class="dropdown-item px-3 tw:cursor-pointer"
|
<a class="tw:px-3 tw:cursor-pointer"
|
||||||
id="calc-menu-mean"
|
id="calc-menu-mean"
|
||||||
_="on click
|
_="on click
|
||||||
set original_value to my innerText
|
set original_value to my innerText
|
||||||
@@ -171,17 +170,17 @@
|
|||||||
put original_value into me
|
put original_value into me
|
||||||
end">
|
end">
|
||||||
0
|
0
|
||||||
</div>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<div class="dropdown-item-text p-0">
|
<div class="tw:p-0">
|
||||||
<div>
|
<div>
|
||||||
<div class="text-body-secondary tw:text-xs tw:font-medium px-3">
|
<div class="tw:text-base-content/60 tw:text-xs tw:font-medium tw:px-3">
|
||||||
{% trans "Max" %}
|
{% trans "Max" %}
|
||||||
</div>
|
</div>
|
||||||
<div class="dropdown-item px-3 tw:cursor-pointer"
|
<a class="tw:px-3 tw:cursor-pointer"
|
||||||
id="calc-menu-max"
|
id="calc-menu-max"
|
||||||
_="on click
|
_="on click
|
||||||
set original_value to my innerText
|
set original_value to my innerText
|
||||||
@@ -191,17 +190,17 @@
|
|||||||
put original_value into me
|
put original_value into me
|
||||||
end">
|
end">
|
||||||
0
|
0
|
||||||
</div>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<div class="dropdown-item-text p-0">
|
<div class="tw:p-0">
|
||||||
<div>
|
<div>
|
||||||
<div class="text-body-secondary tw:text-xs tw:font-medium px-3">
|
<div class="tw:text-base-content/60 tw:text-xs tw:font-medium tw:px-3">
|
||||||
{% trans "Min" %}
|
{% trans "Min" %}
|
||||||
</div>
|
</div>
|
||||||
<div class="dropdown-item px-3 tw:cursor-pointer"
|
<a class="tw:px-3 tw:cursor-pointer"
|
||||||
id="calc-menu-min"
|
id="calc-menu-min"
|
||||||
_="on click
|
_="on click
|
||||||
set original_value to my innerText
|
set original_value to my innerText
|
||||||
@@ -211,17 +210,17 @@
|
|||||||
put original_value into me
|
put original_value into me
|
||||||
end">
|
end">
|
||||||
0
|
0
|
||||||
</div>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<div class="dropdown-item-text p-0">
|
<div class="tw:p-0">
|
||||||
<div>
|
<div>
|
||||||
<div class="text-body-secondary tw:text-xs tw:font-medium px-3">
|
<div class="tw:text-base-content/60 tw:text-xs tw:font-medium tw:px-3">
|
||||||
{% trans "Count" %}
|
{% trans "Count" %}
|
||||||
</div>
|
</div>
|
||||||
<div class="dropdown-item px-3 tw:cursor-pointer"
|
<a class="tw:px-3 tw:cursor-pointer"
|
||||||
id="calc-menu-count"
|
id="calc-menu-count"
|
||||||
_="on click
|
_="on click
|
||||||
set original_value to my innerText
|
set original_value to my innerText
|
||||||
@@ -231,7 +230,7 @@
|
|||||||
put original_value into me
|
put original_value into me
|
||||||
end">
|
end">
|
||||||
0
|
0
|
||||||
</div>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
{% spaceless %}
|
{% spaceless %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
<span class="tw:text-xs text-white-50 mx-1"
|
<div class="tw:tooltip" data-tip="{{ content }}">
|
||||||
data-bs-toggle="tooltip"
|
<span class="tw:text-xs tw:text-base-content/50 tw:mx-3">
|
||||||
data-bs-title="{{ content }}">
|
|
||||||
<i class="{% if not icon %}fa-solid fa-circle-question{% else %}{{ icon }}{% endif %} fa-fw"></i>
|
<i class="{% if not icon %}fa-solid fa-circle-question{% else %}{{ icon }}{% endif %} fa-fw"></i>
|
||||||
</span>
|
</span>
|
||||||
|
</div>
|
||||||
{% endspaceless %}
|
{% endspaceless %}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<div class="card tw:relative h-100 shadow">
|
<div class="tw:card tw:relative tw:h-full tw:shadow tw:bg-base-300">
|
||||||
<div class="tw:absolute tw:h-8 tw:w-8 tw:right-2 tw:top-2 tw:bg-{{ color }}-300 tw:text-{{ color }}-800 text-center align-items-center d-flex justify-content-center rounded-2">
|
<div class="tw:absolute tw:h-8 tw:w-8 tw:right-2 tw:top-2 tw:bg-{{ color }}-300 tw:text-{{ color }}-800 tw:text-center tw:flex tw:items-center tw:justify-center tw:rounded-lg">
|
||||||
{% if icon %}<i class="{{ icon }}"></i>{% else %}<span class="fw-bold">{{ title.0 }}</span>{% endif %}
|
{% if icon %}<i class="{{ icon }}"></i>{% else %}<span class="tw:font-bold">{{ title.0 }}</span>{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="tw:card-body">
|
||||||
<h5 class="tw:text-{{ color }}-400 fw-bold tw:mr-[50px] {{ title_css_classes }}" {{ attrs }}>{{ title }}{% if help_text %}<c-ui.help-icon :content="help_text" icon=""></c-ui.help-icon>{% endif %}</h5>
|
<h5 class="tw:text-{{ color }}-400 tw:font-bold tw:mr-[50px] {{ title_css_classes }}" {{ attrs }}>{{ title }}{% if help_text %}<c-ui.help-icon :content="help_text" icon=""></c-ui.help-icon>{% endif %}</h5>
|
||||||
{{ slot }}
|
{{ slot }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,31 +1,35 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
<div class="progress-stacked">
|
<div class="tw:flex tw:flex-col">
|
||||||
<div class="progress position-relative" role="progressbar" aria-label="{% trans 'Projected Income' %} ({{ percentage.percentages.income_projected|floatformat:2 }}%)" aria-valuenow="{{ percentage.percentages.expense_projected|floatformat:0 }}" aria-valuemin="0" aria-valuemax="100" style="width: {{ percentage.percentages.income_projected|floatformat:"2u" }}%">
|
<div class="tw:flex tw:relative" role="progressbar" aria-label="{% trans 'Projected Income' %} ({{ percentage.percentages.income_projected|floatformat:2 }}%)" aria-valuenow="{{ percentage.percentages.expense_projected|floatformat:0 }}" aria-valuemin="0" aria-valuemax="100" style="width: {{ percentage.percentages.income_projected|floatformat:"2u" }}%">
|
||||||
<div class="progress-bar progress-bar-striped tw:bg-green-300!"
|
<div class="tw:h-6 tw:bg-green-300 tw:bg-striped"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-placement="top"
|
data-bs-placement="top"
|
||||||
title="{% trans 'Projected Income' %} ({{ percentage.percentages.income_projected|floatformat:2 }}%)">
|
title="{% trans 'Projected Income' %} ({{ percentage.percentages.income_projected|floatformat:2 }}%)"
|
||||||
|
style="width: 100%">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="progress position-relative" role="progressbar" aria-label="{% trans 'Current Income' %} ({{ percentage.percentages.income_current|floatformat:2 }}%)" aria-valuenow="{{ percentage.percentages.expense_projected|floatformat:0 }}" aria-valuemin="0" aria-valuemax="100" style="width: {{ percentage.percentages.income_current|floatformat:"2u" }}%">
|
<div class="tw:flex tw:relative" role="progressbar" aria-label="{% trans 'Current Income' %} ({{ percentage.percentages.income_current|floatformat:2 }}%)" aria-valuenow="{{ percentage.percentages.expense_projected|floatformat:0 }}" aria-valuemin="0" aria-valuemax="100" style="width: {{ percentage.percentages.income_current|floatformat:"2u" }}%">
|
||||||
<div class="progress-bar tw:bg-green-400!"
|
<div class="tw:h-6 tw:bg-green-400"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-placement="top"
|
data-bs-placement="top"
|
||||||
title="{% trans 'Current Income' %} ({{ p.percentages.income_current|floatformat:2 }}%)">
|
title="{% trans 'Current Income' %} ({{ p.percentages.income_current|floatformat:2 }}%)"
|
||||||
|
style="width: 100%">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="progress position-relative" role="progressbar" aria-label="{% trans 'Projected Expenses' %} ({{ percentage.percentages.expense_projected|floatformat:2 }}%)" aria-valuenow="{{ percentage.percentages.expense_projected|floatformat:0 }}" aria-valuemin="0" aria-valuemax="100" style="width: {{ percentage.percentages.expense_projected|floatformat:"2u" }}%">
|
<div class="tw:flex tw:relative" role="progressbar" aria-label="{% trans 'Projected Expenses' %} ({{ percentage.percentages.expense_projected|floatformat:2 }}%)" aria-valuenow="{{ percentage.percentages.expense_projected|floatformat:0 }}" aria-valuemin="0" aria-valuemax="100" style="width: {{ percentage.percentages.expense_projected|floatformat:"2u" }}%">
|
||||||
<div class="progress-bar progress-bar-striped tw:bg-red-300!"
|
<div class="tw:h-6 tw:bg-red-300 tw:bg-striped"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-placement="top"
|
data-bs-placement="top"
|
||||||
title="{% trans 'Projected Expenses' %} ({{ percentage.percentages.expense_projected|floatformat:2 }}%)">
|
title="{% trans 'Projected Expenses' %} ({{ percentage.percentages.expense_projected|floatformat:2 }}%)"
|
||||||
|
style="width: 100%">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="progress position-relative" role="progressbar" aria-label="{% trans 'Current Expenses' %} ({{ percentage.percentages.expense_current|floatformat:2 }}%)" aria-valuenow="{{ percentage.percentages.expense_projected|floatformat:0 }}" aria-valuemin="0" aria-valuemax="100" style="width: {{ percentage.percentages.expense_current|floatformat:"2u" }}%">
|
<div class="tw:flex tw:relative" role="progressbar" aria-label="{% trans 'Current Expenses' %} ({{ percentage.percentages.expense_current|floatformat:2 }}%)" aria-valuenow="{{ percentage.percentages.expense_projected|floatformat:0 }}" aria-valuemin="0" aria-valuemax="100" style="width: {{ percentage.percentages.expense_current|floatformat:"2u" }}%">
|
||||||
<div class="progress-bar tw:bg-red-400!"
|
<div class="tw:h-6 tw:bg-red-400"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-placement="top"
|
data-bs-placement="top"
|
||||||
title="{% trans 'Current Expenses' %} ({{ percentage.percentages.expense_current|floatformat:2 }}%)">
|
title="{% trans 'Current Expenses' %} ({{ percentage.percentages.expense_current|floatformat:2 }}%)"
|
||||||
|
style="width: 100%">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,49 +1,49 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
<div class="d-grid gap-2 d-xl-flex justify-content-xl-end">
|
<div class="tw:grid tw:gap-2 tw:grid-cols-1 tw:xl:flex tw:xl:justify-end">
|
||||||
<div class="d-grid gap-2 d-xl-flex flex-wrap justify-content-xl-center">
|
<div class="tw:grid tw:gap-2 tw:xl:flex tw:flex-wrap tw:xl:justify-center">
|
||||||
<button class="btn btn-sm btn-outline-success"
|
<button class="tw:btn tw:btn-sm tw:btn-outline tw:btn-success"
|
||||||
hx-get="{% url 'transaction_add' %}"
|
hx-get="{% url 'transaction_add' %}"
|
||||||
hx-target="#generic-offcanvas"
|
hx-target="#generic-offcanvas"
|
||||||
hx-trigger="click, add_income from:window"
|
hx-trigger="click, add_income from:window"
|
||||||
hx-vals='{"year": {{ year }}, {% if month %}"month": {{ month }},{% endif %} "type": "IN"}'>
|
hx-vals='{"year": {{ year }}, {% if month %}"month": {{ month }},{% endif %} "type": "IN"}'>
|
||||||
<i class="fa-solid fa-arrow-right-to-bracket me-2"></i>
|
<i class="fa-solid fa-arrow-right-to-bracket tw:me-2"></i>
|
||||||
{% translate "Income" %}
|
{% translate "Income" %}
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-sm btn-outline-danger"
|
<button class="tw:btn tw:btn-sm tw:btn-outline tw:btn-error"
|
||||||
hx-get="{% url 'transaction_add' %}"
|
hx-get="{% url 'transaction_add' %}"
|
||||||
hx-target="#generic-offcanvas"
|
hx-target="#generic-offcanvas"
|
||||||
hx-trigger="click, add_expense from:window"
|
hx-trigger="click, add_expense from:window"
|
||||||
hx-vals='{"year": {{ year }}, {% if month %}"month": {{ month }},{% endif %} "type": "EX"}'>
|
hx-vals='{"year": {{ year }}, {% if month %}"month": {{ month }},{% endif %} "type": "EX"}'>
|
||||||
<i class="fa-solid fa-arrow-right-from-bracket me-2"></i>
|
<i class="fa-solid fa-arrow-right-from-bracket tw:me-2"></i>
|
||||||
{% translate "Expense" %}
|
{% translate "Expense" %}
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-sm btn-outline-warning"
|
<button class="tw:btn tw:btn-sm tw:btn-outline tw:btn-warning"
|
||||||
hx-get="{% url 'installment_plan_add' %}"
|
hx-get="{% url 'installment_plan_add' %}"
|
||||||
hx-trigger="click, installment from:window"
|
hx-trigger="click, installment from:window"
|
||||||
hx-target="#generic-offcanvas">
|
hx-target="#generic-offcanvas">
|
||||||
<i class="fa-solid fa-divide me-2"></i>
|
<i class="fa-solid fa-divide tw:me-2"></i>
|
||||||
{% translate "Installment" %}
|
{% translate "Installment" %}
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-sm btn-outline-warning"
|
<button class="tw:btn tw:btn-sm tw:btn-outline tw:btn-warning"
|
||||||
hx-get="{% url 'recurring_transaction_add' %}"
|
hx-get="{% url 'recurring_transaction_add' %}"
|
||||||
hx-trigger="click, balance from:window"
|
hx-trigger="click, balance from:window"
|
||||||
hx-target="#generic-offcanvas">
|
hx-target="#generic-offcanvas">
|
||||||
<i class="fa-solid fa-repeat me-2"></i>
|
<i class="fa-solid fa-repeat tw:me-2"></i>
|
||||||
{% translate "Recurring" %}
|
{% translate "Recurring" %}
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-sm btn-outline-info"
|
<button class="tw:btn tw:btn-sm tw:btn-outline tw:btn-info"
|
||||||
hx-get="{% url 'transactions_transfer' %}"
|
hx-get="{% url 'transactions_transfer' %}"
|
||||||
hx-target="#generic-offcanvas"
|
hx-target="#generic-offcanvas"
|
||||||
hx-trigger="click, add_transfer from:window"
|
hx-trigger="click, add_transfer from:window"
|
||||||
hx-vals='{"year": {{ year }} {% if month %}, "month": {{ month }}{% endif %}}'>
|
hx-vals='{"year": {{ year }} {% if month %}, "month": {{ month }}{% endif %}}'>
|
||||||
<i class="fa-solid fa-money-bill-transfer me-2"></i>
|
<i class="fa-solid fa-money-bill-transfer tw:me-2"></i>
|
||||||
{% translate "Transfer" %}
|
{% translate "Transfer" %}
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-sm btn-outline-info"
|
<button class="tw:btn tw:btn-sm tw:btn-outline tw:btn-info"
|
||||||
hx-get="{% url 'account_reconciliation' %}"
|
hx-get="{% url 'account_reconciliation' %}"
|
||||||
hx-trigger="click, balance from:window"
|
hx-trigger="click, balance from:window"
|
||||||
hx-target="#generic-offcanvas">
|
hx-target="#generic-offcanvas">
|
||||||
<i class="fa-solid fa-scale-balanced me-2"></i>
|
<i class="fa-solid fa-scale-balanced tw:me-2"></i>
|
||||||
{% translate "Balance" %}
|
{% translate "Balance" %}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
<div class="tw:sticky tw:bottom-4 tw:left-0 tw:right-0 tw:z-50 tw:hidden mx-auto tw:w-fit" id="actions-bar"
|
<div class="tw:sticky tw:bottom-4 tw:left-0 tw:right-0 tw:z-50 tw:hidden tw:mx-auto tw:w-fit" id="actions-bar"
|
||||||
_="on change from #transactions-list or htmx:afterSettle from window
|
_="on change from #transactions-list or htmx:afterSettle from window
|
||||||
if #actions-bar then
|
if #actions-bar then
|
||||||
if no <input[type='checkbox']:checked/> in #transactions-list
|
if no <input[type='checkbox']:checked/> in #transactions-list
|
||||||
@@ -17,34 +17,34 @@
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end">
|
end">
|
||||||
<div class="card slide-in-bottom tw:max-w-[90vw]">
|
<div class="tw:card tw:bg-base-300 tw:shadow slide-in-bottom tw:max-w-[90vw] tw:card-border">
|
||||||
<div class="card-body p-2 d-flex justify-content-between align-items-center gap-3 tw:overflow-x-auto">
|
<div class="tw:card-body tw:flex-row tw:p-2 tw:flex tw:justify-between tw:items-center tw:gap-3 tw:overflow-x-auto">
|
||||||
{% spaceless %}
|
{% spaceless %}
|
||||||
<div class="tw:font-bold tw:text-md ms-2" id="selected-count">0</div>
|
<div class="tw:font-bold tw:text-md tw:ms-2" id="selected-count">0</div>
|
||||||
<div class="vr tw:align-middle"></div>
|
<div class="tw:divider tw:divider-horizontal tw:m-0"></div>
|
||||||
<div class="dropdown">
|
<div class="tw:dropdown tw:dropdown-top tw:dropdown-end">
|
||||||
<button class="btn btn-secondary btn-sm dropdown-toggle" type="button" data-bs-toggle="dropdown"
|
<button tabindex="0" role="button" class="tw:btn tw:btn-secondary tw:btn-sm" type="button">
|
||||||
aria-expanded="false" data-bs-popper-config='{"strategy":"fixed"}'>
|
|
||||||
<i class="fa-regular fa-square-check fa-fw"></i>
|
<i class="fa-regular fa-square-check fa-fw"></i>
|
||||||
|
<i class="fa-solid fa-chevron-down fa-xs"></i>
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu">
|
<ul tabindex="0" class="tw:dropdown-content tw:menu tw:bg-base-300 tw:rounded-box tw:z-[1] tw:w-full tw:p-2 tw:shadow tw:fixed!">
|
||||||
<li>
|
<li>
|
||||||
<div class="dropdown-item px-3 tw:cursor-pointer"
|
<a class="tw:cursor-pointer"
|
||||||
_="on click set <#transactions-list .transaction:not([style*='display: none']) input[type='checkbox']/>'s checked to true then call me.blur() then trigger change">
|
_="on click set <#transactions-list .transaction:not([style*='display: none']) input[type='checkbox']/>'s checked to true then call me.blur() then trigger change">
|
||||||
<i class="fa-regular fa-square-check tw:text-green-400 me-3"></i>{% translate 'Select All' %}
|
<i class="fa-regular fa-square-check tw:text-green-400 tw:me-3"></i>{% translate 'Select All' %}
|
||||||
</div>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<div class="dropdown-item px-3 tw:cursor-pointer"
|
<a class="tw:cursor-pointer"
|
||||||
_="on click set <#transactions-list input[type='checkbox']/>'s checked to false then call me.blur() then trigger change">
|
_="on click set <#transactions-list input[type='checkbox']/>'s checked to false then call me.blur() then trigger change">
|
||||||
<i class="fa-regular fa-square tw:text-red-400 me-3"></i>{% translate 'Unselect All' %}
|
<i class="fa-regular fa-square tw:text-red-400 tw:me-3"></i>{% translate 'Unselect All' %}
|
||||||
</div>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="vr tw:align-middle"></div>
|
<div class="tw:divider tw:divider-horizontal tw:m-0"></div>
|
||||||
<div class="btn-group">
|
<div class="tw:join">
|
||||||
<button class="btn btn-secondary btn-sm"
|
<button class="tw:btn tw:btn-secondary tw:join-item tw:btn-sm"
|
||||||
hx-get="{% url 'transactions_bulk_edit' %}"
|
hx-get="{% url 'transactions_bulk_edit' %}"
|
||||||
hx-target="#generic-offcanvas"
|
hx-target="#generic-offcanvas"
|
||||||
hx-include=".transaction"
|
hx-include=".transaction"
|
||||||
@@ -52,37 +52,37 @@
|
|||||||
data-bs-title="{% translate 'Edit' %}">
|
data-bs-title="{% translate 'Edit' %}">
|
||||||
<i class="fa-solid fa-pencil"></i>
|
<i class="fa-solid fa-pencil"></i>
|
||||||
</button>
|
</button>
|
||||||
<button type="button" class="btn btn-sm btn-secondary dropdown-toggle dropdown-toggle-split"
|
<div class="tw:dropdown tw:dropdown-top tw:dropdown-end">
|
||||||
data-bs-toggle="dropdown" data-bs-popper-config='{"strategy":"fixed"}' aria-expanded="false"
|
<button type="button" tabindex="0" role="button" class="tw:join-item tw:btn tw:btn-sm tw:btn-secondary">
|
||||||
data-bs-auto-close="outside">
|
<i class="fa-solid fa-chevron-down fa-xs"></i>
|
||||||
<span class="visually-hidden">{% trans "Toggle Dropdown" %}</span>
|
</button>
|
||||||
</button>
|
|
||||||
|
|
||||||
<ul class="dropdown-menu">
|
<ul tabindex="0" class="tw:dropdown-content tw:fixed! tw:menu tw:bg-base-300 tw:rounded-box tw:z-[1] tw:w-full tw:p-2 tw:shadow">
|
||||||
<li>
|
<li>
|
||||||
<div class="dropdown-item px-3 tw:cursor-pointer"
|
<a class="tw:cursor-pointer"
|
||||||
hx-get="{% url 'transactions_bulk_unpay' %}"
|
hx-get="{% url 'transactions_bulk_unpay' %}"
|
||||||
hx-include=".transaction">
|
hx-include=".transaction">
|
||||||
<i class="fa-regular fa-circle tw:text-red-400 fa-fw me-3"></i>{% translate 'Mark as unpaid' %}
|
<i class="fa-regular fa-circle tw:text-red-400 fa-fw tw:me-3"></i>{% translate 'Mark as unpaid' %}
|
||||||
</div>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<div class="dropdown-item px-3 tw:cursor-pointer"
|
<a class="tw:cursor-pointer"
|
||||||
hx-get="{% url 'transactions_bulk_pay' %}"
|
hx-get="{% url 'transactions_bulk_pay' %}"
|
||||||
hx-include=".transaction">
|
hx-include=".transaction">
|
||||||
<i class="fa-regular fa-circle-check tw:text-green-400 fa-fw me-3"></i>{% translate 'Mark as paid' %}
|
<i class="fa-regular fa-circle-check tw:text-green-400 fa-fw tw:me-3"></i>{% translate 'Mark as paid' %}
|
||||||
</div>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-secondary btn-sm"
|
<button class="tw:btn tw:btn-secondary tw:btn-sm"
|
||||||
hx-get="{% url 'transactions_bulk_clone' %}"
|
hx-get="{% url 'transactions_bulk_clone' %}"
|
||||||
hx-include=".transaction"
|
hx-include=".transaction"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate 'Duplicate' %}">
|
data-bs-title="{% 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="tw:btn tw:btn-secondary tw: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"
|
||||||
@@ -93,10 +93,10 @@
|
|||||||
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-danger"></i>
|
<i class="fa-solid fa-trash tw:text-error"></i>
|
||||||
</button>
|
</button>
|
||||||
<div class="vr tw:align-middle"></div>
|
<div class="tw:divider tw:divider-horizontal tw:m-0"></div>
|
||||||
<div class="btn-group"
|
<div class="tw:join"
|
||||||
_="on selected_transactions_updated from #actions-bar
|
_="on selected_transactions_updated from #actions-bar
|
||||||
set realTotal to math.bignumber(0)
|
set realTotal to math.bignumber(0)
|
||||||
set flatTotal to math.bignumber(0)
|
set flatTotal to math.bignumber(0)
|
||||||
@@ -134,144 +134,145 @@
|
|||||||
put mean.toLocaleString(undefined, {minimumFractionDigits: 0, maximumFractionDigits: 40}) into #calc-menu-mean's innerText
|
put mean.toLocaleString(undefined, {minimumFractionDigits: 0, maximumFractionDigits: 40}) into #calc-menu-mean's innerText
|
||||||
put flatAmountValues.length.toLocaleString(undefined, {minimumFractionDigits: 0, maximumFractionDigits: 40}) into #calc-menu-count's innerText
|
put flatAmountValues.length.toLocaleString(undefined, {minimumFractionDigits: 0, maximumFractionDigits: 40}) into #calc-menu-count's innerText
|
||||||
end">
|
end">
|
||||||
<button class="btn btn-secondary btn-sm" _="on click
|
<button class="tw:btn tw:btn-secondary tw:btn-sm tw:join-item"
|
||||||
|
_="on click
|
||||||
set original_value to #real-total-front's innerText
|
set original_value to #real-total-front's innerText
|
||||||
writeText(original_value) on navigator.clipboard
|
writeText(original_value) on navigator.clipboard
|
||||||
put '{% translate "copied!" %}' into #real-total-front's innerText
|
put '{% translate "copied!" %}' into #real-total-front's innerText
|
||||||
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 tw:me-md-2 tw:text-primary"></i>
|
||||||
<span class="d-none d-md-inline-block" id="real-total-front">0</span>
|
<span class="tw:hidden tw:md:inline-block" id="real-total-front">0</span>
|
||||||
</button>
|
|
||||||
<button type="button" class="btn btn-sm btn-secondary dropdown-toggle dropdown-toggle-split"
|
|
||||||
data-bs-toggle="dropdown" aria-expanded="false" data-bs-auto-close="outside"
|
|
||||||
data-bs-popper-config='{"strategy":"fixed"}'>
|
|
||||||
<span class="visually-hidden">{% trans "Toggle Dropdown" %}</span>
|
|
||||||
</button>
|
</button>
|
||||||
|
<div class="tw:dropdown tw:dropdown-end tw:dropdown-top">
|
||||||
|
<button type="button" tabindex="0" role="button" class="tw:join-item tw:btn tw:btn-sm tw:btn-secondary">
|
||||||
|
<i class="fa-solid fa-chevron-down fa-xs"></i>
|
||||||
|
</button>
|
||||||
|
|
||||||
<ul class="dropdown-menu">
|
<ul tabindex="0" class="tw:dropdown-content tw:menu tw:bg-base-300 tw:rounded-box tw:z-[1] tw:w-full tw:shadow tw:fixed!">
|
||||||
<li>
|
<li class="tw:cursor-pointer"
|
||||||
<div class="dropdown-item-text p-0">
|
_="on click
|
||||||
<div>
|
set original_value to #calc-menu-flat-total's innerText
|
||||||
<div class="text-body-secondary tw:text-xs tw:font-medium px-3">
|
writeText(original_value) on navigator.clipboard
|
||||||
{% trans "Flat Total" %}
|
put '{% translate "copied!" %}' into #calc-menu-flat-total
|
||||||
</div>
|
wait 1s
|
||||||
<div class="dropdown-item px-3 tw:cursor-pointer"
|
put original_value into #calc-menu-flat-total
|
||||||
id="calc-menu-flat-total"
|
end">
|
||||||
_="on click
|
<div class="tw:p-0">
|
||||||
set original_value to my innerText
|
<div>
|
||||||
writeText(my innerText) on navigator.clipboard
|
<div class="tw:text-base-content/60 tw:text-xs tw:font-medium tw:px-3">
|
||||||
put '{% translate "copied!" %}' into me
|
{% trans "Flat Total" %}
|
||||||
wait 1s
|
</div>
|
||||||
put original_value into me
|
<div class="tw:px-3"
|
||||||
end">
|
id="calc-menu-flat-total">
|
||||||
0
|
0
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</li>
|
||||||
</li>
|
<li class="tw:cursor-pointer"
|
||||||
<li>
|
_="on click
|
||||||
<div class="dropdown-item-text p-0">
|
set original_value to #calc-menu-real-total's innerText
|
||||||
<div>
|
writeText(original_value) on navigator.clipboard
|
||||||
<div class="text-body-secondary tw:text-xs tw:font-medium px-3">
|
put '{% translate "copied!" %}' into #calc-menu-real-total
|
||||||
{% trans "Real Total" %}
|
wait 1s
|
||||||
</div>
|
put original_value into #calc-menu-real-total
|
||||||
<div class="dropdown-item px-3 tw:cursor-pointer"
|
end">
|
||||||
id="calc-menu-real-total"
|
<div class="tw:p-0">
|
||||||
_="on click
|
<div>
|
||||||
set original_value to my innerText
|
<div class="tw:text-base-content/60 tw:text-xs tw:font-medium tw:px-3">
|
||||||
writeText(my innerText) on navigator.clipboard
|
{% trans "Real Total" %}
|
||||||
put '{% translate "copied!" %}' into me
|
</div>
|
||||||
wait 1s
|
<div class="tw:px-3"
|
||||||
put original_value into me
|
id="calc-menu-real-total">
|
||||||
end">
|
0
|
||||||
0
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</li>
|
||||||
</li>
|
<li class="tw:cursor-pointer"
|
||||||
<li>
|
_="on click
|
||||||
<div class="dropdown-item-text p-0">
|
set original_value to #calc-menu-mean's innerText
|
||||||
<div>
|
writeText(original_value) on navigator.clipboard
|
||||||
<div class="text-body-secondary tw:text-xs tw:font-medium px-3">
|
put '{% translate "copied!" %}' into #calc-menu-mean
|
||||||
{% trans "Mean" %}
|
wait 1s
|
||||||
</div>
|
put original_value into #calc-menu-mean
|
||||||
<div class="dropdown-item px-3 tw:cursor-pointer"
|
end">
|
||||||
id="calc-menu-mean"
|
<div class="tw:p-0">
|
||||||
_="on click
|
<div>
|
||||||
set original_value to my innerText
|
<div class="tw:text-base-content/60 tw:text-xs tw:font-medium tw:px-3">
|
||||||
writeText(my innerText) on navigator.clipboard
|
{% trans "Mean" %}
|
||||||
put '{% translate "copied!" %}' into me
|
</div>
|
||||||
wait 1s
|
<div class="tw:px-3"
|
||||||
put original_value into me
|
id="calc-menu-mean">
|
||||||
end">
|
0
|
||||||
0
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</li>
|
||||||
</li>
|
<li class="tw:cursor-pointer"
|
||||||
<li>
|
_="on click
|
||||||
<div class="dropdown-item-text p-0">
|
set original_value to #calc-menu-max's innerText
|
||||||
<div>
|
writeText(original_value) on navigator.clipboard
|
||||||
<div class="text-body-secondary tw:text-xs tw:font-medium px-3">
|
put '{% translate "copied!" %}' into #calc-menu-max
|
||||||
{% trans "Max" %}
|
wait 1s
|
||||||
</div>
|
put original_value into #calc-menu-max
|
||||||
<div class="dropdown-item px-3 tw:cursor-pointer"
|
end">
|
||||||
id="calc-menu-max"
|
<div class="tw:p-0">
|
||||||
_="on click
|
<div>
|
||||||
set original_value to my innerText
|
<div class="tw:text-base-content/60 tw:text-xs tw:font-medium tw:px-3">
|
||||||
writeText(my innerText) on navigator.clipboard
|
{% trans "Max" %}
|
||||||
put '{% translate "copied!" %}' into me
|
</div>
|
||||||
wait 1s
|
<div class="tw:px-3"
|
||||||
put original_value into me
|
id="calc-menu-max">
|
||||||
end">
|
0
|
||||||
0
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</li>
|
||||||
</li>
|
<li class="tw:cursor-pointer"
|
||||||
<li>
|
_="on click
|
||||||
<div class="dropdown-item-text p-0">
|
set original_value to #calc-menu-min's innerText
|
||||||
<div>
|
writeText(original_value) on navigator.clipboard
|
||||||
<div class="text-body-secondary tw:text-xs tw:font-medium px-3">
|
put '{% translate "copied!" %}' into #calc-menu-min
|
||||||
{% trans "Min" %}
|
wait 1s
|
||||||
</div>
|
put original_value into #calc-menu-min
|
||||||
<div class="dropdown-item px-3 tw:cursor-pointer"
|
end">
|
||||||
id="calc-menu-min"
|
<div class="tw:p-0">
|
||||||
_="on click
|
<div>
|
||||||
set original_value to my innerText
|
<div class="tw:text-base-content/60 tw:text-xs tw:font-medium tw:px-3">
|
||||||
writeText(my innerText) on navigator.clipboard
|
{% trans "Min" %}
|
||||||
put '{% translate "copied!" %}' into me
|
</div>
|
||||||
wait 1s
|
<div class="tw:px-3"
|
||||||
put original_value into me
|
id="calc-menu-min">
|
||||||
end">
|
0
|
||||||
0
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</li>
|
||||||
</li>
|
<li class="tw:cursor-pointer"
|
||||||
<li>
|
_="on click
|
||||||
<div class="dropdown-item-text p-0">
|
set original_value to #calc-menu-count's innerText
|
||||||
<div>
|
writeText(original_value) on navigator.clipboard
|
||||||
<div class="text-body-secondary tw:text-xs tw:font-medium px-3">
|
put '{% translate "copied!" %}' into #calc-menu-count
|
||||||
{% trans "Count" %}
|
wait 1s
|
||||||
</div>
|
put original_value into #calc-menu-count
|
||||||
<div class="dropdown-item px-3 tw:cursor-pointer"
|
end">
|
||||||
id="calc-menu-count"
|
<div class="tw:p-0">
|
||||||
_="on click
|
<div>
|
||||||
set original_value to my innerText
|
<div class="tw:text-base-content/60 tw:text-xs tw:font-medium tw:px-3">
|
||||||
writeText(my innerText) on navigator.clipboard
|
{% trans "Count" %}
|
||||||
put '{% translate "copied!" %}' into me
|
</div>
|
||||||
wait 1s
|
<div class="tw:px-3"
|
||||||
put original_value into me
|
id="calc-menu-count">
|
||||||
end">
|
0
|
||||||
0
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</li>
|
||||||
</li>
|
</ul>
|
||||||
</ul>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endspaceless %}
|
{% endspaceless %}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
title="{% translate "Income" %}"></c-components.fab_menu_button>
|
title="{% translate "Income" %}"></c-components.fab_menu_button>
|
||||||
|
|
||||||
<c-components.fab_menu_button
|
<c-components.fab_menu_button
|
||||||
color="danger"
|
color="error"
|
||||||
hx_target="#generic-offcanvas"
|
hx_target="#generic-offcanvas"
|
||||||
hx_trigger="click, add_income from:window"
|
hx_trigger="click, add_income from:window"
|
||||||
hx_vals='{"year": {{ year }}, {% if month %}"month": {{ month }},{% endif %} "type": "EX"}'
|
hx_vals='{"year": {{ year }}, {% if month %}"month": {{ month }},{% endif %} "type": "EX"}'
|
||||||
|
|||||||
9
app/templates/crispy-daisyui/accordion-group.html
Normal file
9
app/templates/crispy-daisyui/accordion-group.html
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<div class="tw:collapse tw:collapse-arrow tw:bg-base-100 tw:border tw:border-base-300{% if div.css_class %} {{div.css_class}}{% endif %}">
|
||||||
|
<input type="radio" name="{{ div.data_parent }}" {% if div.active %}checked="checked"{% endif %} />
|
||||||
|
<div class="tw:collapse-title tw:font-semibold">
|
||||||
|
{{ div.name }}
|
||||||
|
</div>
|
||||||
|
<div class="tw:collapse-content">
|
||||||
|
{{ fields|safe }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
3
app/templates/crispy-daisyui/accordion.html
Normal file
3
app/templates/crispy-daisyui/accordion.html
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<div class="tw:join tw:join-vertical tw:w-full{% if accordion.css_class %} {{accordion.css_class}}{% endif %}" id="{{ accordion.css_id }}">
|
||||||
|
{{ content|safe }}
|
||||||
|
</div>
|
||||||
22
app/templates/crispy-daisyui/betterform.html
Normal file
22
app/templates/crispy-daisyui/betterform.html
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{% for fieldset in form.fieldsets %}
|
||||||
|
<fieldset class="tw:fieldset fieldset-{{ forloop.counter }} {{ fieldset.classes }}">
|
||||||
|
{% if fieldset.legend %}
|
||||||
|
<legend class="tw:fieldset-legend">{{ fieldset.legend }}</legend>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if fieldset.description %}
|
||||||
|
<p class="tw:text-sm tw:text-base-content/60">{{ fieldset.description }}</p>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% for field in fieldset %}
|
||||||
|
{% if field.is_hidden %}
|
||||||
|
{{ field }}
|
||||||
|
{% else %}
|
||||||
|
{% include "crispy-daisyui/field.html" %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% if not forloop.last or not fieldset_open %}
|
||||||
|
</fieldset>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
9
app/templates/crispy-daisyui/display_form.html
Normal file
9
app/templates/crispy-daisyui/display_form.html
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{% if form.form_html %}
|
||||||
|
{% if include_media %}{{ form.media }}{% endif %}
|
||||||
|
{% if form_show_errors %}
|
||||||
|
{% include "crispy-daisyui/errors.html" %}
|
||||||
|
{% endif %}
|
||||||
|
{{ form.form_html }}
|
||||||
|
{% else %}
|
||||||
|
{% include "crispy-daisyui/uni_form.html" %}
|
||||||
|
{% endif %}
|
||||||
8
app/templates/crispy-daisyui/errors.html
Normal file
8
app/templates/crispy-daisyui/errors.html
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{% if form.non_field_errors %}
|
||||||
|
<div class="tw:alert tw:alert-error">
|
||||||
|
{% if form_error_title %}<h4 class="tw:font-bold">{{ form_error_title }}</h4>{% endif %}
|
||||||
|
<ul class="tw:m-0 tw:list-disc tw:list-inside">
|
||||||
|
{{ form.non_field_errors|unordered_list }}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
9
app/templates/crispy-daisyui/errors_formset.html
Normal file
9
app/templates/crispy-daisyui/errors_formset.html
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{% if formset.non_form_errors %}
|
||||||
|
<div class="tw:alert tw:alert-error">
|
||||||
|
{% if formset_error_title %}<h4 class="tw:font-bold">{{ formset_error_title }}</h4>{% endif %}
|
||||||
|
<ul class="tw:m-0 tw:list-disc tw:list-inside">
|
||||||
|
{{ formset.non_form_errors|unordered_list }}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
71
app/templates/crispy-daisyui/field.html
Normal file
71
app/templates/crispy-daisyui/field.html
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
{% load crispy_forms_field %}
|
||||||
|
|
||||||
|
{% if field.is_hidden %}
|
||||||
|
{{ field }}
|
||||||
|
{% else %}
|
||||||
|
{% if field|is_checkbox and tag != "td" %}
|
||||||
|
<div class="tw:mb-3">
|
||||||
|
{% if label_class %}
|
||||||
|
<div class="{{ field_class }}">
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
<{% if tag %}{{ tag }}{% else %}div{% endif %} id="div_{{ field.auto_id }}" class="{% if field|is_checkbox and form_show_labels %}tw:form-control{% else %}tw:mb-3{% endif %}{% if wrapper_class %} {{ wrapper_class }}{% endif %}{% if field.css_classes %} {{ field.css_classes }}{% endif %}">
|
||||||
|
{% if field.label and not field|is_checkbox and form_show_labels %}
|
||||||
|
{% if field.use_fieldset %}<fieldset class="tw:fieldset"{% if field.aria_describedby %} aria-describedby="{{ field.aria_describedby }}"{% endif %}>{% endif %}
|
||||||
|
<{% if field.use_fieldset %}legend{% else %}label{% endif %}
|
||||||
|
{% if field.id_for_label %}for="{{ field.id_for_label }}"{% endif %} class="tw:label{% if label_class %} {{ label_class }}{% endif %}{% if field.field.required %} requiredField{% endif %}">
|
||||||
|
{{ field.label }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %}
|
||||||
|
</{% if field.use_fieldset %}legend{% else %}label{% endif %}>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if field|is_checkboxselectmultiple or field|is_radioselect %}
|
||||||
|
{% include 'crispy-daisyui/layout/radio_checkbox_select.html' %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if not field|is_checkboxselectmultiple and not field|is_radioselect %}
|
||||||
|
{% if field|is_checkbox and form_show_labels %}
|
||||||
|
{% if field.errors %}
|
||||||
|
{% crispy_field field 'class' 'tw:checkbox tw:checkbox-error' %}
|
||||||
|
{% else %}
|
||||||
|
{% crispy_field field 'class' 'tw:checkbox' %}
|
||||||
|
{% endif %}
|
||||||
|
<label for="{{ field.id_for_label }}" class="tw:label{% if field.field.required %} requiredField{% endif %}">
|
||||||
|
{{ field.label }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %}
|
||||||
|
</label>
|
||||||
|
{% include 'crispy-daisyui/layout/help_text_and_errors.html' %}
|
||||||
|
{% else %}
|
||||||
|
{% if field_class %}<div class="{{ field_class }}">{% endif %}
|
||||||
|
{% if field|is_file %}
|
||||||
|
{% include 'crispy-daisyui/layout/field_file.html' %}
|
||||||
|
{% elif field|is_select %}
|
||||||
|
{% if field.errors %}
|
||||||
|
{% crispy_field field 'class' 'tw:select tw:select-bordered tw:select-error tw:w-full' %}
|
||||||
|
{% else %}
|
||||||
|
{% crispy_field field 'class' 'tw:select tw:select-bordered tw:w-full' %}
|
||||||
|
{% endif %}
|
||||||
|
{% elif field|is_checkbox %}
|
||||||
|
{% if field.errors %}
|
||||||
|
{% crispy_field field 'class' 'tw:checkbox tw:checkbox-error' %}
|
||||||
|
{% else %}
|
||||||
|
{% crispy_field field 'class' 'tw:checkbox' %}
|
||||||
|
{% endif %}
|
||||||
|
{% elif field.errors %}
|
||||||
|
{% crispy_field field 'class' 'tw:input tw:input-bordered tw:input-error tw:w-full' %}
|
||||||
|
{% else %}
|
||||||
|
{% crispy_field field 'class' 'tw:input tw:input-bordered tw:w-full' %}
|
||||||
|
{% endif %}
|
||||||
|
{% if not field|is_file %}
|
||||||
|
{% include 'crispy-daisyui/layout/help_text_and_errors.html' %}
|
||||||
|
{% endif %}
|
||||||
|
{% if field_class %}</div>{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% if field.use_fieldset and field.label and form_show_labels %}</fieldset>{% endif %}
|
||||||
|
</{% if tag %}{{ tag }}{% else %}div{% endif %}>
|
||||||
|
{% if field|is_checkbox and tag != "td" %}
|
||||||
|
{% if label_class %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
13
app/templates/crispy-daisyui/inputs.html
Normal file
13
app/templates/crispy-daisyui/inputs.html
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{% if inputs %}
|
||||||
|
<div class="tw:mb-3">
|
||||||
|
{% if label_class %}
|
||||||
|
<div class="aab {{ label_class }}"></div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div class="{{ field_class }}">
|
||||||
|
{% for input in inputs %}
|
||||||
|
{% include "crispy-daisyui/layout/baseinput.html" %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
4
app/templates/crispy-daisyui/layout/alert.html
Normal file
4
app/templates/crispy-daisyui/layout/alert.html
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<div class="tw:alert {{ alert.css_class }}" role="alert"{% if alert.css_id %} id="{{ alert.css_id }}"{% endif %}>
|
||||||
|
{{ content|safe }}
|
||||||
|
{% if dismiss %}<button type="button" class="tw:btn tw:btn-sm tw:btn-circle tw:btn-ghost" data-bs-dismiss="alert" aria-label="Close">✕</button>{% endif %}
|
||||||
|
</div>
|
||||||
1
app/templates/crispy-daisyui/layout/attrs.html
Normal file
1
app/templates/crispy-daisyui/layout/attrs.html
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{% for name, value in widget.attrs.items %}{% if value is not False %} {{ name }}{% if value is not True %}="{{ value|stringformat:'s' }}"{% endif %}{% endif %}{% endfor %}
|
||||||
9
app/templates/crispy-daisyui/layout/baseinput.html
Normal file
9
app/templates/crispy-daisyui/layout/baseinput.html
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<input type="{{ input.input_type }}"
|
||||||
|
name="{% if input.name|wordcount > 1 %}{{ input.name|slugify }}{% else %}{{ input.name }}{% endif %}"
|
||||||
|
value="{{ input.value }}"
|
||||||
|
{% if input.input_type != "hidden" %}
|
||||||
|
class="tw:btn {{ input.field_classes }}"
|
||||||
|
id="{% if input.id %}{{ input.id }}{% else %}{{ input.input_type }}-id-{{ input.name|slugify }}{% endif %}"
|
||||||
|
{% endif %}
|
||||||
|
{{ input.flat_attrs }}
|
||||||
|
/>
|
||||||
1
app/templates/crispy-daisyui/layout/button.html
Normal file
1
app/templates/crispy-daisyui/layout/button.html
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<button class="tw:btn" {{ button.flat_attrs }}>{{ button.content|safe }}</button>
|
||||||
4
app/templates/crispy-daisyui/layout/buttonholder.html
Normal file
4
app/templates/crispy-daisyui/layout/buttonholder.html
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<div {% if buttonholder.css_id %}id="{{ buttonholder.css_id }}"{% endif %}
|
||||||
|
class="tw:flex tw:gap-2{% if buttonholder.css_class %} {{ buttonholder.css_class }}{% endif %}">
|
||||||
|
{{ fields_output|safe }}
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
{% if field.is_hidden %}
|
||||||
|
{{ field }}
|
||||||
|
{% else %}
|
||||||
|
<div id="div_{{ field.auto_id }}" class="tw:mb-3{% if wrapper_class %} {{ wrapper_class }}{% endif %}{% if field.css_classes %} {{ field.css_classes }}{% endif %}">
|
||||||
|
|
||||||
|
{% if field.label %}
|
||||||
|
<fieldset class="tw:fieldset"{% if field.aria_describedby %} aria-describedby="{{ field.aria_describedby }}"{% endif %}>
|
||||||
|
<legend for="{{ field.id_for_label }}" class="tw:fieldset-legend {{ label_class }}{% if field.field.required %} requiredField{% endif %}">
|
||||||
|
{{ field.label }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %}
|
||||||
|
</legend>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% include 'crispy-daisyui/layout/radio_checkbox_select.html' %}
|
||||||
|
{% if field.label %}</fieldset>{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
6
app/templates/crispy-daisyui/layout/column.html
Normal file
6
app/templates/crispy-daisyui/layout/column.html
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<div {% if div.css_id %}id="{{ div.css_id }}"{% endif %}
|
||||||
|
class="tw:col-span-12 {{ div.css_class|default:'' }}" {{ div.flat_attrs }}>
|
||||||
|
{{ fields|safe }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
4
app/templates/crispy-daisyui/layout/div.html
Normal file
4
app/templates/crispy-daisyui/layout/div.html
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<div {% if div.css_id %}id="{{ div.css_id }}"{% endif %}
|
||||||
|
{% if div.css_class %}class="{{ div.css_class }}"{% endif %} {{ div.flat_attrs }}>
|
||||||
|
{{ fields|safe }}
|
||||||
|
</div>
|
||||||
12
app/templates/crispy-daisyui/layout/field_errors.html
Normal file
12
app/templates/crispy-daisyui/layout/field_errors.html
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{% if form_show_errors and field.errors %}
|
||||||
|
{% if field.errors.field_id %}
|
||||||
|
{# Django 5.2+ #}
|
||||||
|
<div id="{{field.errors.field_id}}_error" class="tw:text-error tw:text-sm tw:mt-1">
|
||||||
|
{% else %}
|
||||||
|
<div id="{{field.auto_id}}_error" class="tw:text-error tw:text-sm tw:mt-1">
|
||||||
|
{% endif %}
|
||||||
|
{% for error in field.errors %}
|
||||||
|
<span id="error_{{ forloop.counter }}_{{ field.auto_id }}"><strong>{{ error }}</strong></span>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
12
app/templates/crispy-daisyui/layout/field_errors_block.html
Normal file
12
app/templates/crispy-daisyui/layout/field_errors_block.html
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{% if form_show_errors and field.errors %}
|
||||||
|
{% if field.errors.field_id %}
|
||||||
|
{# Django 5.2+ #}
|
||||||
|
<div id="{{field.errors.field_id}}_error" class="tw:text-error tw:text-sm tw:mt-1">
|
||||||
|
{% else %}
|
||||||
|
<div id="{{field.auto_id}}_error" class="tw:text-error tw:text-sm tw:mt-1">
|
||||||
|
{% endif %}
|
||||||
|
{% for error in field.errors %}
|
||||||
|
<p id="error_{{ forloop.counter }}_{{ field.auto_id }}"><strong>{{ error }}</strong></p>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
26
app/templates/crispy-daisyui/layout/field_file.html
Normal file
26
app/templates/crispy-daisyui/layout/field_file.html
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{% load crispy_forms_field %}
|
||||||
|
|
||||||
|
{% for widget in field.subwidgets %}
|
||||||
|
{% if widget.data.is_initial %}
|
||||||
|
<div class="tw:join tw:mb-2 tw:w-full">
|
||||||
|
<span class="tw:btn tw:btn-disabled tw:join-item">{{ widget.data.initial_text }}</span>
|
||||||
|
<div class="tw:input tw:input-bordered tw:join-item tw:flex tw:items-center tw:flex-grow">
|
||||||
|
<span class="tw:break-all tw:flex-grow">
|
||||||
|
<a href="{{ field.value.url }}" class="tw:link">{{ field.value.name }}</a>
|
||||||
|
</span>
|
||||||
|
{% if not widget.data.required %}
|
||||||
|
<span class="tw:ml-2">
|
||||||
|
<label class="tw:label tw:cursor-pointer tw:gap-2">
|
||||||
|
<input type="checkbox" name="{{ widget.data.checkbox_name }}" id="{{ widget.data.checkbox_id }}" class="tw:checkbox"{% if field.field.disabled %} disabled{% endif %} >
|
||||||
|
<span class="tw:label-text">{{ widget.data.clear_checkbox_label }}</span>
|
||||||
|
</label>
|
||||||
|
</span>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<div{% if field.errors %} class="tw:input-error"{%endif%}>
|
||||||
|
<input type="{{ widget.data.type }}" name="{{ widget.data.name }}" class="tw:file-input tw:file-input-bordered tw:w-full{% if widget.data.attrs.class %} {{ widget.data.attrs.class }}{% endif %}{% if field.errors %} tw:input-error{%endif%}"{% if field.field.disabled %} disabled{% endif %}{% for name, value in widget.data.attrs.items %}{% if value is not False and name != 'class' %} {{ name }}{% if value is not True %}="{{ value|stringformat:'s' }}"{% endif %}{% endif %}{% endfor %}>
|
||||||
|
{% include 'crispy-daisyui/layout/help_text_and_errors.html' %}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
39
app/templates/crispy-daisyui/layout/field_with_buttons.html
Normal file
39
app/templates/crispy-daisyui/layout/field_with_buttons.html
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
{% load crispy_forms_field %}
|
||||||
|
|
||||||
|
<div{% if div.css_id %} id="{{ div.css_id }}"{% endif %} class="tw:mb-3{% if wrapper_class %} {{ wrapper_class }}{% endif %}{% if field.css_classes %} {{ field.css_classes }}{% endif %}{% if div.css_class %} {{ div.css_class }}{% endif %}" {{ div.flat_attrs }}>
|
||||||
|
{% if field.label and form_show_labels %}
|
||||||
|
<label for="{{ field.id_for_label }}" class="tw:label {{ label_class }}{% if field.field.required %} requiredField{% endif %}">
|
||||||
|
<span class="tw:label-text">{{ field.label }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %}</span>
|
||||||
|
</label>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div{% if field_class %} class="{{ field_class }}"{% endif %}>
|
||||||
|
<div class="tw:join tw:w-full{% if input_size %} {{ input_size }}{% endif %}">
|
||||||
|
{% if field|is_select %}
|
||||||
|
{% if field.errors %}
|
||||||
|
{% crispy_field field 'class' 'tw:select tw:select-bordered tw:select-error tw:join-item tw:flex-grow' %}
|
||||||
|
{% else %}
|
||||||
|
{% crispy_field field 'class' 'tw:select tw:select-bordered tw:join-item tw:flex-grow' %}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{% if field.errors %}
|
||||||
|
{% crispy_field field 'class' 'tw:input tw:input-bordered tw:input-error tw:join-item tw:flex-grow' %}
|
||||||
|
{% else %}
|
||||||
|
{% crispy_field field 'class' 'tw:input tw:input-bordered tw:join-item tw:flex-grow' %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{{ buttons|safe }}
|
||||||
|
</div>
|
||||||
|
{% if field.errors.field_id %}
|
||||||
|
{# Django 5.2+ #}
|
||||||
|
<div id="{{field.errors.field_id}}_error" class="tw:text-error tw:text-sm tw:mt-1">
|
||||||
|
{% else %}
|
||||||
|
<div id="{{field.auto_id}}_error" class="tw:text-error tw:text-sm tw:mt-1">
|
||||||
|
{% endif %}
|
||||||
|
{% for error in field.errors %}
|
||||||
|
<p id="error_{{ forloop.counter }}_{{ field.auto_id }}"><small><strong>{{ error }}</strong></small></p>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% include 'crispy-daisyui/layout/help_text.html' %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
6
app/templates/crispy-daisyui/layout/fieldset.html
Normal file
6
app/templates/crispy-daisyui/layout/fieldset.html
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<fieldset {% if fieldset.css_id %}id="{{ fieldset.css_id }}"{% endif %}
|
||||||
|
class="tw:fieldset{% if fieldset.css_class %} {{ fieldset.css_class }}{% endif %}"
|
||||||
|
{{ fieldset.flat_attrs }}>
|
||||||
|
{% if legend %}<legend class="tw:fieldset-legend">{{ legend|safe }}</legend>{% endif %}
|
||||||
|
{{ fields|safe }}
|
||||||
|
</fieldset>
|
||||||
28
app/templates/crispy-daisyui/layout/floating_field.html
Normal file
28
app/templates/crispy-daisyui/layout/floating_field.html
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
{% load crispy_forms_field %}
|
||||||
|
|
||||||
|
{% if field.is_hidden %}
|
||||||
|
{{ field }}
|
||||||
|
{% else %}
|
||||||
|
<{% if tag %}{{ tag }}{% else %}div{% endif %} id="div_{{ field.auto_id }}" class="tw:mb-3{% if wrapper_class %} {{ wrapper_class }}{% endif %}{% if field.css_classes %} {{ field.css_classes }}{% endif %}">
|
||||||
|
|
||||||
|
<label class="tw:input tw:input-bordered tw:flex tw:items-center tw:gap-2" {% if field.id_for_label %}for="{{ field.id_for_label }}"{% endif %}{% if label_class %} {{ label_class }}{% endif %}>
|
||||||
|
{{ field.label }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %}
|
||||||
|
{% if field|is_select %}
|
||||||
|
{%if field.errors %}
|
||||||
|
{% crispy_field field 'class' 'tw:select tw:select-bordered tw:select-error tw:grow' 'placeholder' field.name %}
|
||||||
|
{% else %}
|
||||||
|
{% crispy_field field 'class' 'tw:select tw:select-bordered tw:grow' 'placeholder' field.name %}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{% if field.errors %}
|
||||||
|
{% crispy_field field 'class' 'tw:grow' 'placeholder' field.name %}
|
||||||
|
{% else %}
|
||||||
|
{% crispy_field field 'class' 'tw:grow' 'placeholder' field.name %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
</label>
|
||||||
|
|
||||||
|
{% include 'crispy-daisyui/layout/help_text_and_errors.html' %}
|
||||||
|
|
||||||
|
</{% if tag %}{{ tag }}{% else %}div{% endif %}>
|
||||||
|
{% endif %}
|
||||||
11
app/templates/crispy-daisyui/layout/formactions.html
Normal file
11
app/templates/crispy-daisyui/layout/formactions.html
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<div
|
||||||
|
{% if formactions.flat_attrs %}{{ formactions.flat_attrs }}{% endif %}
|
||||||
|
class="tw:mb-3 tw:flex tw:gap-2 {{ 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>
|
||||||
|
</div>
|
||||||
7
app/templates/crispy-daisyui/layout/help_text.html
Normal file
7
app/templates/crispy-daisyui/layout/help_text.html
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{% if field.help_text %}
|
||||||
|
{% if help_text_inline %}
|
||||||
|
<span id="{{ field.auto_id }}_helptext" class="tw:text-sm tw:text-base-content/60">{{ field.help_text|safe}}</span>
|
||||||
|
{% else %}
|
||||||
|
<div {% if field.auto_id %}id="{{ field.auto_id }}_helptext" {% endif %}class="tw:text-sm tw:text-base-content/60 tw:mt-1">{{ field.help_text|safe }}</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
{% if help_text_inline and not error_text_inline %}
|
||||||
|
{% include 'bootstrap5/layout/help_text.html' %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if error_text_inline %}
|
||||||
|
{% include 'bootstrap5/layout/field_errors.html' %}
|
||||||
|
{% else %}
|
||||||
|
{% include 'bootstrap5/layout/field_errors_block.html' %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if not help_text_inline %}
|
||||||
|
{% include 'bootstrap5/layout/help_text.html' %}
|
||||||
|
{% endif %}
|
||||||
26
app/templates/crispy-daisyui/layout/inline_field.html
Normal file
26
app/templates/crispy-daisyui/layout/inline_field.html
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{% load crispy_forms_field %}
|
||||||
|
|
||||||
|
{% if field.is_hidden %}
|
||||||
|
{{ field }}
|
||||||
|
{% else %}
|
||||||
|
{% if field|is_checkbox %}
|
||||||
|
<div id="div_{{ field.auto_id }}" class="tw:form-control tw:inline-flex{% if wrapper_class %} {{ wrapper_class }}{% endif %}">
|
||||||
|
<label class="tw:label tw:cursor-pointer tw:gap-2">
|
||||||
|
{% crispy_field field 'class' 'tw:checkbox' %}
|
||||||
|
<span class="tw:label-text">{{ field.label }}</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div id="div_{{ field.auto_id }}"{% if wrapper_class %} class="{{ wrapper_class }}"{% endif %}>
|
||||||
|
<label for="{{ field.id_for_label }}" class="tw:sr-only">
|
||||||
|
{{ field.label }}
|
||||||
|
</label>
|
||||||
|
{% if field.errors %}
|
||||||
|
{% crispy_field field 'class' 'tw:input tw:input-bordered tw:input-error' 'placeholder' field.label %}
|
||||||
|
{% else %}
|
||||||
|
{% crispy_field field 'class' 'tw:input tw:input-bordered' 'placeholder' field.label %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
11
app/templates/crispy-daisyui/layout/modal.html
Normal file
11
app/templates/crispy-daisyui/layout/modal.html
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<div id="{{ modal.css_id }}" class="tw:modal {{ modal.css_class }}" {{ modal.flat_attrs }}>
|
||||||
|
<div class="tw:modal-box" role="document">
|
||||||
|
<form method="dialog">
|
||||||
|
<button class="tw:btn tw:btn-sm tw:btn-circle tw:btn-ghost tw:absolute tw:right-2 tw:top-2" aria-label="Close">✕</button>
|
||||||
|
</form>
|
||||||
|
<h3 class="tw:font-bold tw:text-lg {{ modal.title_class }}" id="{{ modal.title_id }}-label">{{ modal.title }}</h3>
|
||||||
|
<div class="tw:py-4">
|
||||||
|
{{ fields }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
27
app/templates/crispy-daisyui/layout/multifield.html
Normal file
27
app/templates/crispy-daisyui/layout/multifield.html
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
{% load crispy_forms_field %}
|
||||||
|
|
||||||
|
{% if field.is_hidden %}
|
||||||
|
{{ field }}
|
||||||
|
{% else %}
|
||||||
|
|
||||||
|
{% if field.label %}
|
||||||
|
<label for="{{ field.id_for_label }}" class="tw:label{% if labelclass %} {{ labelclass }}{% endif %}">
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if field|is_checkbox %}
|
||||||
|
{% crispy_field field %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if field.label %}
|
||||||
|
<span class="tw:label-text">{{ field.label }}</span>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if not field|is_checkbox %}
|
||||||
|
{% crispy_field field %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if field.label %}
|
||||||
|
</label>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
{% load crispy_forms_field %}
|
||||||
|
|
||||||
|
{% if field.is_hidden %}
|
||||||
|
{{ field }}
|
||||||
|
{% else %}
|
||||||
|
<div id="div_{{ field.auto_id }}" class="tw:mb-3{% if wrapper_class %} {{ wrapper_class }}{% endif %}{% if form_group_wrapper_class %} {{ form_group_wrapper_class }}{% endif %}{% if form_show_errors and field.errors %} tw: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="tw:label{{ label_class }}{% if field.field.required %} requiredField{% endif %}">
|
||||||
|
<span class="tw:label-text">{{ field.label }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %}</span>
|
||||||
|
</label>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div {% if field_class %}class="{{ field_class }}"{% endif %}>
|
||||||
|
<label class="tw:input tw:input-bordered tw:flex tw:items-center tw:gap-2{% if input_size %} {{ input_size }}{% endif %}{% if field.errors %} tw:input-error{% endif %}">
|
||||||
|
{# prepend #}
|
||||||
|
{% if crispy_prepended_text %}
|
||||||
|
<span>{{ crispy_prepended_text }}</span>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{# input #}
|
||||||
|
{% if field|is_select %}
|
||||||
|
{% if field.errors %}
|
||||||
|
{% crispy_field field 'class' 'tw:select tw:select-bordered tw:select-error tw:w-full' %}
|
||||||
|
{% else %}
|
||||||
|
{% crispy_field field 'class' 'tw:select tw:select-bordered tw:w-full' %}
|
||||||
|
{% endif %}
|
||||||
|
{% elif field.errors %}
|
||||||
|
{% crispy_field field 'class' 'tw:grow' %}
|
||||||
|
{% else %}
|
||||||
|
{% crispy_field field 'class' 'tw:grow' %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{# append #}
|
||||||
|
{% if crispy_appended_text %}
|
||||||
|
<span>{{ crispy_appended_text }}</span>
|
||||||
|
{% 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>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
{% load crispy_forms_filters %}
|
||||||
|
{% load l10n %}
|
||||||
|
|
||||||
|
<div {% if field_class %}class="{{ field_class }}"{% endif %}{% if flat_attrs %} {{ flat_attrs }}{% endif %}>
|
||||||
|
|
||||||
|
{% for group, options, index in field|optgroups %}
|
||||||
|
{% if group %}<strong class="tw:font-bold tw:mb-2 tw:block">{{ group }}</strong>{% endif %}
|
||||||
|
{% for option in options %}
|
||||||
|
<div class="tw:form-control{% if inline_class %} tw:inline-flex{% endif %}">
|
||||||
|
<label class="tw:label tw:cursor-pointer{% if inline_class %} tw:inline-flex{% endif %}">
|
||||||
|
<input type="{{option.type}}" class="{% if option.type == 'radio' %}tw:radio{% else %}tw:checkbox{% endif %}{% if field.errors %} tw:{% if option.type == 'radio' %}radio{% else %}checkbox{% endif %}-error{% endif %} tw:me-2" name="{{ field.html_name }}" value="{{ option.value|unlocalize }}" {% include "crispy-daisyui/layout/attrs.html" with widget=option %}>
|
||||||
|
<span class="tw:label-text">{{ option.label|unlocalize }}</span>
|
||||||
|
</label>
|
||||||
|
{% if field.errors and forloop.last and not inline_class and forloop.parentloop.last %}
|
||||||
|
{% include 'crispy-daisyui/layout/field_errors_block.html' %}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
{% if field.errors and inline_class %}
|
||||||
|
{% if field.errors.field_id %}
|
||||||
|
{# Django 5.2+ #}
|
||||||
|
<div id="{{field.errors.field_id}}_error" class="tw:text-error tw:text-sm tw:mt-1">
|
||||||
|
{% else %}
|
||||||
|
<div id="{{field.auto_id}}_error" class="tw:text-error tw:text-sm tw:mt-1">
|
||||||
|
{% endif %}
|
||||||
|
{% for error in field.errors %}
|
||||||
|
<p id="error_{{ forloop.counter }}_{{ field.auto_id }}"><strong>{{ error }}</strong></p>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% include 'crispy-daisyui/layout/help_text.html' %}
|
||||||
16
app/templates/crispy-daisyui/layout/radioselect_inline.html
Normal file
16
app/templates/crispy-daisyui/layout/radioselect_inline.html
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{% if field.is_hidden %}
|
||||||
|
{{ field }}
|
||||||
|
{% else %}
|
||||||
|
<div id="div_{{ field.auto_id }}" class="tw:mb-3{% if wrapper_class %} {{ wrapper_class }}{% endif %}{% if field.css_classes %} {{ field.css_classes }}{% endif %}">
|
||||||
|
|
||||||
|
{% if field.label %}
|
||||||
|
<fieldset class="tw:fieldset"{% if field.aria_describedby %} aria-describedby="{{ field.aria_describedby }}"{% endif %}>
|
||||||
|
<legend for="{{ field.id_for_label }}" class="tw:fieldset-legend {{ label_class }}{% if field.field.required %} requiredField{% endif %}">
|
||||||
|
{{ field.label }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %}
|
||||||
|
</legend>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% include 'crispy-daisyui/layout/radio_checkbox_select.html' %}
|
||||||
|
{% if field.label %}</fieldset>{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
3
app/templates/crispy-daisyui/layout/row.html
Normal file
3
app/templates/crispy-daisyui/layout/row.html
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<div {% if div.css_id %}id="{{ div.css_id }}"{% endif %} class="tw:grid tw:grid-cols-12 tw:gap-4 {{ div.css_class|default:'' }}" {{ div.flat_attrs }}>
|
||||||
|
{{ fields|safe }}
|
||||||
|
</div>
|
||||||
19
app/templates/crispy-daisyui/layout/switch.html
Normal file
19
app/templates/crispy-daisyui/layout/switch.html
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
{% load crispy_forms_field %}
|
||||||
|
|
||||||
|
{% if field.is_hidden %}
|
||||||
|
{{ field }}
|
||||||
|
{% else %}
|
||||||
|
<{% if tag %}{{ tag }}{% else %}div{% endif %} id="div_{{ field.auto_id }}" class="tw:form-control tw:mb-3{% if wrapper_class %} {{ wrapper_class }}{% endif %}{% if field.css_classes %} {{ field.css_classes }}{% endif %}">
|
||||||
|
<div class="{{ field_class }}">
|
||||||
|
{% if field.errors %}
|
||||||
|
{% crispy_field field 'class' 'tw:toggle tw:toggle-error' 'role' 'switch' %}
|
||||||
|
{% else %}
|
||||||
|
{% crispy_field field 'class' 'tw:toggle' 'role' 'switch' %}
|
||||||
|
{% endif %}
|
||||||
|
<label for="{{ field.id_for_label }}" class="tw:label{% if field.field.required %} requiredField{% endif %}">
|
||||||
|
{{ field.label }}
|
||||||
|
</label>
|
||||||
|
{% include 'crispy-daisyui/layout/help_text_and_errors.html' %}
|
||||||
|
</div>
|
||||||
|
</{% if tag %}{{ tag }}{% else %}div{% endif %}>
|
||||||
|
{% endif %}
|
||||||
1
app/templates/crispy-daisyui/layout/tab-link.html
Normal file
1
app/templates/crispy-daisyui/layout/tab-link.html
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<input type="radio" name="{{ link.css_id }}_tabs" role="tab" class="tw:tab{% if 'active' in link.css_class %} tw:tab-active{% endif %}" aria-label="{{ link.name|capfirst }}{% if tab.errors %}!{% endif %}" {% if 'active' in link.css_class %}checked="checked"{% endif %} />
|
||||||
4
app/templates/crispy-daisyui/layout/tab.html
Normal file
4
app/templates/crispy-daisyui/layout/tab.html
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<div role="tablist" class="tw:tabs tw:tabs-lifted{% if tabs.css_class %} {{ tabs.css_class }}{% endif %}"{% if tabs.css_id %} id="{{ tabs.css_id }}"{% endif %}>
|
||||||
|
{{ links|safe }}
|
||||||
|
{{ content|safe }}
|
||||||
|
</div>
|
||||||
12
app/templates/crispy-daisyui/layout/uneditable_input.html
Normal file
12
app/templates/crispy-daisyui/layout/uneditable_input.html
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{% load crispy_forms_field %}
|
||||||
|
|
||||||
|
|
||||||
|
<div id="div_{{ field.auto_id }}" class="tw:mb-3{% if form_show_errors and field.errors %} tw:error{% endif %}{% if field.css_classes %} {{ field.css_classes }}{% endif %}">
|
||||||
|
<label class="tw:label {{ label_class }}{% if field.field.required %} requiredField{% endif %}">
|
||||||
|
<span class="tw:label-text">{{ field.label }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %}</span>
|
||||||
|
</label>
|
||||||
|
<div class="{{ field_class }}">
|
||||||
|
{% crispy_field field 'disabled' 'disabled' %}
|
||||||
|
{% include 'crispy-daisyui/layout/help_text.html' %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
57
app/templates/crispy-daisyui/table_inline_formset.html
Normal file
57
app/templates/crispy-daisyui/table_inline_formset.html
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
{% load crispy_forms_tags %}
|
||||||
|
{% load crispy_forms_utils %}
|
||||||
|
{% load crispy_forms_field %}
|
||||||
|
|
||||||
|
{% specialspaceless %}
|
||||||
|
{% if formset_tag %}
|
||||||
|
<form {{ flat_attrs }} method="{{ form_method }}" {% if formset.is_multipart %} enctype="multipart/form-data"{% endif %}>
|
||||||
|
{% endif %}
|
||||||
|
{% if formset_method|lower == 'post' and not disable_csrf %}
|
||||||
|
{% csrf_token %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div>
|
||||||
|
{{ formset.management_form|crispy }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table{% if form_id %} id="{{ form_id }}_table"{% endif%} class="tw:table tw:table-zebra tw:table-sm">
|
||||||
|
<thead>
|
||||||
|
{% if formset.readonly and not formset.queryset.exists %}
|
||||||
|
{% else %}
|
||||||
|
<tr>
|
||||||
|
{% for field in formset.forms.0 %}
|
||||||
|
{% if field.label and not field.is_hidden %}
|
||||||
|
<th for="{{ field.auto_id }}" class="{% if field.field.required %}requiredField{% endif %}">
|
||||||
|
{{ field.label }}{% if field.field.required and not field|is_checkbox %}<span class="asteriskField">*</span>{% endif %}
|
||||||
|
</th>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
<tr class="tw:hidden empty-form">
|
||||||
|
{% for field in formset.empty_form %}
|
||||||
|
{% include 'crispy-daisyui/field.html' with tag="td" form_show_labels=False %}
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
{% for form in formset %}
|
||||||
|
{% if form_show_errors and not form.is_extra %}
|
||||||
|
{% include "crispy-daisyui/errors.html" %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
{% for field in form %}
|
||||||
|
{% include 'crispy-daisyui/field.html' with tag="td" form_show_labels=False %}
|
||||||
|
{% endfor %}
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
{% include "crispy-daisyui/inputs.html" %}
|
||||||
|
|
||||||
|
{% if formset_tag %}</form>{% endif %}
|
||||||
|
{% endspecialspaceless %}
|
||||||
11
app/templates/crispy-daisyui/uni_form.html
Normal file
11
app/templates/crispy-daisyui/uni_form.html
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{% load crispy_forms_utils %}
|
||||||
|
|
||||||
|
{% specialspaceless %}
|
||||||
|
{% if include_media %}{{ form.media }}{% endif %}
|
||||||
|
{% if form_show_errors %}
|
||||||
|
{% include "crispy-daisyui/errors.html" %}
|
||||||
|
{% endif %}
|
||||||
|
{% for field in form %}
|
||||||
|
{% include field_template %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endspecialspaceless %}
|
||||||
8
app/templates/crispy-daisyui/uni_formset.html
Normal file
8
app/templates/crispy-daisyui/uni_formset.html
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{% with formset.management_form as form %}
|
||||||
|
{% include 'crispy-daisyui/uni_form.html' %}
|
||||||
|
{% endwith %}
|
||||||
|
{% for form in formset %}
|
||||||
|
<div class="tw:mb-4">
|
||||||
|
{% include 'crispy-daisyui/uni_form.html' %}
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
14
app/templates/crispy-daisyui/whole_uni_form.html
Normal file
14
app/templates/crispy-daisyui/whole_uni_form.html
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{% load crispy_forms_utils %}
|
||||||
|
|
||||||
|
{% specialspaceless %}
|
||||||
|
{% if form_tag %}<form {{ flat_attrs }} method="{{ form_method }}" {% if form.is_multipart %} enctype="multipart/form-data"{% endif %}>{% endif %}
|
||||||
|
{% if form_method|lower == 'post' and not disable_csrf %}
|
||||||
|
{% csrf_token %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% include "crispy-daisyui/display_form.html" %}
|
||||||
|
|
||||||
|
{% include "crispy-daisyui/inputs.html" %}
|
||||||
|
|
||||||
|
{% if form_tag %}</form>{% endif %}
|
||||||
|
{% endspecialspaceless %}
|
||||||
30
app/templates/crispy-daisyui/whole_uni_formset.html
Normal file
30
app/templates/crispy-daisyui/whole_uni_formset.html
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
{% load crispy_forms_tags %}
|
||||||
|
{% load crispy_forms_utils %}
|
||||||
|
|
||||||
|
{% specialspaceless %}
|
||||||
|
{% if formset_tag %}
|
||||||
|
<form {{ flat_attrs }} method="{{ form_method }}" {% if formset.is_multipart %} enctype="multipart/form-data"{% endif %}>
|
||||||
|
{% endif %}
|
||||||
|
{% if formset_method|lower == 'post' and not disable_csrf %}
|
||||||
|
{% csrf_token %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div>
|
||||||
|
{{ formset.management_form|crispy }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% include "crispy-daisyui/errors_formset.html" %}
|
||||||
|
|
||||||
|
{% for form in formset %}
|
||||||
|
{% include "crispy-daisyui/display_form.html" %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% if inputs %}
|
||||||
|
<div class="tw:flex tw:gap-2 tw:mt-4">
|
||||||
|
{% for input in inputs %}
|
||||||
|
{% include "crispy-daisyui/layout/baseinput.html" %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% if formset_tag %}</form>{% endif %}
|
||||||
|
{% endspecialspaceless %}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
<div class="container px-md-3 py-3 column-gap-5">
|
<div class="tw:container tw:px-md-3 tw:py-3 tw:column-gap-5">
|
||||||
<div class="tw:text-3xl fw-bold font-monospace tw:w-full mb-3">
|
<div class="tw:text-3xl tw:font-bold tw:font-mono tw:w-full tw:mb-3">
|
||||||
{% spaceless %}
|
{% spaceless %}
|
||||||
<div>{% translate 'Currencies' %}<span>
|
<div>{% translate 'Currencies' %}<span>
|
||||||
<a class="text-decoration-none tw:text-2xl p-1 category-action"
|
<a class="tw:no-underline tw:text-2xl tw:p-1 category-action"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Add" %}"
|
data-bs-title="{% translate "Add" %}"
|
||||||
@@ -14,32 +14,32 @@
|
|||||||
{% endspaceless %}
|
{% endspaceless %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card">
|
<div class="tw:card tw:bg-base-100 tw:shadow-xl">
|
||||||
<div class="card-body table-responsive">
|
<div class="tw:card-body tw:overflow-x-auto">
|
||||||
{% if currencies %}
|
{% if currencies %}
|
||||||
<c-config.search></c-config.search>
|
<c-config.search></c-config.search>
|
||||||
<table class="table table-hover">
|
<table class="tw:table tw:table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col" class="col-auto"></th>
|
<th scope="col" class="tw:w-auto"></th>
|
||||||
<th scope="col" class="col-auto">{% translate 'Code' %}</th>
|
<th scope="col" class="tw:w-auto">{% translate 'Code' %}</th>
|
||||||
<th scope="col" class="col">{% translate 'Name' %}</th>
|
<th scope="col">{% translate 'Name' %}</th>
|
||||||
<th scope="col" class="col">{% translate 'Archived' %}</th>
|
<th scope="col">{% translate 'Archived' %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for currency in currencies %}
|
{% for currency in currencies %}
|
||||||
<tr class="currency">
|
<tr class="currency">
|
||||||
<td class="col-auto">
|
<td class="tw:w-auto">
|
||||||
<div class="btn-group" role="group" aria-label="{% translate 'Actions' %}">
|
<div class="tw:join" role="group" aria-label="{% translate 'Actions' %}">
|
||||||
<a class="btn btn-secondary btn-sm"
|
<a class="tw:btn tw:btn-secondary tw:btn-sm tw:join-item"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Edit" %}"
|
data-bs-title="{% translate "Edit" %}"
|
||||||
hx-get="{% url 'currency_edit' pk=currency.id %}"
|
hx-get="{% url 'currency_edit' pk=currency.id %}"
|
||||||
hx-target="#generic-offcanvas">
|
hx-target="#generic-offcanvas">
|
||||||
<i class="fa-solid fa-pencil fa-fw"></i></a>
|
<i class="fa-solid fa-pencil fa-fw"></i></a>
|
||||||
<a class="btn btn-secondary btn-sm text-danger"
|
<a class="tw:btn tw:btn-secondary tw:btn-sm tw:join-item tw:text-error"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Delete" %}"
|
data-bs-title="{% translate "Delete" %}"
|
||||||
@@ -52,9 +52,9 @@
|
|||||||
_="install prompt_swal"><i class="fa-solid fa-trash fa-fw"></i></a>
|
_="install prompt_swal"><i class="fa-solid fa-trash fa-fw"></i></a>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="col-auto">{{ currency.code }}</td>
|
<td class="tw:w-auto">{{ currency.code }}</td>
|
||||||
<td class="col">{{ currency.name }}</td>
|
<td>{{ currency.name }}</td>
|
||||||
<td class="col">{% if currency.is_archived %}<i class="fa-solid fa-solid fa-check text-success"></i>{% endif %}</td>
|
<td>{% if currency.is_archived %}<i class="fa-solid fa-solid fa-check tw:text-success"></i>{% endif %}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
{% load currency_display %}
|
{% load currency_display %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
<div class="container-fluid px-md-3 py-3 column-gap-5">
|
<div class="tw:container-fluid tw:px-md-3 tw:py-3 tw:column-gap-5">
|
||||||
<div class="d-lg-flex justify-content-between mb-3 w-100">
|
<div class="tw:lg:flex tw:justify-between tw:mb-3 tw:w-full">
|
||||||
<div class="tw:text-3xl fw-bold font-monospace d-flex align-items-center">
|
<div class="tw:text-3xl tw:font-bold tw:font-mono tw:flex tw:items-center">
|
||||||
{{ strategy.name }}
|
{{ strategy.name }}
|
||||||
</div>
|
</div>
|
||||||
<div class="tw:text-sm text-lg-end mt-2 mt-lg-0">
|
<div class="tw:text-sm tw:lg:text-right tw:mt-2 tw:lg:mt-0">
|
||||||
<div class="mb-2">
|
<div class="tw:mb-2">
|
||||||
<span class="badge rounded-pill text-bg-secondary">{{ strategy.payment_currency.name }}</span> x <span class="badge rounded-pill text-bg-secondary">{{ strategy.target_currency.name }}</span>
|
<span class="tw:badge tw:badge-secondary tw:rounded-full">{{ strategy.payment_currency.name }}</span> x <span class="tw:badge tw:badge-secondary tw:rounded-full">{{ strategy.target_currency.name }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
{% if strategy.current_price %}
|
{% if strategy.current_price %}
|
||||||
@@ -25,13 +25,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row gy-3 gx-3">
|
<div class="tw:grid tw:lg:grid-cols-2 tw:gap-3">
|
||||||
<div class="col-xl-6 col">
|
<div>
|
||||||
<div class="card">
|
<div class="tw:card tw:bg-base-100 tw:shadow-xl">
|
||||||
<div class="card-body">
|
<div class="tw:card-body">
|
||||||
{% spaceless %}
|
{% spaceless %}
|
||||||
<div class="card-title tw:text-xl">{% trans "Entries" %}<span>
|
<div class="tw:card-title tw:text-xl">{% trans "Entries" %}<span>
|
||||||
<a class="text-decoration-none p-1 category-action"
|
<a class="tw:no-underline tw:p-1 category-action"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Add" %}"
|
data-bs-title="{% translate "Add" %}"
|
||||||
@@ -44,8 +44,8 @@
|
|||||||
{% endspaceless %}
|
{% endspaceless %}
|
||||||
|
|
||||||
{% if entries %}
|
{% if entries %}
|
||||||
<div class="table-responsive">
|
<div class="tw:overflow-x-auto">
|
||||||
<table class="table table-hover text-nowrap">
|
<table class="tw:table tw:table-hover tw:whitespace-nowrap">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th></th>
|
<th></th>
|
||||||
@@ -59,9 +59,9 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
{% for entry in entries %}
|
{% for entry in entries %}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="col-auto">
|
<td class="tw:w-auto">
|
||||||
<div class="btn-group" role="group" aria-label="{% translate 'Actions' %}">
|
<div class="tw:join" role="group" aria-label="{% translate 'Actions' %}">
|
||||||
<a class="btn btn-secondary btn-sm"
|
<a class="tw:btn tw:btn-secondary tw:btn-sm tw:join-item"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Edit" %}"
|
data-bs-title="{% translate "Edit" %}"
|
||||||
@@ -69,7 +69,7 @@
|
|||||||
hx-target="#generic-offcanvas"
|
hx-target="#generic-offcanvas"
|
||||||
hx-swap="innerHTML">
|
hx-swap="innerHTML">
|
||||||
<i class="fa-solid fa-pencil fa-fw"></i></a>
|
<i class="fa-solid fa-pencil fa-fw"></i></a>
|
||||||
<a class="btn btn-secondary btn-sm text-danger"
|
<a class="tw:btn tw:btn-secondary tw:btn-sm tw:join-item tw:text-error"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Delete" %}"
|
data-bs-title="{% translate "Delete" %}"
|
||||||
@@ -107,11 +107,11 @@
|
|||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{% if entry.profit_loss_percentage > 0 %}
|
{% if entry.profit_loss_percentage > 0 %}
|
||||||
<span class="badge text-bg-success"><i
|
<span class="tw:badge tw:badge-success"><i
|
||||||
class="fa-solid fa-up-long me-2"></i>{{ entry.profit_loss_percentage|floatformat:"2g" }}%</span>
|
class="fa-solid fa-up-long tw:me-2"></i>{{ entry.profit_loss_percentage|floatformat:"2g" }}%</span>
|
||||||
{% elif entry.profit_loss_percentage < 0 %}
|
{% elif entry.profit_loss_percentage < 0 %}
|
||||||
<span class="badge text-bg-danger"><i
|
<span class="tw:badge tw:badge-error"><i
|
||||||
class="fa-solid fa-down-long me-2"></i>{{ entry.profit_loss_percentage|floatformat:"2g" }}%</span>
|
class="fa-solid fa-down-long tw:me-2"></i>{{ entry.profit_loss_percentage|floatformat:"2g" }}%</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -127,13 +127,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-xl-6 col">
|
<div>
|
||||||
<div class="row row-cols-1 row-cols-md-2 row-cols-xl-3 gy-3 gx-3">
|
<div class="tw:grid tw:grid-cols-1 tw:md:grid-cols-2 tw:xl:grid-cols-3 tw:gap-3">
|
||||||
<div class="col">
|
<div>
|
||||||
<div class="card h-100">
|
<div class="tw:card tw:bg-base-100 tw:shadow-xl tw:h-full">
|
||||||
<div class="card-body">
|
<div class="tw:card-body">
|
||||||
<h5 class="card-title">{% trans "Total Invested" %}</h5>
|
<h5 class="tw:card-title">{% trans "Total Invested" %}</h5>
|
||||||
<div class="card-text">
|
<div class="tw:text-base-content">
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="strategy.total_invested"
|
:amount="strategy.total_invested"
|
||||||
:prefix="strategy.payment_currency.prefix"
|
:prefix="strategy.payment_currency.prefix"
|
||||||
@@ -143,11 +143,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div>
|
||||||
<div class="card h-100">
|
<div class="tw:card tw:bg-base-100 tw:shadow-xl tw:h-full">
|
||||||
<div class="card-body">
|
<div class="tw:card-body">
|
||||||
<h5 class="card-title">{% trans "Total Received" %}</h5>
|
<h5 class="tw:card-title">{% trans "Total Received" %}</h5>
|
||||||
<div class="card-text">
|
<div class="tw:text-base-content">
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="strategy.total_received"
|
:amount="strategy.total_received"
|
||||||
:prefix="strategy.target_currency.prefix"
|
:prefix="strategy.target_currency.prefix"
|
||||||
@@ -157,11 +157,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div>
|
||||||
<div class="card h-100">
|
<div class="tw:card tw:bg-base-100 tw:shadow-xl tw:h-full">
|
||||||
<div class="card-body">
|
<div class="tw:card-body">
|
||||||
<h5 class="card-title">{% trans "Current Total Value" %}</h5>
|
<h5 class="tw:card-title">{% trans "Current Total Value" %}</h5>
|
||||||
<div class="card-text">
|
<div class="tw:text-base-content">
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="strategy.current_total_value"
|
:amount="strategy.current_total_value"
|
||||||
:prefix="strategy.payment_currency.prefix"
|
:prefix="strategy.payment_currency.prefix"
|
||||||
@@ -171,11 +171,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div>
|
||||||
<div class="card h-100">
|
<div class="tw:card tw:bg-base-100 tw:shadow-xl tw:h-full">
|
||||||
<div class="card-body">
|
<div class="tw:card-body">
|
||||||
<h5 class="card-title">{% trans "Average Entry Price" %}</h5>
|
<h5 class="tw:card-title">{% trans "Average Entry Price" %}</h5>
|
||||||
<div class="card-text">
|
<div class="tw:text-base-content">
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="strategy.average_entry_price"
|
:amount="strategy.average_entry_price"
|
||||||
:prefix="strategy.payment_currency.prefix"
|
:prefix="strategy.payment_currency.prefix"
|
||||||
@@ -185,12 +185,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div>
|
||||||
<div class="card h-100">
|
<div class="tw:card tw:bg-base-100 tw:shadow-xl tw:h-full">
|
||||||
<div class="card-body">
|
<div class="tw:card-body">
|
||||||
<h5 class="card-title">{% trans "Total P/L" %}</h5>
|
<h5 class="tw:card-title">{% trans "Total P/L" %}</h5>
|
||||||
<div
|
<div
|
||||||
class="card-text {% if strategy.total_profit_loss >= 0 %}tw:text-green-400{% else %}tw:text-red-400{% endif %}">
|
class="tw:text-base-content {% if strategy.total_profit_loss >= 0 %}tw:text-green-400{% else %}tw:text-red-400{% endif %}">
|
||||||
<c-amount.display
|
<c-amount.display
|
||||||
:amount="strategy.total_profit_loss"
|
:amount="strategy.total_profit_loss"
|
||||||
:prefix="strategy.payment_currency.prefix"
|
:prefix="strategy.payment_currency.prefix"
|
||||||
@@ -201,20 +201,20 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col">
|
<div>
|
||||||
<div class="card h-100">
|
<div class="tw:card tw:bg-base-100 tw:shadow-xl tw:h-full">
|
||||||
<div class="card-body">
|
<div class="tw:card-body">
|
||||||
<h5 class="card-title">{% trans "Total % P/L" %}</h5>
|
<h5 class="tw:card-title">{% trans "Total % P/L" %}</h5>
|
||||||
<div
|
<div
|
||||||
class="card-text {% if strategy.total_profit_loss >= 0 %}tw:text-green-400{% else %}tw:text-red-400{% endif %}">
|
class="tw:text-base-content {% if strategy.total_profit_loss >= 0 %}tw:text-green-400{% else %}tw:text-red-400{% endif %}">
|
||||||
{{ strategy.total_profit_loss_percentage|floatformat:2 }}%
|
{{ strategy.total_profit_loss_percentage|floatformat:2 }}%
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mt-4">
|
<div class="tw:grid tw:mt-4">
|
||||||
<div class="col-12"
|
<div class="tw:col-span-12"
|
||||||
_="on htmx:afterSettle from #strategy-details
|
_="on htmx:afterSettle from #strategy-details
|
||||||
set perfomancectx to #performanceChart.getContext('2d')
|
set perfomancectx to #performanceChart.getContext('2d')
|
||||||
js(perfomancectx)
|
js(perfomancectx)
|
||||||
@@ -283,16 +283,16 @@
|
|||||||
})
|
})
|
||||||
end
|
end
|
||||||
">
|
">
|
||||||
<div class="card">
|
<div class="tw:card tw:bg-base-100 tw:shadow-xl">
|
||||||
<div class="card-body">
|
<div class="tw:card-body">
|
||||||
<h5 class="card-title">{% trans "Performance Over Time" %}</h5>
|
<h5 class="tw:card-title">{% trans "Performance Over Time" %}</h5>
|
||||||
<canvas id="performanceChart"></canvas>
|
<canvas id="performanceChart"></canvas>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mt-4">
|
<div class="tw:grid tw:mt-4">
|
||||||
<div class="col-12"
|
<div class="tw:col-span-12"
|
||||||
_="on htmx:afterSettle from #strategy-details
|
_="on htmx:afterSettle from #strategy-details
|
||||||
set pricectx to #priceChart.getContext('2d')
|
set pricectx to #priceChart.getContext('2d')
|
||||||
set priceData to {{ price_comparison_data|safe }}
|
set priceData to {{ price_comparison_data|safe }}
|
||||||
@@ -387,16 +387,16 @@
|
|||||||
})
|
})
|
||||||
end
|
end
|
||||||
">
|
">
|
||||||
<div class="card">
|
<div class="tw:card tw:bg-base-100 tw:shadow-xl">
|
||||||
<div class="card-body">
|
<div class="tw:card-body">
|
||||||
<h5 class="card-title">{% trans "Entry Price vs Current Price" %}</h5>
|
<h5 class="tw:card-title">{% trans "Entry Price vs Current Price" %}</h5>
|
||||||
<canvas id="priceChart"></canvas>
|
<canvas id="priceChart"></canvas>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mt-4">
|
<div class="tw:grid tw:mt-4">
|
||||||
<div class="col-12"
|
<div class="tw:col-span-12"
|
||||||
_="on htmx:afterSettle from #strategy-details
|
_="on htmx:afterSettle from #strategy-details
|
||||||
set frequencyctx to #frequencyChart.getContext('2d')
|
set frequencyctx to #frequencyChart.getContext('2d')
|
||||||
js(frequencyctx)
|
js(frequencyctx)
|
||||||
@@ -450,10 +450,10 @@
|
|||||||
})
|
})
|
||||||
end
|
end
|
||||||
">
|
">
|
||||||
<div class="card">
|
<div class="tw:card tw:bg-base-100 tw:shadow-xl">
|
||||||
<div class="card-body">
|
<div class="tw:card-body">
|
||||||
<h5 class="card-title">{% trans "Investment Frequency" %}</h5>
|
<h5 class="tw:card-title">{% trans "Investment Frequency" %}</h5>
|
||||||
<p class="card-text tw:text-gray-400">
|
<p class="tw:text-base-content/60">
|
||||||
{% trans "The straighter the blue line, the more consistent your DCA strategy is." %}
|
{% trans "The straighter the blue line, the more consistent your DCA strategy is." %}
|
||||||
</p>
|
</p>
|
||||||
<canvas id="frequencyChart"></canvas>
|
<canvas id="frequencyChart"></canvas>
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
<div class="container px-md-3 py-3 column-gap-5">
|
<div class="tw:container tw:px-md-3 tw:py-3 tw:column-gap-5">
|
||||||
<div class="tw:text-3xl fw-bold font-monospace tw:w-full mb-3">
|
<div class="tw:text-3xl tw:font-bold tw:font-mono tw:w-full tw:mb-3">
|
||||||
{% spaceless %}
|
{% spaceless %}
|
||||||
<div>{% translate 'Dollar Cost Average Strategies' %}<span>
|
<div>{% translate 'Dollar Cost Average Strategies' %}<span>
|
||||||
<a class="text-decoration-none tw:text-2xl p-1 category-action"
|
<a class="tw:no-underline tw:text-2xl tw:p-1 category-action"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Add" %}"
|
data-bs-title="{% translate "Add" %}"
|
||||||
@@ -14,23 +14,23 @@
|
|||||||
{% endspaceless %}
|
{% endspaceless %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row row-cols-1 row-cols-md-2 row-cols-lg-3 row-cols-xl-4 gy-3 gx-3">
|
<div class="tw:grid tw:grid-cols-1 tw:md:grid-cols-2 tw:lg:grid-cols-3 tw:xl:grid-cols-4 tw:gap-3">
|
||||||
{% for strategy in strategies %}
|
{% for strategy in strategies %}
|
||||||
<div class="col">
|
<div>
|
||||||
<div class="card h-100">
|
<div class="tw:card tw:bg-base-100 tw:shadow-xl tw:h-full tw:flex tw:flex-col">
|
||||||
<div class="card-header">
|
<div class="tw:card-header tw:bg-base-200 tw:p-4">
|
||||||
<span class="badge rounded-pill text-bg-secondary">{{ strategy.payment_currency.name }}</span> x <span
|
<span class="tw:badge tw:badge-secondary tw:rounded-full">{{ strategy.payment_currency.name }}</span> x <span
|
||||||
class="badge rounded-pill text-bg-secondary">{{ strategy.target_currency.name }}</span>
|
class="tw:badge tw:badge-secondary tw:rounded-full">{{ strategy.target_currency.name }}</span>
|
||||||
</div>
|
</div>
|
||||||
<a href="{% url 'dca_strategy_detail_index' strategy_id=strategy.id %}" hx-boost="true"
|
<a href="{% url 'dca_strategy_detail_index' strategy_id=strategy.id %}" hx-boost="true"
|
||||||
class="text-decoration-none card-body">
|
class="tw:no-underline tw:card-body tw:flex-1">
|
||||||
<div class="">
|
<div class="">
|
||||||
<div class="card-title tw:text-xl">{{ strategy.name }}</div>
|
<div class="tw:card-title tw:text-xl">{{ strategy.name }}</div>
|
||||||
<div class="card-text tw:text-gray-400">{{ strategy.notes }}</div>
|
<div class="tw:text-base-content/60">{{ strategy.notes }}</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<div class="card-footer text-end">
|
<div class="tw:card-footer tw:bg-base-200 tw:p-4 tw:text-right">
|
||||||
<a class="text-decoration-none tw:text-gray-400 p-1"
|
<a class="tw:no-underline tw:text-base-content/60 tw:p-1"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Edit" %}"
|
data-bs-title="{% translate "Edit" %}"
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
hx-target="#generic-offcanvas">
|
hx-target="#generic-offcanvas">
|
||||||
<i class="fa-solid fa-pencil fa-fw"></i>
|
<i class="fa-solid fa-pencil fa-fw"></i>
|
||||||
</a>
|
</a>
|
||||||
<a class="text-danger text-decoration-none p-1"
|
<a class="tw:text-error tw:no-underline tw:p-1"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Delete" %}"
|
data-bs-title="{% translate "Delete" %}"
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
<i class="fa-solid fa-trash fa-fw"></i>
|
<i class="fa-solid fa-trash fa-fw"></i>
|
||||||
</a>
|
</a>
|
||||||
{% if not strategy.owner %}
|
{% if not strategy.owner %}
|
||||||
<a class="text-primary text-decoration-none p-1"
|
<a class="tw:text-primary tw:no-underline tw:p-1"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Take ownership" %}"
|
data-bs-title="{% translate "Take ownership" %}"
|
||||||
@@ -60,7 +60,7 @@
|
|||||||
<i class="fa-solid fa-crown fa-fw"></i></a>
|
<i class="fa-solid fa-crown fa-fw"></i></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if user == strategy.owner %}
|
{% if user == strategy.owner %}
|
||||||
<a class="text-primary text-decoration-none p-1"
|
<a class="tw:text-primary tw:no-underline tw:p-1"
|
||||||
role="button"
|
role="button"
|
||||||
hx-target="#generic-offcanvas"
|
hx-target="#generic-offcanvas"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
<div class="container px-md-3 py-3 column-gap-5">
|
<div class="tw:container tw:px-md-3 tw:py-3 tw:column-gap-5">
|
||||||
<div class="tw:text-3xl fw-bold font-monospace tw:w-full mb-3">
|
<div class="tw:text-3xl tw:font-bold tw:font-mono tw:w-full tw:mb-3">
|
||||||
{% spaceless %}
|
{% spaceless %}
|
||||||
<div>{% translate 'Entities' %}<span>
|
<div>{% translate 'Entities' %}<span>
|
||||||
<a class="text-decoration-none tw:text-2xl p-1 category-action"
|
<a class="tw:no-underline tw:text-2xl tw:p-1 category-action"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Add" %}"
|
data-bs-title="{% translate "Add" %}"
|
||||||
@@ -14,18 +14,14 @@
|
|||||||
{% endspaceless %}
|
{% endspaceless %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card">
|
<div class="tw:card tw:bg-base-100 tw:shadow-xl">
|
||||||
<div class="card-header">
|
<div class="tw:card-header tw:bg-base-200 tw:p-4">
|
||||||
<ul class="nav nav-pills card-header-pills" id="myTab" role="tablist">
|
<div role="tablist" class="tw:tabs tw:tabs-lifted">
|
||||||
<li class="nav-item" role="presentation">
|
<button class="tw:tab tw:tab-active" data-bs-toggle="tab" type="button" role="tab" aria-selected="true" hx-get="{% url 'entities_table_active' %}" hx-trigger="load, click" hx-target="#entities-table">{% translate 'Active' %}</button>
|
||||||
<button class="nav-link active" data-bs-toggle="tab" type="button" role="tab" aria-selected="true" hx-get="{% url 'entities_table_active' %}" hx-trigger="load, click" hx-target="#entities-table">{% translate 'Active' %}</button>
|
<button class="tw:tab" hx-get="{% url 'entities_table_archived' %}" hx-target="#entities-table" data-bs-toggle="tab" type="button" role="tab" aria-selected="false">{% translate 'Archived' %}</button>
|
||||||
</li>
|
</div>
|
||||||
<li class="nav-item" role="presentation">
|
|
||||||
<button class="nav-link" hx-get="{% url 'entities_table_archived' %}" hx-target="#entities-table" data-bs-toggle="tab" type="button" role="tab" aria-selected="false">{% translate 'Archived' %}</button>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="tw:card-body">
|
||||||
<div id="entities-table"></div>
|
<div id="entities-table"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -7,21 +7,21 @@
|
|||||||
hx-swap="outerHTML">
|
hx-swap="outerHTML">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if entities %}
|
{% if entities %}
|
||||||
<div class="table-responsive">
|
<div class="tw:overflow-x-auto">
|
||||||
<c-config.search></c-config.search>
|
<c-config.search></c-config.search>
|
||||||
<table class="table table-hover">
|
<table class="tw:table tw:table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col" class="col-auto"></th>
|
<th scope="col" class="tw:w-auto"></th>
|
||||||
<th scope="col" class="col">{% translate 'Name' %}</th>
|
<th scope="col">{% translate 'Name' %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for entity in entities %}
|
{% for entity in entities %}
|
||||||
<tr class="entity">
|
<tr class="entity">
|
||||||
<td class="col-auto">
|
<td class="tw:w-auto">
|
||||||
<div class="btn-group" role="group" aria-label="{% translate 'Actions' %}">
|
<div class="tw:join" role="group" aria-label="{% translate 'Actions' %}">
|
||||||
<a class="btn btn-secondary btn-sm"
|
<a class="tw:btn tw:btn-secondary tw:btn-sm tw:join-item"
|
||||||
role="button"
|
role="button"
|
||||||
hx-swap="innerHTML"
|
hx-swap="innerHTML"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
hx-get="{% url 'entity_edit' entity_id=entity.id %}"
|
hx-get="{% url 'entity_edit' entity_id=entity.id %}"
|
||||||
hx-target="#generic-offcanvas">
|
hx-target="#generic-offcanvas">
|
||||||
<i class="fa-solid fa-pencil fa-fw"></i></a>
|
<i class="fa-solid fa-pencil fa-fw"></i></a>
|
||||||
<a class="btn btn-secondary btn-sm text-danger"
|
<a class="tw:btn tw:btn-secondary tw:btn-sm tw:join-item tw:text-error"
|
||||||
role="button"
|
role="button"
|
||||||
hx-swap="innerHTML"
|
hx-swap="innerHTML"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
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"></i></a>
|
_="install prompt_swal"><i class="fa-solid fa-trash fa-fw"></i></a>
|
||||||
{% if not entity.owner %}
|
{% if not entity.owner %}
|
||||||
<a class="btn btn-secondary btn-sm text-warning"
|
<a class="tw:btn tw:btn-secondary tw:btn-sm tw:join-item tw:text-warning"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Take ownership" %}"
|
data-bs-title="{% translate "Take ownership" %}"
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
<i class="fa-solid fa-crown fa-fw"></i></a>
|
<i class="fa-solid fa-crown fa-fw"></i></a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if user == entity.owner %}
|
{% if user == entity.owner %}
|
||||||
<a class="btn btn-secondary btn-sm text-primary"
|
<a class="tw:btn tw:btn-secondary tw:btn-sm tw:join-item tw:text-primary"
|
||||||
role="button"
|
role="button"
|
||||||
hx-target="#generic-offcanvas"
|
hx-target="#generic-offcanvas"
|
||||||
hx-swap="innerHTML"
|
hx-swap="innerHTML"
|
||||||
@@ -61,7 +61,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="col">{{ entity.name }}</td>
|
<td>{{ entity.name }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
{% load currency_display %}
|
{% load currency_display %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
<div class="container px-md-3 py-3 column-gap-5">
|
<div class="tw:container tw:px-md-3 tw:py-3 tw:column-gap-5">
|
||||||
<div class="tw:text-3xl fw-bold font-monospace tw:w-full mb-3">
|
<div class="tw:text-3xl tw:font-bold tw:font-mono tw:w-full tw:mb-3">
|
||||||
{% spaceless %}
|
{% spaceless %}
|
||||||
<div>{% translate 'Exchange Rates' %}<span>
|
<div>{% translate 'Exchange Rates' %}<span>
|
||||||
<a class="text-decoration-none tw:text-2xl p-1 category-action"
|
<a class="tw:no-underline tw:text-2xl tw:p-1 category-action"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Add" %}"
|
data-bs-title="{% translate "Add" %}"
|
||||||
@@ -15,28 +15,24 @@
|
|||||||
{% endspaceless %}
|
{% endspaceless %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card">
|
<div class="tw:card tw:bg-base-100 tw:shadow-xl">
|
||||||
<div class="card-header">
|
<div class="tw:card-header tw:bg-base-200 tw:p-4">
|
||||||
<ul class="nav nav-pills card-header-pills" id="myTab" role="tablist">
|
<div role="tablist" class="tw:tabs tw:tabs-lifted">
|
||||||
<li class="nav-item" role="presentation">
|
<button class="tw:tab tw:tab-active" hx-indicator="#exchange-rates-table" data-bs-toggle="tab" type="button"
|
||||||
<button class="nav-link active" hx-indicator="#exchange-rates-table" data-bs-toggle="tab" type="button"
|
role="tab" aria-controls="home-tab-pane" aria-selected="true"
|
||||||
role="tab" aria-controls="home-tab-pane" aria-selected="true"
|
hx-get="{% url 'exchange_rates_list_pair' %}" hx-trigger="load, click"
|
||||||
hx-get="{% url 'exchange_rates_list_pair' %}" hx-trigger="load, click"
|
hx-target="#exchange-rates-table" aria-controls="#exchange-rates-table">{% translate 'All' %}</button>
|
||||||
hx-target="#exchange-rates-table" aria-controls="#exchange-rates-table">{% translate 'All' %}</button>
|
|
||||||
</li>
|
|
||||||
{% for pair in pairings %}
|
{% for pair in pairings %}
|
||||||
<li class="nav-item" role="presentation">
|
<button class="tw:tab" hx-indicator="#exchange-rates-table"
|
||||||
<button class="nav-link" hx-indicator="#exchange-rates-table"
|
hx-get="{% url 'exchange_rates_list_pair' %}"
|
||||||
hx-get="{% url 'exchange_rates_list_pair' %}"
|
hx-vals='{"from": "{{ pair.1 }}", "to": "{{ pair.2 }}"}'
|
||||||
hx-vals='{"from": "{{ pair.1 }}", "to": "{{ pair.2 }}"}'
|
hx-target="#exchange-rates-table" data-bs-toggle="tab" type="button" role="tab"
|
||||||
hx-target="#exchange-rates-table" data-bs-toggle="tab" type="button" role="tab"
|
aria-controls="#exchange-rates-table" aria-selected="false">{{ pair.0 }}</button>
|
||||||
aria-controls="#exchange-rates-table" aria-selected="false">{{ pair.0 }}</button>
|
|
||||||
</li>
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card">
|
<div class="tw:card">
|
||||||
<div id="exchange-rates-table" class="show-loading"></div>
|
<div id="exchange-rates-table" class="show-loading"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -1,23 +1,23 @@
|
|||||||
{% load currency_display %}
|
{% load currency_display %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
<div class="card-body show-loading" hx-get="{% url 'exchange_rates_list_pair' %}" hx-trigger="updated from:window" hx-swap="outerHTML" hx-vals='{"page": "{{ page_obj.number }}", "from": "{{ from_currency|default_if_none:"" }}", "to": "{{ to_currency|default_if_none:"" }}"}'>
|
<div class="tw:card-body show-loading" hx-get="{% url 'exchange_rates_list_pair' %}" hx-trigger="updated from:window" hx-swap="outerHTML" hx-vals='{"page": "{{ page_obj.number }}", "from": "{{ from_currency|default_if_none:"" }}", "to": "{{ to_currency|default_if_none:"" }}"}'>
|
||||||
{% if page_obj %}
|
{% if page_obj %}
|
||||||
<div class="table-responsive">
|
<div class="tw:overflow-x-auto">
|
||||||
<table class="table table-hover text-nowrap">
|
<table class="tw:table tw:table-hover tw:whitespace-nowrap">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col" class="col-auto"></th>
|
<th scope="col" class="tw:w-auto"></th>
|
||||||
<th scope="col" class="col">{% translate 'Date' %}</th>
|
<th scope="col">{% translate 'Date' %}</th>
|
||||||
<th scope="col" class="col">{% translate 'Pairing' %}</th>
|
<th scope="col">{% translate 'Pairing' %}</th>
|
||||||
<th scope="col" class="col">{% translate 'Rate' %}</th>
|
<th scope="col">{% translate 'Rate' %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for exchange_rate in page_obj %}
|
{% for exchange_rate in page_obj %}
|
||||||
<tr class="exchange-rate">
|
<tr class="exchange-rate">
|
||||||
<td class="col-auto">
|
<td class="tw:w-auto">
|
||||||
<div class="btn-group" role="group" aria-label="{% translate 'Actions' %}">
|
<div class="tw:join" role="group" aria-label="{% translate 'Actions' %}">
|
||||||
<a class="btn btn-secondary btn-sm"
|
<a class="tw:btn tw:btn-secondary tw:btn-sm tw:join-item"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Edit" %}"
|
data-bs-title="{% translate "Edit" %}"
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
hx-target="#generic-offcanvas"
|
hx-target="#generic-offcanvas"
|
||||||
hx-swap="innerHTML">
|
hx-swap="innerHTML">
|
||||||
<i class="fa-solid fa-pencil fa-fw"></i></a>
|
<i class="fa-solid fa-pencil fa-fw"></i></a>
|
||||||
<a class="btn btn-secondary btn-sm text-danger"
|
<a class="tw:btn tw:btn-secondary tw:btn-sm tw:join-item tw:text-error"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Delete" %}"
|
data-bs-title="{% translate "Delete" %}"
|
||||||
@@ -39,9 +39,9 @@
|
|||||||
_="install prompt_swal"><i class="fa-solid fa-trash fa-fw"></i></a>
|
_="install prompt_swal"><i class="fa-solid fa-trash fa-fw"></i></a>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="col-3">{{ exchange_rate.date|date:"SHORT_DATETIME_FORMAT" }}</td>
|
<td class="tw:w-1/4">{{ exchange_rate.date|date:"SHORT_DATETIME_FORMAT" }}</td>
|
||||||
<td class="col-3"><span class="badge rounded-pill text-bg-secondary">{{ exchange_rate.from_currency.name }}</span> x <span class="badge rounded-pill text-bg-secondary">{{ exchange_rate.to_currency.name }}</span></td>
|
<td class="tw:w-1/4"><span class="tw:badge tw:badge-secondary tw:rounded-full">{{ exchange_rate.from_currency.name }}</span> x <span class="tw:badge tw:badge-secondary tw:rounded-full">{{ exchange_rate.to_currency.name }}</span></td>
|
||||||
<td class="col-3">1 {{ exchange_rate.from_currency.name }} ≅ {% currency_display amount=exchange_rate.rate prefix=exchange_rate.to_currency.prefix suffix=exchange_rate.to_currency.suffix decimal_places=exchange_rate.to_currency.decimal_places%}</td>
|
<td class="tw:w-1/4">1 {{ exchange_rate.from_currency.name }} ≅ {% currency_display amount=exchange_rate.rate prefix=exchange_rate.to_currency.prefix suffix=exchange_rate.to_currency.suffix decimal_places=exchange_rate.to_currency.decimal_places%}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
@@ -52,13 +52,12 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if page_obj.has_other_pages %}
|
{% if page_obj.has_other_pages %}
|
||||||
<div class="mt-auto">
|
<div class="tw:mt-auto">
|
||||||
<input value="{{ page_obj.number }}" name="page" type="hidden" id="page">
|
<input value="{{ page_obj.number }}" name="page" type="hidden" id="page">
|
||||||
|
|
||||||
<nav aria-label="{% translate 'Page navigation' %}">
|
<nav aria-label="{% translate 'Page navigation' %}">
|
||||||
<ul class="pagination justify-content-center mt-5">
|
<div class="tw:join tw:flex tw:justify-center tw:mt-5">
|
||||||
<li class="page-item">
|
<button class="tw:join-item tw:btn tw:btn-sm {% if not page_obj.has_previous %}tw:btn-disabled{% endif %}"
|
||||||
<a class="page-link tw:cursor-pointer {% if not page_obj.has_previous %}disabled{% endif %}"
|
|
||||||
hx-get="{% if page_obj.has_previous %}{% url 'exchange_rates_list_pair' %}{% endif %}"
|
hx-get="{% if page_obj.has_previous %}{% url 'exchange_rates_list_pair' %}{% endif %}"
|
||||||
hx-vals='{"page": 1, "from": "{{ from_currency|default_if_none:"" }}", "to": "{{ to_currency|default_if_none:"" }}"}'
|
hx-vals='{"page": 1, "from": "{{ from_currency|default_if_none:"" }}", "to": "{{ to_currency|default_if_none:"" }}"}'
|
||||||
hx-include="#filter, #order"
|
hx-include="#filter, #order"
|
||||||
@@ -66,8 +65,7 @@
|
|||||||
aria-label="Primeira página"
|
aria-label="Primeira página"
|
||||||
hx-swap="show:top">
|
hx-swap="show:top">
|
||||||
<span aria-hidden="true">«</span>
|
<span aria-hidden="true">«</span>
|
||||||
</a>
|
</button>
|
||||||
</li>
|
|
||||||
{% for page_number in page_obj.paginator.page_range %}
|
{% for page_number in page_obj.paginator.page_range %}
|
||||||
{% comment %}
|
{% comment %}
|
||||||
This conditional allows us to display up to 3 pages before and after the current page
|
This conditional allows us to display up to 3 pages before and after the current page
|
||||||
@@ -78,44 +76,35 @@
|
|||||||
{% endcomment %}
|
{% endcomment %}
|
||||||
{% if page_number <= page_obj.number|add:3 and page_number >= page_obj.number|add:-3 %}
|
{% if page_number <= page_obj.number|add:3 and page_number >= page_obj.number|add:-3 %}
|
||||||
{% if page_obj.number == page_number %}
|
{% if page_obj.number == page_number %}
|
||||||
<li class="page-item active">
|
<button class="tw:join-item tw:btn tw:btn-sm tw:btn-active">
|
||||||
<a class="page-link tw:cursor-pointer">
|
{{ page_number }}
|
||||||
{{ page_number }}
|
</button>
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{% else %}
|
{% else %}
|
||||||
<li class="page-item">
|
<button class="tw:join-item tw:btn tw:btn-sm"
|
||||||
<a class="page-link tw:cursor-pointer"
|
|
||||||
hx-get="{% url 'exchange_rates_list_pair' %}"
|
hx-get="{% url 'exchange_rates_list_pair' %}"
|
||||||
hx-vals='{"page": {{ page_number }}, "from": "{{ from_currency|default_if_none:"" }}", "to": "{{ to_currency|default_if_none:"" }}"}'
|
hx-vals='{"page": {{ page_number }}, "from": "{{ from_currency|default_if_none:"" }}", "to": "{{ to_currency|default_if_none:"" }}"}'
|
||||||
hx-target="#exchange-rates-table"
|
hx-target="#exchange-rates-table"
|
||||||
hx-swap="show:top">
|
hx-swap="show:top">
|
||||||
{{ page_number }}
|
{{ page_number }}
|
||||||
</a>
|
</button>
|
||||||
</li>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% if page_obj.number|add:3 < page_obj.paginator.num_pages %}
|
{% if page_obj.number|add:3 < page_obj.paginator.num_pages %}
|
||||||
<li class="page-item">
|
<button class="tw:join-item tw:btn tw:btn-sm tw:btn-disabled"
|
||||||
<a class="page-link disabled"
|
|
||||||
aria-label="...">
|
aria-label="...">
|
||||||
<span aria-hidden="true">...</span>
|
<span aria-hidden="true">...</span>
|
||||||
</a>
|
</button>
|
||||||
</li>
|
<button class="tw:join-item tw:btn tw:btn-sm"
|
||||||
<li class="page-item">
|
|
||||||
<a class="page-link tw:cursor-pointer"
|
|
||||||
hx-get="{% url 'exchange_rates_list_pair' %}" hx-target="#exchange-rates-table"
|
hx-get="{% url 'exchange_rates_list_pair' %}" hx-target="#exchange-rates-table"
|
||||||
hx-vals='{"page": {{ page_obj.paginator.num_pages }}, "from": "{{ from_currency|default_if_none:"" }}", "to": "{{ to_currency|default_if_none:"" }}"}'
|
hx-vals='{"page": {{ page_obj.paginator.num_pages }}, "from": "{{ from_currency|default_if_none:"" }}", "to": "{{ to_currency|default_if_none:"" }}"}'
|
||||||
hx-include="#filter, #order"
|
hx-include="#filter, #order"
|
||||||
hx-swap="show:top"
|
hx-swap="show:top"
|
||||||
aria-label="Última página">
|
aria-label="Última página">
|
||||||
<span aria-hidden="true">{{ page_obj.paginator.num_pages }}</span>
|
<span aria-hidden="true">{{ page_obj.paginator.num_pages }}</span>
|
||||||
</a>
|
</button>
|
||||||
</li>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<li class="page-item">
|
<button class="tw:join-item tw:btn tw:btn-sm {% if not page_obj.has_next %}tw:btn-disabled{% endif %}"
|
||||||
<a class="page-link {% if not page_obj.has_next %}disabled{% endif %} tw:cursor-pointer"
|
|
||||||
hx-get="{% if page_obj.has_next %}{% url 'exchange_rates_list_pair' %}{% endif %}"
|
hx-get="{% if page_obj.has_next %}{% url 'exchange_rates_list_pair' %}{% endif %}"
|
||||||
hx-vals='{"page": {{ page_obj.paginator.num_pages }}, "from": "{{ from_currency|default_if_none:"" }}", "to": "{{ to_currency|default_if_none:"" }}"}'
|
hx-vals='{"page": {{ page_obj.paginator.num_pages }}, "from": "{{ from_currency|default_if_none:"" }}", "to": "{{ to_currency|default_if_none:"" }}"}'
|
||||||
hx-include="#filter, #order"
|
hx-include="#filter, #order"
|
||||||
@@ -123,9 +112,8 @@
|
|||||||
hx-target="#exchange-rates-table"
|
hx-target="#exchange-rates-table"
|
||||||
aria-label="Next">
|
aria-label="Next">
|
||||||
<span aria-hidden="true">»</span>
|
<span aria-hidden="true">»</span>
|
||||||
</a>
|
</button>
|
||||||
</li>
|
</div>
|
||||||
</ul>
|
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
{% load currency_display %}
|
{% load currency_display %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
<div class="container px-md-3 py-3 column-gap-5">
|
<div class="tw:container tw:px-md-3 tw:py-3 tw:column-gap-5">
|
||||||
<div class="tw:text-3xl fw-bold font-monospace tw:w-full mb-3">
|
<div class="tw:text-3xl tw:font-bold tw:font-mono tw:w-full tw:mb-3">
|
||||||
{% spaceless %}
|
{% spaceless %}
|
||||||
<div>{% translate 'Automatic Exchange Rates' %}<span>
|
<div>{% translate 'Automatic Exchange Rates' %}<span>
|
||||||
<a class="text-decoration-none tw:text-2xl p-1 category-action"
|
<a class="tw:no-underline tw:text-2xl tw:p-1 category-action"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Add" %}"
|
data-bs-title="{% translate "Add" %}"
|
||||||
@@ -15,39 +15,39 @@
|
|||||||
{% endspaceless %}
|
{% endspaceless %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card">
|
<div class="tw:card tw:bg-base-100 tw:shadow-xl">
|
||||||
<div class="card-header text-body-secondary">
|
<div class="tw:card-header tw:bg-base-200 tw:p-4 tw:text-base-content/70">
|
||||||
<button type="button" hx-get="{% url 'automatic_exchange_rate_force_fetch' %}"
|
<button type="button" hx-get="{% url 'automatic_exchange_rate_force_fetch' %}"
|
||||||
class="btn btn-outline-primary btn-sm">{% trans 'Fetch all' %}</button>
|
class="tw:btn tw:btn-outline tw:btn-primary tw:btn-sm">{% trans 'Fetch all' %}</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="tw:card-body">
|
||||||
{% if services %}
|
{% if services %}
|
||||||
<c-config.search></c-config.search>
|
<c-config.search></c-config.search>
|
||||||
<div class="table-responsive">
|
<div class="tw:overflow-x-auto">
|
||||||
<table class="table table-hover">
|
<table class="tw:table tw:table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col" class="col-auto"></th>
|
<th scope="col" class="tw:w-auto"></th>
|
||||||
<th scope="col" class="col-auto"></th>
|
<th scope="col" class="tw:w-auto"></th>
|
||||||
<th scope="col" class="col-auto">{% translate 'Name' %}</th>
|
<th scope="col" class="tw:w-auto">{% translate 'Name' %}</th>
|
||||||
<th scope="col" class="col">{% translate 'Service' %}</th>
|
<th scope="col">{% translate 'Service' %}</th>
|
||||||
<th scope="col" class="col">{% translate 'Targeting' %}</th>
|
<th scope="col">{% translate 'Targeting' %}</th>
|
||||||
<th scope="col" class="col">{% translate 'Last fetch' %}</th>
|
<th scope="col">{% translate 'Last fetch' %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for service in services %}
|
{% for service in services %}
|
||||||
<tr class="services">
|
<tr class="services">
|
||||||
<td class="col-auto">
|
<td class="tw:w-auto">
|
||||||
<div class="btn-group" role="group" aria-label="{% translate 'Actions' %}">
|
<div class="tw:join" role="group" aria-label="{% translate 'Actions' %}">
|
||||||
<a class="btn btn-secondary btn-sm"
|
<a class="tw:btn tw:btn-secondary tw:btn-sm tw:join-item"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Edit" %}"
|
data-bs-title="{% translate "Edit" %}"
|
||||||
hx-get="{% url 'automatic_exchange_rate_edit' pk=service.id %}"
|
hx-get="{% url 'automatic_exchange_rate_edit' pk=service.id %}"
|
||||||
hx-target="#generic-offcanvas">
|
hx-target="#generic-offcanvas">
|
||||||
<i class="fa-solid fa-pencil fa-fw"></i></a>
|
<i class="fa-solid fa-pencil fa-fw"></i></a>
|
||||||
<a class="btn btn-secondary btn-sm text-danger"
|
<a class="tw:btn tw:btn-secondary tw:btn-sm tw:join-item tw:text-error"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Delete" %}"
|
data-bs-title="{% translate "Delete" %}"
|
||||||
@@ -60,12 +60,12 @@
|
|||||||
_="install prompt_swal"><i class="fa-solid fa-trash fa-fw"></i></a>
|
_="install prompt_swal"><i class="fa-solid fa-trash fa-fw"></i></a>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="col-auto">{% if service.is_active %}<i class="fa-solid fa-circle text-success"></i>{% else %}
|
<td class="tw:w-auto">{% if service.is_active %}<i class="fa-solid fa-circle tw:text-success"></i>{% else %}
|
||||||
<i class="fa-solid fa-circle text-danger"></i>{% endif %}</td>
|
<i class="fa-solid fa-circle tw:text-error"></i>{% endif %}</td>
|
||||||
<td class="col-auto">{{ service.name }}</td>
|
<td class="tw:w-auto">{{ service.name }}</td>
|
||||||
<td class="col">{{ service.get_service_type_display }}</td>
|
<td>{{ service.get_service_type_display }}</td>
|
||||||
<td class="col">{{ service.target_currencies.count }} {% trans 'currencies' %}, {{ service.target_accounts.count }} {% trans 'accounts' %}</td>
|
<td>{{ service.target_currencies.count }} {% trans 'currencies' %}, {{ service.target_accounts.count }} {% trans 'accounts' %}</td>
|
||||||
<td class="col">{{ service.last_fetch|date:"SHORT_DATETIME_FORMAT" }}</td>
|
<td>{{ service.last_fetch|date:"SHORT_DATETIME_FORMAT" }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -1,23 +1,23 @@
|
|||||||
{% load currency_display %}
|
{% load currency_display %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
<div class="card-body show-loading" hx-get="{% url 'exchange_rates_list_pair' %}" hx-trigger="updated from:window" hx-swap="outerHTML" hx-vals='{"page": "{{ page_obj.number }}", "from": "{{ from_currency|default_if_none:"" }}", "to": "{{ to_currency|default_if_none:"" }}"}'>
|
<div class="tw:card-body show-loading" hx-get="{% url 'exchange_rates_list_pair' %}" hx-trigger="updated from:window" hx-swap="outerHTML" hx-vals='{"page": "{{ page_obj.number }}", "from": "{{ from_currency|default_if_none:"" }}", "to": "{{ to_currency|default_if_none:"" }}"}'>
|
||||||
{% if page_obj %}
|
{% if page_obj %}
|
||||||
<div class="table-responsive">
|
<div class="tw:overflow-x-auto">
|
||||||
<table class="table table-hover text-nowrap">
|
<table class="tw:table tw:table-hover tw:whitespace-nowrap">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col" class="col-auto"></th>
|
<th scope="col" class="tw:w-auto"></th>
|
||||||
<th scope="col" class="col">{% translate 'Date' %}</th>
|
<th scope="col">{% translate 'Date' %}</th>
|
||||||
<th scope="col" class="col">{% translate 'Pairing' %}</th>
|
<th scope="col">{% translate 'Pairing' %}</th>
|
||||||
<th scope="col" class="col">{% translate 'Rate' %}</th>
|
<th scope="col">{% translate 'Rate' %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for exchange_rate in page_obj %}
|
{% for exchange_rate in page_obj %}
|
||||||
<tr class="exchange-rate">
|
<tr class="exchange-rate">
|
||||||
<td class="col-auto">
|
<td class="tw:w-auto">
|
||||||
<div class="btn-group" role="group" aria-label="{% translate 'Actions' %}">
|
<div class="tw:join" role="group" aria-label="{% translate 'Actions' %}">
|
||||||
<a class="btn btn-secondary btn-sm"
|
<a class="tw:btn tw:btn-secondary tw:btn-sm tw:join-item"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Edit" %}"
|
data-bs-title="{% translate "Edit" %}"
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
hx-target="#generic-offcanvas"
|
hx-target="#generic-offcanvas"
|
||||||
hx-swap="innerHTML">
|
hx-swap="innerHTML">
|
||||||
<i class="fa-solid fa-pencil fa-fw"></i></a>
|
<i class="fa-solid fa-pencil fa-fw"></i></a>
|
||||||
<a class="btn btn-secondary btn-sm text-danger"
|
<a class="tw:btn tw:btn-secondary tw:btn-sm tw:join-item tw:text-error"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Delete" %}"
|
data-bs-title="{% translate "Delete" %}"
|
||||||
@@ -39,9 +39,9 @@
|
|||||||
_="install prompt_swal"><i class="fa-solid fa-trash fa-fw"></i></a>
|
_="install prompt_swal"><i class="fa-solid fa-trash fa-fw"></i></a>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="col-3">{{ exchange_rate.date|date:"SHORT_DATETIME_FORMAT" }}</td>
|
<td class="tw:w-1/4">{{ exchange_rate.date|date:"SHORT_DATETIME_FORMAT" }}</td>
|
||||||
<td class="col-3"><span class="badge rounded-pill text-bg-secondary">{{ exchange_rate.from_currency.name }}</span> x <span class="badge rounded-pill text-bg-secondary">{{ exchange_rate.to_currency.name }}</span></td>
|
<td class="tw:w-1/4"><span class="tw:badge tw:badge-secondary tw:rounded-full">{{ exchange_rate.from_currency.name }}</span> x <span class="tw:badge tw:badge-secondary tw:rounded-full">{{ exchange_rate.to_currency.name }}</span></td>
|
||||||
<td class="col-3">1 {{ exchange_rate.from_currency.name }} ≅ {% currency_display amount=exchange_rate.rate prefix=exchange_rate.to_currency.prefix suffix=exchange_rate.to_currency.suffix decimal_places=exchange_rate.to_currency.decimal_places%}</td>
|
<td class="tw:w-1/4">1 {{ exchange_rate.from_currency.name }} ≅ {% currency_display amount=exchange_rate.rate prefix=exchange_rate.to_currency.prefix suffix=exchange_rate.to_currency.suffix decimal_places=exchange_rate.to_currency.decimal_places%}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
@@ -52,13 +52,12 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if page_obj.has_other_pages %}
|
{% if page_obj.has_other_pages %}
|
||||||
<div class="mt-auto">
|
<div class="tw:mt-auto">
|
||||||
<input value="{{ page_obj.number }}" name="page" type="hidden" id="page">
|
<input value="{{ page_obj.number }}" name="page" type="hidden" id="page">
|
||||||
|
|
||||||
<nav aria-label="{% translate 'Page navigation' %}">
|
<nav aria-label="{% translate 'Page navigation' %}">
|
||||||
<ul class="pagination justify-content-center mt-5">
|
<div class="tw:join tw:flex tw:justify-center tw:mt-5">
|
||||||
<li class="page-item">
|
<button class="tw:join-item tw:btn tw:btn-sm tw:cursor-pointer {% if not page_obj.has_previous %}tw:btn-disabled{% endif %}"
|
||||||
<a class="page-link tw:cursor-pointer {% if not page_obj.has_previous %}disabled{% endif %}"
|
|
||||||
hx-get="{% if page_obj.has_previous %}{% url 'exchange_rates_list_pair' %}{% endif %}"
|
hx-get="{% if page_obj.has_previous %}{% url 'exchange_rates_list_pair' %}{% endif %}"
|
||||||
hx-vals='{"page": 1, "from": "{{ from_currency|default_if_none:"" }}", "to": "{{ to_currency|default_if_none:"" }}"}'
|
hx-vals='{"page": 1, "from": "{{ from_currency|default_if_none:"" }}", "to": "{{ to_currency|default_if_none:"" }}"}'
|
||||||
hx-include="#filter, #order"
|
hx-include="#filter, #order"
|
||||||
@@ -66,8 +65,7 @@
|
|||||||
aria-label="Primeira página"
|
aria-label="Primeira página"
|
||||||
hx-swap="show:top">
|
hx-swap="show:top">
|
||||||
<span aria-hidden="true">«</span>
|
<span aria-hidden="true">«</span>
|
||||||
</a>
|
</button>
|
||||||
</li>
|
|
||||||
{% for page_number in page_obj.paginator.page_range %}
|
{% for page_number in page_obj.paginator.page_range %}
|
||||||
{% comment %}
|
{% comment %}
|
||||||
This conditional allows us to display up to 3 pages before and after the current page
|
This conditional allows us to display up to 3 pages before and after the current page
|
||||||
@@ -78,44 +76,35 @@
|
|||||||
{% endcomment %}
|
{% endcomment %}
|
||||||
{% if page_number <= page_obj.number|add:3 and page_number >= page_obj.number|add:-3 %}
|
{% if page_number <= page_obj.number|add:3 and page_number >= page_obj.number|add:-3 %}
|
||||||
{% if page_obj.number == page_number %}
|
{% if page_obj.number == page_number %}
|
||||||
<li class="page-item active">
|
<button class="tw:join-item tw:btn tw:btn-sm tw:btn-active tw:cursor-pointer">
|
||||||
<a class="page-link tw:cursor-pointer">
|
|
||||||
{{ page_number }}
|
{{ page_number }}
|
||||||
</a>
|
</button>
|
||||||
</li>
|
|
||||||
{% else %}
|
{% else %}
|
||||||
<li class="page-item">
|
<button class="tw:join-item tw:btn tw:btn-sm tw:cursor-pointer"
|
||||||
<a class="page-link tw:cursor-pointer"
|
|
||||||
hx-get="{% url 'exchange_rates_list_pair' %}"
|
hx-get="{% url 'exchange_rates_list_pair' %}"
|
||||||
hx-vals='{"page": {{ page_number }}, "from": "{{ from_currency|default_if_none:"" }}", "to": "{{ to_currency|default_if_none:"" }}"}'
|
hx-vals='{"page": {{ page_number }}, "from": "{{ from_currency|default_if_none:"" }}", "to": "{{ to_currency|default_if_none:"" }}"}'
|
||||||
hx-target="#exchange-rates-table"
|
hx-target="#exchange-rates-table"
|
||||||
hx-swap="show:top">
|
hx-swap="show:top">
|
||||||
{{ page_number }}
|
{{ page_number }}
|
||||||
</a>
|
</button>
|
||||||
</li>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% if page_obj.number|add:3 < page_obj.paginator.num_pages %}
|
{% if page_obj.number|add:3 < page_obj.paginator.num_pages %}
|
||||||
<li class="page-item">
|
<button class="tw:join-item tw:btn tw:btn-sm tw:btn-disabled"
|
||||||
<a class="page-link disabled"
|
|
||||||
aria-label="...">
|
aria-label="...">
|
||||||
<span aria-hidden="true">...</span>
|
<span aria-hidden="true">...</span>
|
||||||
</a>
|
</button>
|
||||||
</li>
|
<button class="tw:join-item tw:btn tw:btn-sm tw:cursor-pointer"
|
||||||
<li class="page-item">
|
|
||||||
<a class="page-link tw:cursor-pointer"
|
|
||||||
hx-get="{% url 'exchange_rates_list_pair' %}" hx-target="#exchange-rates-table"
|
hx-get="{% url 'exchange_rates_list_pair' %}" hx-target="#exchange-rates-table"
|
||||||
hx-vals='{"page": {{ page_obj.paginator.num_pages }}, "from": "{{ from_currency|default_if_none:"" }}", "to": "{{ to_currency|default_if_none:"" }}"}'
|
hx-vals='{"page": {{ page_obj.paginator.num_pages }}, "from": "{{ from_currency|default_if_none:"" }}", "to": "{{ to_currency|default_if_none:"" }}"}'
|
||||||
hx-include="#filter, #order"
|
hx-include="#filter, #order"
|
||||||
hx-swap="show:top"
|
hx-swap="show:top"
|
||||||
aria-label="Última página">
|
aria-label="Última página">
|
||||||
<span aria-hidden="true">{{ page_obj.paginator.num_pages }}</span>
|
<span aria-hidden="true">{{ page_obj.paginator.num_pages }}</span>
|
||||||
</a>
|
</button>
|
||||||
</li>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<li class="page-item">
|
<button class="tw:join-item tw:btn tw:btn-sm {% if not page_obj.has_next %}tw:btn-disabled{% endif %} tw:cursor-pointer"
|
||||||
<a class="page-link {% if not page_obj.has_next %}disabled{% endif %} tw:cursor-pointer"
|
|
||||||
hx-get="{% if page_obj.has_next %}{% url 'exchange_rates_list_pair' %}{% endif %}"
|
hx-get="{% if page_obj.has_next %}{% url 'exchange_rates_list_pair' %}{% endif %}"
|
||||||
hx-vals='{"page": {{ page_obj.paginator.num_pages }}, "from": "{{ from_currency|default_if_none:"" }}", "to": "{{ to_currency|default_if_none:"" }}"}'
|
hx-vals='{"page": {{ page_obj.paginator.num_pages }}, "from": "{{ from_currency|default_if_none:"" }}", "to": "{{ to_currency|default_if_none:"" }}"}'
|
||||||
hx-include="#filter, #order"
|
hx-include="#filter, #order"
|
||||||
@@ -123,9 +112,8 @@
|
|||||||
hx-target="#exchange-rates-table"
|
hx-target="#exchange-rates-table"
|
||||||
aria-label="Next">
|
aria-label="Next">
|
||||||
<span aria-hidden="true">»</span>
|
<span aria-hidden="true">»</span>
|
||||||
</a>
|
</button>
|
||||||
</li>
|
</div>
|
||||||
</ul>
|
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
{% block title %}{% translate 'Export' %}{% endblock %}
|
{% block title %}{% translate 'Export' %}{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<div class="container p-3">
|
<div class="tw:container tw:p-3">
|
||||||
<form hx-post="{% url 'export_form' %}" hx-ext="htmx-download" hx-swap="none" id="export-form" class="show-loading px-1" target="_blank">
|
<form hx-post="{% url 'export_form' %}" hx-ext="htmx-download" hx-swap="none" id="export-form" class="show-loading tw:px-1" target="_blank">
|
||||||
{% crispy form %}
|
{% crispy form %}
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,12 +5,12 @@
|
|||||||
{% block title %}{% translate 'Restore' %}{% endblock %}
|
{% block title %}{% translate 'Restore' %}{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<div class="container p-3">
|
<div class="tw:container tw:p-3">
|
||||||
<form hx-post="{% url 'restore_form' %}"
|
<form hx-post="{% url 'restore_form' %}"
|
||||||
hx-target="#generic-offcanvas"
|
hx-target="#generic-offcanvas"
|
||||||
id="restore-form"
|
id="restore-form"
|
||||||
enctype="multipart/form-data"
|
enctype="multipart/form-data"
|
||||||
class="show-loading px-1">
|
class="show-loading tw:px-1">
|
||||||
{% crispy form %}
|
{% crispy form %}
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load webpack_loader %}
|
<div class="offcanvas-header tw:flex tw:justify-between tw:items-center">
|
||||||
<div class="offcanvas-header">
|
<h5 class="offcanvas-title tw:font-medium tw:text-xl">{% block title %}{% endblock %}</h5>
|
||||||
<h5 class="offcanvas-title">{% block title %}{% endblock %}</h5>
|
<button type="button" class="tw:btn tw:btn-ghost tw:btn-sm tw:btn-circle" aria-label="{% trans 'Close' %}" data-bs-dismiss="offcanvas"><i class="fa-solid fa-xmark"></i></button>
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label={% translate 'Close' %}></button>
|
|
||||||
</div>
|
</div>
|
||||||
<div id="generic-offcanvas-body" class="offcanvas-body"
|
<div id="generic-offcanvas-body" class="offcanvas-body"
|
||||||
_="install init_tom_select
|
_="install init_tom_select
|
||||||
|
|||||||
@@ -1,22 +1,20 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
<div class="container px-md-3 py-3 column-gap-5">
|
<div class="tw:container tw:px-md-3 tw:py-3 tw:column-gap-5">
|
||||||
<div class="tw:text-3xl fw-bold font-monospace tw:w-full mb-3">
|
<div class="tw:text-3xl tw:font-bold tw:font-mono tw:w-full tw:mb-3">
|
||||||
{% spaceless %}
|
{% spaceless %}
|
||||||
<div>{% translate 'Import Profiles' %}<span>
|
<div>{% translate 'Import Profiles' %}<span>
|
||||||
<span class="dropdown" data-bs-toggle="tooltip"
|
<span class="tw:dropdown" data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Add" %}">
|
data-bs-title="{% translate "Add" %}">
|
||||||
<a class="text-decoration-none tw:text-2xl p-1" role="button"
|
<a class="tw:no-underline tw:text-2xl tw:p-1" role="button"
|
||||||
data-bs-toggle="dropdown"
|
data-bs-toggle="dropdown"
|
||||||
data-bs-title="{% translate "Add" %}" aria-expanded="false">
|
data-bs-title="{% translate "Add" %}" aria-expanded="false">
|
||||||
<i class="fa-solid fa-circle-plus fa-fw"></i>
|
<i class="fa-solid fa-circle-plus fa-fw"></i>
|
||||||
</a>
|
</a>
|
||||||
<ul class="dropdown-menu">
|
<ul class="tw:dropdown-content tw:menu tw:bg-base-100 tw:rounded-box tw:z-[1] tw:w-52 tw:p-2 tw:shadow">
|
||||||
<li><a class="dropdown-item"
|
<li><a role="button"
|
||||||
role="button"
|
|
||||||
hx-get="{% url 'import_profiles_add' %}"
|
hx-get="{% url 'import_profiles_add' %}"
|
||||||
hx-target="#generic-offcanvas">{% trans 'New' %}</a></li>
|
hx-target="#generic-offcanvas">{% trans 'New' %}</a></li>
|
||||||
<li><a class="dropdown-item"
|
<li><a role="button"
|
||||||
role="button"
|
|
||||||
hx-get="{% url 'import_presets_list' %}"
|
hx-get="{% url 'import_presets_list' %}"
|
||||||
hx-target="#persistent-generic-offcanvas-left">{% trans 'From preset' %}</a></li>
|
hx-target="#persistent-generic-offcanvas-left">{% trans 'From preset' %}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -25,45 +23,45 @@
|
|||||||
{% endspaceless %}
|
{% endspaceless %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card">
|
<div class="tw:card tw:bg-base-100 tw:shadow-xl">
|
||||||
<div class="card-body table-responsive">
|
<div class="tw:card-body tw:overflow-x-auto">
|
||||||
{% if profiles %}
|
{% if profiles %}
|
||||||
<c-config.search></c-config.search>
|
<c-config.search></c-config.search>
|
||||||
<table class="table table-hover text-nowrap">
|
<table class="tw:table tw:table-hover tw:whitespace-nowrap">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col" class="col-auto"></th>
|
<th scope="col" class="tw:w-auto"></th>
|
||||||
<th scope="col" class="col">{% translate 'Name' %}</th>
|
<th scope="col">{% translate 'Name' %}</th>
|
||||||
<th scope="col" class="col">{% translate 'Version' %}</th>
|
<th scope="col">{% translate 'Version' %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for profile in profiles %}
|
{% for profile in profiles %}
|
||||||
<tr class="profile">
|
<tr class="profile">
|
||||||
<td class="col-auto">
|
<td class="tw:w-auto">
|
||||||
<div class="btn-group" role="group" aria-label="{% translate 'Actions' %}">
|
<div class="tw:join" role="group" aria-label="{% translate 'Actions' %}">
|
||||||
<a class="btn btn-secondary btn-sm"
|
<a class="tw:btn tw:btn-secondary tw:btn-sm tw:join-item"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Edit" %}"
|
data-bs-title="{% translate "Edit" %}"
|
||||||
hx-get="{% url 'import_profile_edit' profile_id=profile.id %}"
|
hx-get="{% url 'import_profile_edit' profile_id=profile.id %}"
|
||||||
hx-target="#generic-offcanvas">
|
hx-target="#generic-offcanvas">
|
||||||
<i class="fa-solid fa-pencil fa-fw"></i></a>
|
<i class="fa-solid fa-pencil fa-fw"></i></a>
|
||||||
<a class="btn btn-secondary btn-sm text-success"
|
<a class="tw:btn tw:btn-secondary tw:btn-sm tw:join-item tw:text-success"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Runs" %}"
|
data-bs-title="{% translate "Runs" %}"
|
||||||
hx-get="{% url 'import_profile_runs_list' profile_id=profile.id %}"
|
hx-get="{% url 'import_profile_runs_list' profile_id=profile.id %}"
|
||||||
hx-target="#persistent-generic-offcanvas-left">
|
hx-target="#persistent-generic-offcanvas-left">
|
||||||
<i class="fa-solid fa-person-running fa-fw"></i></a>
|
<i class="fa-solid fa-person-running fa-fw"></i></a>
|
||||||
<a class="btn btn-secondary btn-sm text-primary"
|
<a class="tw:btn tw:btn-secondary tw:btn-sm tw:join-item tw:text-primary"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Import" %}"
|
data-bs-title="{% translate "Import" %}"
|
||||||
hx-get="{% url 'import_run_add' profile_id=profile.id %}"
|
hx-get="{% url 'import_run_add' profile_id=profile.id %}"
|
||||||
hx-target="#generic-offcanvas">
|
hx-target="#generic-offcanvas">
|
||||||
<i class="fa-solid fa-file-import fa-fw"></i></a>
|
<i class="fa-solid fa-file-import fa-fw"></i></a>
|
||||||
<a class="btn btn-secondary btn-sm text-danger"
|
<a class="tw:btn tw:btn-secondary tw:btn-sm tw:join-item tw:text-error"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Delete" %}"
|
data-bs-title="{% translate "Delete" %}"
|
||||||
@@ -76,8 +74,8 @@
|
|||||||
_="install prompt_swal"><i class="fa-solid fa-trash fa-fw"></i></a>
|
_="install prompt_swal"><i class="fa-solid fa-trash fa-fw"></i></a>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="col">{{ profile.name }}</td>
|
<td>{{ profile.name }}</td>
|
||||||
<td class="col">{{ profile.get_version_display }}</td>
|
<td>{{ profile.get_version_display }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -6,28 +6,28 @@
|
|||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
{% if presets %}
|
{% if presets %}
|
||||||
<div id="search" class="mb-3">
|
<div id="search" class="tw:mb-3">
|
||||||
<label class="w-100">
|
<label class="tw:w-full">
|
||||||
<input type="search"
|
<input type="search"
|
||||||
class="form-control"
|
class="tw:input tw:input-bordered tw:w-full"
|
||||||
placeholder="{% translate 'Search' %}"
|
placeholder="{% translate 'Search' %}"
|
||||||
_="on input or search
|
_="on input or search
|
||||||
show < .col /> in <#items/>
|
show < .col /> in <#items/>
|
||||||
when its textContent.toLowerCase() contains my value.toLowerCase()"/>
|
when its textContent.toLowerCase() contains my value.toLowerCase()"/>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="row row-cols-1 g-4" id="items">
|
<div class="tw:grid tw:grid-cols-1 tw:gap-4" id="items">
|
||||||
{% for preset in presets %}
|
{% for preset in presets %}
|
||||||
<a class="text-decoration-none"
|
<a class="tw:no-underline"
|
||||||
role="button"
|
role="button"
|
||||||
hx-post="{% url 'import_profiles_add' %}"
|
hx-post="{% url 'import_profiles_add' %}"
|
||||||
hx-vals='{"yaml_config": {{ preset.config }}, "name": "{{ preset.name }}", "version": "{{ preset.schema_version }}", "message": {{ preset.message }}}'
|
hx-vals='{"yaml_config": {{ preset.config }}, "name": "{{ preset.name }}", "version": "{{ preset.schema_version }}", "message": {{ preset.message }}}'
|
||||||
hx-target="#generic-offcanvas">
|
hx-target="#generic-offcanvas">
|
||||||
|
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="card">
|
<div class="tw:card tw:bg-base-100 tw:shadow-xl">
|
||||||
<div class="card-body">
|
<div class="tw:card-body">
|
||||||
<h5 class="card-title">{{ preset.name }}</h5>
|
<h5 class="tw:card-title">{{ preset.name }}</h5>
|
||||||
<hr>
|
<hr>
|
||||||
<p>{{ preset.description }}</p>
|
<p>{{ preset.description }}</p>
|
||||||
<p>{% trans 'By' %} {{ preset.authors|join:", " }}</p>
|
<p>{% trans 'By' %} {{ preset.authors|join:", " }}</p>
|
||||||
|
|||||||
@@ -11,21 +11,21 @@
|
|||||||
class="show-loading"
|
class="show-loading"
|
||||||
hx-swap="show:none scroll:none">
|
hx-swap="show:none scroll:none">
|
||||||
{% if runs %}
|
{% if runs %}
|
||||||
<div class="row row-cols-1 g-4">
|
<div class="tw:grid tw:grid-cols-1 tw:gap-4">
|
||||||
{% for run in runs %}
|
{% for run in runs %}
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="card">
|
<div class="tw:card tw:bg-base-100 tw:shadow-xl">
|
||||||
<div class="card-header tw:text-sm {% if run.status == run.Status.QUEUED %}text-body{% elif run.status == run.Status.PROCESSING %}text-warning{% elif run.status == run.Status.FINISHED %}text-success{% else %}text-danger{% endif %}">
|
<div class="tw:card-header tw:bg-base-200 tw:p-4 tw:text-sm {% if run.status == run.Status.QUEUED %}tw:text-base-content{% elif run.status == run.Status.PROCESSING %}tw:text-warning{% elif run.status == run.Status.FINISHED %}tw:text-success{% else %}tw:text-error{% endif %}">
|
||||||
<span><i class="fa-solid {% if run.status == run.Status.QUEUED %}fa-hourglass-half{% elif run.status == run.Status.PROCESSING %}fa-spinner{% elif run.status == run.Status.FINISHED %}fa-check{% else %}fa-xmark{% endif %} fa-fw me-2"></i>{{ run.get_status_display }}</span>
|
<span><i class="fa-solid {% if run.status == run.Status.QUEUED %}fa-hourglass-half{% elif run.status == run.Status.PROCESSING %}fa-spinner{% elif run.status == run.Status.FINISHED %}fa-check{% else %}fa-xmark{% endif %} fa-fw tw:me-2"></i>{{ run.get_status_display }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="tw:card-body">
|
||||||
<h5 class="card-title"><i class="fa-solid fa-hashtag me-1 tw:text-xs tw:text-gray-400"></i>{{ run.id }}<span class="tw:text-xs tw:text-gray-400 ms-1">({{ run.file_name }})</span></h5>
|
<h5 class="tw:card-title"><i class="fa-solid fa-hashtag tw:me-1 tw:text-xs tw:text-gray-400"></i>{{ run.id }}<span class="tw:text-xs tw:text-gray-400 tw:ms-1">({{ run.file_name }})</span></h5>
|
||||||
<hr>
|
<hr>
|
||||||
<div class="row row-cols-1 row-cols-md-2 row-cols-lg-3 w-100 g-4">
|
<div class="tw:grid tw:grid-cols-1 tw:md:grid-cols-2 tw:lg:grid-cols-3 tw:w-full tw:gap-4">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="d-flex flex-row">
|
<div class="tw:flex tw:flex-row">
|
||||||
<div class="d-flex flex-column">
|
<div class="tw:flex tw:flex-col">
|
||||||
<div class="text-body-secondary tw:text-xs tw:font-medium">
|
<div class="tw:text-base-content/70 tw:text-xs tw:font-medium">
|
||||||
{% trans 'Total Items' %}
|
{% trans 'Total Items' %}
|
||||||
</div>
|
</div>
|
||||||
<div class="tw:text-sm">
|
<div class="tw:text-sm">
|
||||||
@@ -36,9 +36,9 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="d-flex flex-row">
|
<div class="tw:flex tw:flex-row">
|
||||||
<div class="d-flex flex-column">
|
<div class="tw:flex tw:flex-col">
|
||||||
<div class="text-body-secondary tw:text-xs tw:font-medium">
|
<div class="tw:text-base-content/70 tw:text-xs tw:font-medium">
|
||||||
{% trans 'Processed Items' %}
|
{% trans 'Processed Items' %}
|
||||||
</div>
|
</div>
|
||||||
<div class="tw:text-sm">
|
<div class="tw:text-sm">
|
||||||
@@ -49,9 +49,9 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="d-flex flex-row">
|
<div class="tw:flex tw:flex-row">
|
||||||
<div class="d-flex flex-column">
|
<div class="tw:flex tw:flex-col">
|
||||||
<div class="text-body-secondary tw:text-xs tw:font-medium">
|
<div class="tw:text-base-content/70 tw:text-xs tw:font-medium">
|
||||||
{% trans 'Skipped Items' %}
|
{% trans 'Skipped Items' %}
|
||||||
</div>
|
</div>
|
||||||
<div class="tw:text-sm">
|
<div class="tw:text-sm">
|
||||||
@@ -62,9 +62,9 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="d-flex flex-row">
|
<div class="tw:flex tw:flex-row">
|
||||||
<div class="d-flex flex-column">
|
<div class="tw:flex tw:flex-col">
|
||||||
<div class="text-body-secondary tw:text-xs tw:font-medium">
|
<div class="tw:text-base-content/70 tw:text-xs tw:font-medium">
|
||||||
{% trans 'Failed Items' %}
|
{% trans 'Failed Items' %}
|
||||||
</div>
|
</div>
|
||||||
<div class="tw:text-sm">
|
<div class="tw:text-sm">
|
||||||
@@ -75,9 +75,9 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="d-flex flex-row">
|
<div class="tw:flex tw:flex-row">
|
||||||
<div class="d-flex flex-column">
|
<div class="tw:flex tw:flex-col">
|
||||||
<div class="text-body-secondary tw:text-xs tw:font-medium">
|
<div class="tw:text-base-content/70 tw:text-xs tw:font-medium">
|
||||||
{% trans 'Successful Items' %}
|
{% trans 'Successful Items' %}
|
||||||
</div>
|
</div>
|
||||||
<div class="tw:text-sm">
|
<div class="tw:text-sm">
|
||||||
@@ -89,14 +89,14 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-footer text-body-secondary">
|
<div class="tw:card-footer tw:bg-base-200 tw:p-4 tw:text-base-content/70">
|
||||||
<a class="text-decoration-none text-info"
|
<a class="tw:no-underline tw:text-info"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Logs" %}"
|
data-bs-title="{% translate "Logs" %}"
|
||||||
hx-get="{% url 'import_run_log' profile_id=profile.id run_id=run.id %}"
|
hx-get="{% url 'import_run_log' profile_id=profile.id run_id=run.id %}"
|
||||||
hx-target="#generic-offcanvas"><i class="fa-solid fa-file-lines"></i></a>
|
hx-target="#generic-offcanvas"><i class="fa-solid fa-file-lines"></i></a>
|
||||||
<a class="text-decoration-none text-danger"
|
<a class="tw:no-underline tw:text-error"
|
||||||
role="button"
|
role="button"
|
||||||
data-bs-toggle="tooltip"
|
data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% translate "Delete" %}"
|
data-bs-title="{% translate "Delete" %}"
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
{% block title %}{% translate 'Logs for' %} #{{ run.id }}{% endblock %}
|
{% block title %}{% translate 'Logs for' %} #{{ run.id }}{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<div class="card tw:max-h-full tw:overflow-auto">
|
<div class="tw:card tw:bg-base-100 tw:shadow-xl tw:max-h-full tw:overflow-auto">
|
||||||
<div class="card-body">
|
<div class="tw:card-body">
|
||||||
{{ run.logs|linebreaks }}
|
{{ run.logs|linebreaks }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,14 +3,16 @@
|
|||||||
{% load static %}
|
{% load static %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load active_link %}
|
{% load active_link %}
|
||||||
<nav class="navbar border-bottom bg-body-tertiary d-flex d-lg-none" hx-boost="true">
|
<nav class="tw:navbar tw:border-b tw:border-base-300 tw:bg-base-200 tw:flex tw:lg:hidden" hx-boost="true">
|
||||||
<div class="container-fluid">
|
<div class="tw:container tw:mx-auto tw:px-4 tw:flex tw:justify-between tw:items-center tw:w-full">
|
||||||
<a class="navbar-brand fw-bold text-primary font-base" href="{% url 'index' %}">
|
<a class="tw:text-xl tw:font-bold tw:text-primary" href="{% url 'index' %}">
|
||||||
<img src="{% static 'img/logo-icon.svg' %}" alt="WYGIWYH Logo" height="40" width="40" title="WYGIWYH"/>
|
<img src="{% static 'img/logo-icon.svg' %}" alt="WYGIWYH Logo" height="40" width="40" title="WYGIWYH"/>
|
||||||
</a>
|
</a>
|
||||||
<button class="navbar-toggler" type="button" data-bs-toggle="offcanvas" data-bs-target="#sidebar"
|
<button class="tw:btn tw:btn-ghost tw:lg:hidden" type="button" data-bs-toggle="offcanvas" data-bs-target="#sidebar"
|
||||||
aria-controls="sidebar" aria-label={% translate "Toggle navigation" %}>
|
aria-controls="sidebar" aria-label={% translate "Toggle navigation" %}>
|
||||||
<span class="navbar-toggler-icon"></span>
|
<svg class="tw:w-6 tw:h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path>
|
||||||
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|||||||
@@ -1,24 +1,24 @@
|
|||||||
{% load settings %}
|
{% load settings %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
<div class="dropdown">
|
<div class="tw:dropdown tw:dropdown-top tw:dropdown-end">
|
||||||
<div class="btn btn-secondary btn-sm" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
<div tabindex="0" role="button" class="tw:btn tw:btn-secondary tw:btn-sm">
|
||||||
<i class="fa-solid fa-cog"></i>
|
<i class="fa-solid fa-cog"></i>
|
||||||
</div>
|
</div>
|
||||||
<ul class="dropdown-menu dropdown-menu-start dropdown-menu-lg-end">
|
<ul tabindex="0" class="tw:dropdown-content tw:menu tw:bg-base-100 tw:rounded-box tw:z-[1] tw:w-52 tw:p-2 tw:shadow">
|
||||||
<li><a class="dropdown-item"
|
<li><a
|
||||||
hx-get="{% url 'user_settings' %}"
|
hx-get="{% url 'user_settings' %}"
|
||||||
hx-target="#generic-offcanvas"
|
hx-target="#generic-offcanvas"
|
||||||
role="button">
|
role="button">
|
||||||
<i class="fa-solid fa-gear me-2 fa-fw"></i>{% translate 'Settings' %}</a></li>
|
<i class="fa-solid fa-gear tw:me-2 fa-fw"></i>{% translate 'Settings' %}</a></li>
|
||||||
<li><a class="dropdown-item"
|
<li><a
|
||||||
hx-get="{% url 'user_edit' pk=request.user.id %}"
|
hx-get="{% url 'user_edit' pk=request.user.id %}"
|
||||||
hx-target="#generic-offcanvas"
|
hx-target="#generic-offcanvas"
|
||||||
role="button">
|
role="button">
|
||||||
<i class="fa-solid fa-user me-2 fa-fw"></i>{% translate 'Edit profile' %}</a></li>
|
<i class="fa-solid fa-user tw:me-2 fa-fw"></i>{% translate 'Edit profile' %}</a></li>
|
||||||
<li><hr class="dropdown-divider"></li>
|
<hr class="tw:my-1 tw:text-base-content/60">
|
||||||
{% spaceless %}
|
{% spaceless %}
|
||||||
<li>
|
<li>
|
||||||
<a class="dropdown-item" hx-get="{% url 'toggle_amount_visibility' %}" role="button">
|
<a hx-get="{% url 'toggle_amount_visibility' %}" role="button">
|
||||||
{% if user.settings.hide_amounts %}
|
{% if user.settings.hide_amounts %}
|
||||||
{% include 'users/generic/show_amounts.html' %}
|
{% include 'users/generic/show_amounts.html' %}
|
||||||
{% else %}
|
{% else %}
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
{% endspaceless %}
|
{% endspaceless %}
|
||||||
{% spaceless %}
|
{% spaceless %}
|
||||||
<li>
|
<li>
|
||||||
<a class="dropdown-item" hx-get="{% url 'toggle_sound_playing' %}" role="button">
|
<a hx-get="{% url 'toggle_sound_playing' %}" role="button">
|
||||||
{% if user.settings.mute_sounds %}
|
{% if user.settings.mute_sounds %}
|
||||||
{% include 'users/generic/play_sounds.html' %}
|
{% include 'users/generic/play_sounds.html' %}
|
||||||
{% else %}
|
{% else %}
|
||||||
@@ -38,15 +38,15 @@
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endspaceless %}
|
{% endspaceless %}
|
||||||
<li><hr class="dropdown-divider"></li>
|
<hr class="tw:my-1 tw:text-base-content/60">
|
||||||
<li>
|
<li>
|
||||||
<a class="dropdown-item" hx-get="{% url 'invalidate_cache' %}" role="button">
|
<a hx-get="{% url 'invalidate_cache' %}" role="button">
|
||||||
<i class="fa-solid fa-broom me-2 fa-fw"></i>{% translate 'Clear cache' %}
|
<i class="fa-solid fa-broom tw:me-2 fa-fw"></i>{% translate 'Clear cache' %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li><a class="dropdown-item" href="{% url 'logout' %}"><i class="fa-solid fa-door-open me-2 fa-fw"></i
|
<li><a href="{% url 'logout' %}"><i class="fa-solid fa-door-open tw:me-2 fa-fw"></i
|
||||||
>{% translate 'Logout' %}</a></li>
|
>{% translate 'Logout' %}</a></li>
|
||||||
<li><hr class="dropdown-divider"></li>
|
<hr class="tw:my-1 tw:text-base-content/60">
|
||||||
<li><a class="dropdown-item" href="https://github.com/eitchtee/WYGIWYH/releases" target="_blank" rel="nofollow">v. {% settings "APP_VERSION" %}</a></li>
|
<li><a href="https://github.com/eitchtee/WYGIWYH/releases" target="_blank" rel="nofollow">v. {% settings "APP_VERSION" %}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<div id="persistent-generic-offcanvas" class="offcanvas offcanvas-end offcanvas-size-xl tw:z-1100!"
|
<div id="persistent-generic-offcanvas" class="offcanvas offcanvas-end offcanvas-size-xl tw:z-1100! tw:bg-base-200! tw:text-base-content!"
|
||||||
data-bs-backdrop="static"
|
data-bs-backdrop="static"
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
_="on htmx:afterSettle call bootstrap.Offcanvas.getOrCreateInstance(me).show() end
|
_="on htmx:afterSettle call bootstrap.Offcanvas.getOrCreateInstance(me).show() end
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
on force_hide_offcanvas call bootstrap.Offcanvas.getOrCreateInstance(me).hide() end
|
on force_hide_offcanvas call bootstrap.Offcanvas.getOrCreateInstance(me).hide() end
|
||||||
on hidden.bs.offcanvas set my innerHTML to '' end">
|
on hidden.bs.offcanvas set my innerHTML to '' end">
|
||||||
</div>
|
</div>
|
||||||
<div id="persistent-generic-offcanvas-left" class="offcanvas offcanvas-start offcanvas-size-xl tw:z-1100!"
|
<div id="persistent-generic-offcanvas-left" class="offcanvas offcanvas-start offcanvas-size-xl tw:z-1100! tw:bg-base-200! tw:text-base-content!"
|
||||||
data-bs-backdrop="static"
|
data-bs-backdrop="static"
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
_="on htmx:afterSettle call bootstrap.Offcanvas.getOrCreateInstance(me).show() end
|
_="on htmx:afterSettle call bootstrap.Offcanvas.getOrCreateInstance(me).show() end
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div id="generic-offcanvas" class="offcanvas offcanvas-end offcanvas-size-xl tw:z-1100!"
|
<div id="generic-offcanvas" class="offcanvas offcanvas-end offcanvas-size-xl tw:z-1100! tw:bg-base-200! tw:text-base-content!"
|
||||||
data-bs-backdrop="static"
|
data-bs-backdrop="static"
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
_="on htmx:afterSettle call bootstrap.Offcanvas.getOrCreateInstance(me).show() end
|
_="on htmx:afterSettle call bootstrap.Offcanvas.getOrCreateInstance(me).show() end
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
on htmx:beforeOnLoad[detail.boosted] call bootstrap.Offcanvas.getOrCreateInstance(me).hide()
|
on htmx:beforeOnLoad[detail.boosted] call bootstrap.Offcanvas.getOrCreateInstance(me).hide()
|
||||||
on hidden.bs.offcanvas set my innerHTML to '' end">
|
on hidden.bs.offcanvas set my innerHTML to '' end">
|
||||||
</div>
|
</div>
|
||||||
<div id="generic-offcanvas-left" class="offcanvas offcanvas-start offcanvas-size-xl tw:z-1100!"
|
<div id="generic-offcanvas-left" class="offcanvas offcanvas-start offcanvas-size-xl tw:z-1100! tw:bg-base-200! tw:text-base-content!"
|
||||||
data-bs-backdrop="static"
|
data-bs-backdrop="static"
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
_="on htmx:afterSettle call bootstrap.Offcanvas.getOrCreateInstance(me).show() end
|
_="on htmx:afterSettle call bootstrap.Offcanvas.getOrCreateInstance(me).show() end
|
||||||
|
|||||||
@@ -12,3 +12,11 @@
|
|||||||
<div class="tw:bg-yellow-300"></div>
|
<div class="tw:bg-yellow-300"></div>
|
||||||
<div class="tw:bg-red-300"></div>
|
<div class="tw:bg-red-300"></div>
|
||||||
<div class="tw:bg-green-300"></div>
|
<div class="tw:bg-green-300"></div>
|
||||||
|
<div class="tw:btn-primary"></div>
|
||||||
|
<div class="tw:btn-secondary"></div>
|
||||||
|
<div class="tw:btn-accent"></div>
|
||||||
|
<div class="tw:btn-neutral"></div>
|
||||||
|
<div class="tw:btn-info"></div>
|
||||||
|
<div class="tw:btn-success"></div>
|
||||||
|
<div class="tw:btn-error"></div>
|
||||||
|
<div class="tw:btn-warning"></div>
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
{% load webpack_loader %}
|
{% load django_vite %}
|
||||||
|
|
||||||
{% javascript_pack 'bootstrap' attrs="defer" %}
|
{% vite_hmr_client %}
|
||||||
{% javascript_pack 'sweetalert2' attrs="defer" %}
|
|
||||||
{% javascript_pack 'select' attrs="defer" %}
|
{% vite_asset 'bootstrap' defer=True %}
|
||||||
{% javascript_pack 'datepicker' %}
|
{% vite_asset 'sweetalert2' defer=True %}
|
||||||
{% javascript_pack 'autosize' attrs="defer" %}
|
{% vite_asset 'select' defer=True %}
|
||||||
|
{% vite_asset 'datepicker' %}
|
||||||
|
{% vite_asset 'autosize' defer=True %}
|
||||||
|
|
||||||
{% 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' %}
|
||||||
@@ -15,8 +17,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' %}
|
||||||
|
|
||||||
{% javascript_pack 'htmx' attrs="defer" %}
|
{% vite_asset 'htmx' defer=True %}
|
||||||
{% javascript_pack 'charts' %}
|
{% vite_asset 'charts' %}
|
||||||
|
|
||||||
|
{% vite_asset 'style' %}
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
let tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
let tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||||
|
|||||||
@@ -11,18 +11,17 @@
|
|||||||
id="sidebar"
|
id="sidebar"
|
||||||
hx-boost="true"
|
hx-boost="true"
|
||||||
hx-swap="transition:true"
|
hx-swap="transition:true"
|
||||||
data-bs-scroll="true"
|
class="offcanvas-lg offcanvas-start tw:lg:flex tw:flex-col tw:fixed tw:top-0 tw:left-0 tw:h-full tw:bg-base-300! tw:shadow-sm tw:z-[1020]">
|
||||||
class="offcanvas-lg offcanvas-start d-lg-flex flex-column position-fixed top-0 start-0 h-100 bg-body-tertiary shadow-sm tw:z-1020">
|
<div class="tw:hidden tw:lg:flex tw:items-center tw:justify-between tw:pr-4 tw:border-b tw:border-base-content/10 sidebar-submenu-header">
|
||||||
|
<a href="{% url 'index' %}" class="tw:m-0 tw:hidden tw:lg:flex tw:justify-start tw:p-3 tw:no-underline sidebar-title">
|
||||||
<div class="d-none d-lg-flex tw:justify-between tw:items-center tw:border-b tw:border-gray-600 tw:lg:flex">
|
|
||||||
<a href="{% url 'index' %}" class="m-0 d-none d-lg-flex tw:justify-start p-3 text-decoration-none sidebar-title">
|
|
||||||
<img src="{% static 'img/logo-icon.svg' %}" alt="WYGIWYH Logo" height="30" width="30" title="WYGIWYH"/>
|
<img src="{% static 'img/logo-icon.svg' %}" alt="WYGIWYH Logo" height="30" width="30" title="WYGIWYH"/>
|
||||||
<span class="fs-4 fw-bold ms-3">WYGIWYH</span>
|
<span class="tw:text-2xl tw:font-bold tw:ml-3">WYGIWYH</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
id="sidebar-toggle-btn"
|
id="sidebar-toggle-btn"
|
||||||
class="text-secondary-emphasis tw:rounded-full tw:w-12 tw:h-12 tw:flex tw:items-center tw:justify-center tw:transition-all tw:duration-300"
|
|
||||||
|
class="tw:btn tw:btn-ghost tw:btn-circle tw:w-12 tw:h-12 tw:flex tw:items-center tw:justify-center tw:transition-all tw:duration-300"
|
||||||
hx-get="{% url 'toggle_sidebar_status' %}"
|
hx-get="{% url 'toggle_sidebar_status' %}"
|
||||||
_="on click
|
_="on click
|
||||||
toggle .sidebar-floating on #sidebar-container
|
toggle .sidebar-floating on #sidebar-container
|
||||||
@@ -36,17 +35,17 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="offcanvas-header">
|
<div class="tw:lg:hidden tw:flex tw:justify-between tw:items-center tw:p-4 tw:text-base-content">
|
||||||
<a href="{% url 'index' %}" class="offcanvas-title d-flex tw:justify-start text-decoration-none">
|
<a href="{% url 'index' %}" class="tw:flex tw:justify-start tw:no-underline">
|
||||||
<img src="{% static 'img/logo-icon.svg' %}" alt="WYGIWYH Logo" height="30" width="30" title="WYGIWYH"/>
|
<img src="{% static 'img/logo-icon.svg' %}" alt="WYGIWYH Logo" height="30" width="30" title="WYGIWYH"/>
|
||||||
<span class="fs-4 fw-bold ms-3">WYGIWYH</span>
|
<span class="tw:text-2xl tw:font-bold tw:ml-3">WYGIWYH</span>
|
||||||
</a>
|
</a>
|
||||||
<button type="button" class="btn-close" data-bs-target="#sidebar" data-bs-dismiss="offcanvas"
|
<button type="button" class="tw:btn tw:btn-ghost tw:btn-sm tw:btn-circle" data-bs-target="#sidebar" data-bs-dismiss="offcanvas"
|
||||||
aria-label={% translate 'Close' %}></button>
|
aria-label={% translate 'Close' %}><i class="fa-solid fa-xmark"></i></button>
|
||||||
</div>
|
</div>
|
||||||
<hr class="m-0">
|
<hr class="tw:m-0 tw:text-base-content/60">
|
||||||
|
|
||||||
<ul class="list-unstyled p-3 d-flex flex-column gap-0 tw:text-nowrap tw:lg:group-hover:animate-[disable-pointer-events]"
|
<ul class="tw:list-none tw:p-3 tw:flex tw:flex-col tw:gap-1 tw:whitespace-nowrap tw:lg:group-hover:animate-[disable-pointer-events]"
|
||||||
style="animation-duration: 100ms">
|
style="animation-duration: 100ms">
|
||||||
|
|
||||||
<c-components.sidebar-menu-item
|
<c-components.sidebar-menu-item
|
||||||
@@ -136,42 +135,43 @@
|
|||||||
</c-components.sidebar-menu-item>
|
</c-components.sidebar-menu-item>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<hr>
|
<hr class="tw:border-base-300">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div type="button"
|
<div role="button"
|
||||||
data-bs-toggle="collapse"
|
data-bs-toggle="collapse"
|
||||||
data-bs-target="#collapsible-panel"
|
data-bs-target="#collapsible-panel"
|
||||||
aria-expanded="false"
|
aria-expanded="false"
|
||||||
aria-controls="collapsible-panel"
|
aria-controls="collapsible-panel"
|
||||||
class="sidebar-menu-item tw:text-wrap tw:lg:text-nowrap tw:lg:text-sm d-flex align-items-center text-decoration-none p-2 rounded-3 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="sidebar-menu-item tw:text-wrap tw:lg:text-nowrap tw:lg:text-sm tw:flex tw:items-center tw:no-underline tw:p-2 tw:rounded-2xl tw: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" %}">
|
||||||
<i class="fa-solid fa-toolbox fa-fw"></i>
|
<i class="fa-solid fa-toolbox fa-fw"></i>
|
||||||
<span class="ms-3 fw-medium tw:lg:group-hover:truncate tw:lg:group-focus:truncate tw:lg:group-hover:text-ellipsis tw:lg:group-focus:text-ellipsis">
|
<span class="tw:ml-3 tw:font-medium tw:lg:group-hover:truncate tw:lg:group-focus:truncate tw:lg:group-hover:text-ellipsis tw:lg:group-focus:text-ellipsis">
|
||||||
{% translate 'Management' %}
|
{% translate 'Management' %}
|
||||||
</span>
|
</span>
|
||||||
<i class="fa-solid fa-chevron-right fa-fw ms-auto pe-2"></i>
|
<i class="fa-solid fa-chevron-right fa-fw tw:ml-auto tw:pe-2"></i>
|
||||||
</div>
|
</div>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div class="mt-auto p-2 w-100">
|
<div class="tw:mt-auto tw:p-2 tw:w-full">
|
||||||
<div id="collapsible-panel"
|
<div id="collapsible-panel"
|
||||||
class="p-0 collapse tw:absolute tw:bottom-0 tw:left-0 tw:w-full tw:z-30 tw: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="tw:p-0 collapse tw:absolute tw:bottom-0 tw:left-0 tw:w-full tw:z-30 tw: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="tw:h-dvh tw:backdrop-blur-3xl tw:flex tw:flex-col">
|
<div class="tw:h-dvh tw:backdrop-blur-3xl tw:flex tw:flex-col">
|
||||||
<div
|
<div
|
||||||
class="tw:justify-between tw:items-center tw:p-4 tw:border-b tw:border-gray-600 sidebar-submenu-header">
|
class="tw:justify-between tw:items-center tw:p-4 tw:border-b tw:border-base-content/10 sidebar-submenu-header tw:text-base-content">
|
||||||
<h5 class="tw:text-lg tw:font-semibold tw:text-gray-800 m-0">
|
<h5 class="tw:text-lg tw:font-semibold tw:text-base-content tw:m-0">
|
||||||
{% trans 'Management' %}
|
{% trans 'Management' %}
|
||||||
</h5>
|
</h5>
|
||||||
|
|
||||||
<button type="button" class="btn-close" aria-label="Close"
|
<button type="button" class="tw:btn tw:btn-ghost tw:btn-sm tw:btn-circle" aria-label="{% trans 'Close' %}"
|
||||||
data-bs-toggle="collapse"
|
data-bs-toggle="collapse"
|
||||||
data-bs-target="#collapsible-panel"
|
data-bs-target="#collapsible-panel"
|
||||||
aria-expanded="true"
|
aria-expanded="true"
|
||||||
aria-controls="collapsible-panel">
|
aria-controls="collapsible-panel">
|
||||||
|
<i class="fa-solid fa-xmark"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ul class="list-unstyled p-3 d-flex flex-column gap-1 tw:lg:group-hover:animate-[disable-pointer-events] tw:flex-1"
|
<ul class="tw:list-none tw:p-3 tw:flex tw:flex-col tw:gap-2 tw:lg:group-hover:animate-[disable-pointer-events] tw:flex-1"
|
||||||
style="animation-duration: 100ms">
|
style="animation-duration: 100ms">
|
||||||
<c-components.sidebar-menu-header title="{% translate 'Transactions' %}"></c-components.sidebar-menu-header>
|
<c-components.sidebar-menu-header title="{% translate 'Transactions' %}"></c-components.sidebar-menu-header>
|
||||||
<c-components.sidebar-menu-item
|
<c-components.sidebar-menu-item
|
||||||
@@ -269,16 +269,16 @@
|
|||||||
</div>
|
</div>
|
||||||
{% get_update_check as update_check %}
|
{% get_update_check as update_check %}
|
||||||
{% if update_check.update_available %}
|
{% if update_check.update_available %}
|
||||||
<div class="my-3">
|
<div class="tw:my-3">
|
||||||
<a class="px-3 badge text-bg-primary text-decoration-none tw:cursor-pointer w-100 tw:text-xs!"
|
<a class="tw:px-3 tw:badge tw:badge-primary tw:no-underline tw:cursor-pointer tw:w-full !tw:text-xs"
|
||||||
href="https://github.com/eitchtee/WYGIWYH/releases/latest" target="_blank"><i
|
href="https://github.com/eitchtee/WYGIWYH/releases/latest" target="_blank"><i
|
||||||
class="fa-solid fa-circle-exclamation fa-fw me-2"></i><span
|
class="fa-solid fa-circle-exclamation fa-fw tw:mr-2"></i><span
|
||||||
class="tw:lg:invisible tw:lg:group-hover:visible">v.{{ update_check.latest_version }} {% translate 'is available' %}!</span></a>
|
class="tw:lg:invisible tw:lg:group-hover:visible">v.{{ update_check.latest_version }} {% translate 'is available' %}!</span></a>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<div class="btn-group w-100 sidebar-item" role="group">
|
<div class="tw:btn-group tw:w-full sidebar-item" role="group">
|
||||||
<button type="button" class="btn btn-secondary btn-sm" data-bs-toggle="tooltip"
|
<button type="button" class="tw:btn tw:btn-secondary tw:btn-sm tw:w-full" data-bs-toggle="tooltip"
|
||||||
data-bs-title="{% trans "Calculator" %}"
|
data-bs-title="{% trans "Calculator" %}"
|
||||||
_="on click trigger show on #calculator">
|
_="on click trigger show on #calculator">
|
||||||
<i class="fa-solid fa-calculator fa-fw"></i>
|
<i class="fa-solid fa-calculator fa-fw"></i>
|
||||||
@@ -287,14 +287,14 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<hr class="my-1">
|
<hr class="tw:my-1 tw:border-base-300">
|
||||||
<div
|
<div
|
||||||
class="ps-4 pe-2 py-2 d-flex align-items-center text-decoration-none justify-content-between">
|
class="tw:ps-4 tw:pe-2 tw:py-2 tw:flex tw:items-center tw:no-underline tw:justify-between">
|
||||||
|
|
||||||
<div class="d-flex align-items-center" style="min-width: 0;">
|
<div class="tw:flex tw:items-center" style="min-width: 0;">
|
||||||
<i class="fa-solid fa-circle-user text-body-secondary"></i>
|
<i class="fa-solid fa-circle-user tw:text-base-content/60"></i>
|
||||||
|
|
||||||
<strong class="mx-2 text-body-secondary text-truncate sidebar-invisible">
|
<strong class="tw:mx-2 tw:text-base-content/60 tw:truncate sidebar-invisible">
|
||||||
{{ user.email }}
|
{{ user.email }}
|
||||||
</strong>
|
</strong>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
{% load webpack_loader %}
|
|
||||||
|
|
||||||
{% stylesheet_pack 'style' %}
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{% load formats %}
|
{% load formats %}
|
||||||
<div class="tw:hidden tw:w-[60vw] tw:lg:w-[30vw] tw:xl:w-[20vw] position-fixed shadow rounded-3 bg-body tw:border-gray-700 tw:border tw:border-solid tw:text-center tw:align-middle tw:z-[2000] tw:touch-none user-select-none"
|
<div class="tw:hidden tw:w-[60vw] tw:lg:w-[30vw] tw:xl:w-[20vw] tw:fixed tw:shadow tw:rounded-3xl tw:bg-base-100 tw:border-base-300 tw:border tw:border-solid tw:text-center tw:align-middle tw:z-[2000] tw:touch-none tw:select-none"
|
||||||
id="calculator"
|
id="calculator"
|
||||||
hx-preserve
|
hx-preserve
|
||||||
_="
|
_="
|
||||||
@@ -48,12 +48,12 @@
|
|||||||
end">
|
end">
|
||||||
|
|
||||||
<div id="calculator-handle"
|
<div id="calculator-handle"
|
||||||
class="position-absolute bg-secondary rounded-top-2 tw:cursor-move d-flex align-items-center justify-content-center tw:top-[-20px] tw:left-[3px] tw:w-[2em] tw:h-[20px]">
|
class="tw:absolute tw:bg-secondary tw:rounded-t-lg tw:cursor-move tw:flex tw:items-center tw:justify-center tw:top-[-20px] tw:left-[3px] tw:w-[2em] tw:h-[20px]">
|
||||||
<i class="fa-solid fa-grip"></i>
|
<i class="fa-solid fa-grip"></i>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<input type="search"
|
<input type="search"
|
||||||
class="form-control"
|
class="tw:input tw:w-full"
|
||||||
id="calculator-input"
|
id="calculator-input"
|
||||||
_="on click me.focus()
|
_="on click me.focus()
|
||||||
on input or search
|
on input or search
|
||||||
@@ -91,12 +91,12 @@
|
|||||||
end"
|
end"
|
||||||
placeholder="2 + 2">
|
placeholder="2 + 2">
|
||||||
<div class="tw:hidden" id="calculator-result-container">
|
<div class="tw:hidden" id="calculator-result-container">
|
||||||
<div class="d-flex flex-row p-2 justify-content-between">
|
<div class="tw:flex tw:flex-row tw:p-2 tw:justify-between">
|
||||||
<div class="tw:text-gray-400">=</div>
|
<div class="tw:text-base-content/40">=</div>
|
||||||
<div id="calculator-result" class="user-select-all"></div>
|
<div id="calculator-result" class="tw:select-all"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="position-absolute tw:cursor-pointer top-0 start-100 translate-middle tw:p-0 text-bg-primary border border-light rounded-circle tw:flex tw:items-center tw:justify-center tw:w-5 tw:h-5"
|
<div class="tw:absolute tw:cursor-pointer tw:top-0 tw:left-full tw:start-100 tw:-translate-x-1/2 tw:-translate-y-1/2 tw:p-0 tw:bg-primary tw:text-primary-content tw:border tw:border-base-100 tw:rounded-full tw:flex tw:items-center tw:justify-center tw:w-5 tw:h-5"
|
||||||
_="on click trigger show on #calculator">
|
_="on click trigger show on #calculator">
|
||||||
<i class="fa-solid fa-xmark tw:flex tw:items-center tw:justify-center tw:w-full tw:h-full"></i>
|
<i class="fa-solid fa-xmark tw:flex tw:items-center tw:justify-center tw:w-full tw:h-full"></i>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% if account_data.labels %}
|
{% if account_data.labels %}
|
||||||
<div class="chart-container" style="position: relative; height:400px; width:100%"
|
<div class="chart-container tw:relative tw:h-[400px] tw:w-full"
|
||||||
_="init call setupAccountChart() end">
|
_="init call setupAccountChart() end">
|
||||||
<canvas id="accountChart"></canvas>
|
<canvas id="accountChart"></canvas>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% if currency_data.labels %}
|
{% if currency_data.labels %}
|
||||||
<div class="chart-container" style="position: relative; height:400px; width:100%"
|
<div class="chart-container tw:relative tw:h-[400px] tw:w-full"
|
||||||
_="init call setupCurrencyChart() end">
|
_="init call setupCurrencyChart() end">
|
||||||
<canvas id="currencyChart"></canvas>
|
<canvas id="currencyChart"></canvas>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user