mirror of
https://github.com/eitchtee/WYGIWYH.git
synced 2026-05-20 14:47:12 +02:00
feat: automated replacement
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{% load i18n %}
|
||||
{% 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">
|
||||
<canvas id="accountChart"></canvas>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% load i18n %}
|
||||
{% 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">
|
||||
<canvas id="currencyChart"></canvas>
|
||||
</div>
|
||||
|
||||
@@ -7,25 +7,25 @@
|
||||
{% crispy category_form %}
|
||||
</form>
|
||||
|
||||
<div class="row row-cols-1 row-cols-lg-2 gx-3 gy-3">
|
||||
<div class="col">
|
||||
<div class="card h-100">
|
||||
<div class="card-header">
|
||||
<div class="tw:grid tw:grid-cols-1 tw:lg:grid-cols-2 tw:gap-3">
|
||||
<div class="tw:w-full">
|
||||
<div class="tw:card tw:bg-base-100 tw:shadow-xl tw:h-full">
|
||||
<div class="tw:card-header tw:bg-base-200 tw:p-4 tw:font-semibold">
|
||||
{% trans "Income/Expense by Account" %}
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="tw:card-body">
|
||||
<div id="account-card" class="show-loading" hx-get="{% url 'category_sum_by_account' %}"
|
||||
hx-trigger="updated from:window" hx-include="#category-form, #picker-form, #picker-type">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="card h-100">
|
||||
<div class="card-header">
|
||||
<div class="tw:w-full">
|
||||
<div class="tw:card tw:bg-base-100 tw:shadow-xl tw:h-full">
|
||||
<div class="tw:card-header tw:bg-base-200 tw:p-4 tw:font-semibold">
|
||||
{% trans "Income/Expense by Currency" %}
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="tw:card-body">
|
||||
<div id="currency-card" class="show-loading" hx-get="{% url 'category_sum_by_currency' %}"
|
||||
hx-trigger="updated from:window" hx-include="#category-form, #picker-form, #picker-type">
|
||||
</div>
|
||||
|
||||
@@ -2,77 +2,76 @@
|
||||
|
||||
<div hx-get="{% url 'category_overview' %}" hx-trigger="updated from:window" class="show-loading" hx-swap="outerHTML"
|
||||
hx-include="#picker-form, #picker-type, #view-type, #show-tags, #showing, #show-entities">
|
||||
<div class="h-100 text-center mb-4">
|
||||
<div class="btn-group gap-3" role="group" id="view-type" _="on change trigger updated">
|
||||
<input type="radio" class="btn-check"
|
||||
<div class="tw:h-full tw:text-center tw:mb-4">
|
||||
<div class="tw:join" role="group" id="view-type" _="on change trigger updated">
|
||||
<input type="radio" class="tw:join-item tw:btn tw:btn-outline tw:btn-primary tw:rounded-full"
|
||||
name="view_type"
|
||||
id="table-view"
|
||||
autocomplete="off"
|
||||
value="table"
|
||||
aria-label="{% trans 'Table' %}"
|
||||
{% if view_type == "table" %}checked{% endif %}>
|
||||
<label class="btn btn-outline-primary rounded-5" for="table-view"><i
|
||||
class="fa-solid fa-table fa-fw me-2"></i>{% trans 'Table' %}</label>
|
||||
|
||||
<input type="radio"
|
||||
class="btn-check"
|
||||
class="tw:join-item tw:btn tw:btn-outline tw:btn-primary tw:rounded-full"
|
||||
name="view_type"
|
||||
id="bars-view"
|
||||
autocomplete="off"
|
||||
value="bars"
|
||||
aria-label="{% trans 'Bars' %}"
|
||||
{% if view_type == "bars" %}checked{% endif %}>
|
||||
<label class="btn btn-outline-primary rounded-5" for="bars-view"><i
|
||||
class="fa-solid fa-chart-bar fa-fw me-2"></i>{% trans 'Bars' %}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-3 mb-1 d-flex flex-column flex-md-row justify-content-between">
|
||||
<div class="d-flex gap-4">
|
||||
<div class="tw:mt-3 tw:mb-1 tw:flex tw:flex-col tw:md:flex-row tw:justify-between">
|
||||
<div class="tw:flex tw:gap-4">
|
||||
{% if view_type == 'table' %}
|
||||
<div class="form-check form-switch" id="show-tags">
|
||||
<div class="tw:form-control" id="show-tags">
|
||||
<input type="hidden" name="show_tags" value="off">
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="show-tags-switch" name="show_tags"
|
||||
_="on change trigger updated" {% if show_tags %}checked{% endif %}>
|
||||
{% spaceless %}
|
||||
<label class="form-check-label" for="show-tags-switch">
|
||||
{% trans 'Tags' %}
|
||||
</label>
|
||||
<c-ui.help-icon
|
||||
content="{% trans 'Transaction amounts associated with multiple tags will be counted once for each tag' %}"
|
||||
icon="fa-solid fa-circle-exclamation"></c-ui.help-icon>
|
||||
{% endspaceless %}
|
||||
<label class="tw:label tw:cursor-pointer tw:gap-2">
|
||||
<input type="checkbox" class="tw:toggle" id="show-tags-switch" name="show_tags"
|
||||
_="on change trigger updated" {% if show_tags %}checked{% endif %}>
|
||||
{% spaceless %}
|
||||
<span class="tw:label-text">
|
||||
{% trans 'Tags' %}
|
||||
</span>
|
||||
<c-ui.help-icon
|
||||
content="{% trans 'Transaction amounts associated with multiple tags will be counted once for each tag' %}"
|
||||
icon="fa-solid fa-circle-exclamation"></c-ui.help-icon>
|
||||
{% endspaceless %}
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check form-switch" id="show-entities" {% if not show_tags %}style="display: none;"{% endif %}>
|
||||
<div class="tw:form-control" id="show-entities" {% if not show_tags %}style="display: none;"{% endif %}>
|
||||
<input type="hidden" name="show_entities" value="off">
|
||||
<input class="form-check-input" type="checkbox" role="switch" id="show-entities-switch" name="show_entities"
|
||||
_="on change trigger updated" {% if show_entities %}checked{% endif %}>
|
||||
{% spaceless %}
|
||||
<label class="form-check-label" for="show-entities-switch">
|
||||
{% trans 'Entities' %}
|
||||
</label>
|
||||
<c-ui.help-icon
|
||||
content="{% trans 'Transaction amounts associated with multiple tags and entities will be counted once for each tag' %}"
|
||||
icon="fa-solid fa-circle-exclamation"></c-ui.help-icon>
|
||||
{% endspaceless %}
|
||||
<label class="tw:label tw:cursor-pointer tw:gap-2">
|
||||
<input type="checkbox" class="tw:toggle" id="show-entities-switch" name="show_entities"
|
||||
_="on change trigger updated" {% if show_entities %}checked{% endif %}>
|
||||
{% spaceless %}
|
||||
<span class="tw:label-text">
|
||||
{% trans 'Entities' %}
|
||||
</span>
|
||||
<c-ui.help-icon
|
||||
content="{% trans 'Transaction amounts associated with multiple tags and entities will be counted once for each tag' %}"
|
||||
icon="fa-solid fa-circle-exclamation"></c-ui.help-icon>
|
||||
{% endspaceless %}
|
||||
</label>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="btn-group btn-group-sm" role="group" id="showing" _="on change trigger updated">
|
||||
<input type="radio" class="btn-check" name="showing" id="showing-projected" autocomplete="off"
|
||||
<div class="tw:join" role="group" id="showing" _="on change trigger updated">
|
||||
<input type="radio" class="tw:join-item tw:btn tw:btn-outline tw:btn-primary tw:btn-sm" name="showing" id="showing-projected" autocomplete="off" aria-label="{% trans 'Projected' %}"
|
||||
value="projected" {% if showing == 'projected' %}checked{% endif %}>
|
||||
<label class="btn btn-outline-primary" for="showing-projected">{% trans "Projected" %}</label>
|
||||
|
||||
<input type="radio" class="btn-check" name="showing" id="showing-current" autocomplete="off" value="current"
|
||||
<input type="radio" class="tw:join-item tw:btn tw:btn-outline tw:btn-primary tw:btn-sm" name="showing" id="showing-current" autocomplete="off" value="current" aria-label="{% trans 'Current' %}"
|
||||
{% if showing == 'current' %}checked{% endif %}>
|
||||
<label class="btn btn-outline-primary" for="showing-current">{% trans "Current" %}</label>
|
||||
|
||||
<input type="radio" class="btn-check" name="showing" id="showing-final" autocomplete="off" value="final"
|
||||
<input type="radio" class="tw:join-item tw:btn tw:btn-outline tw:btn-primary tw:btn-sm" name="showing" id="showing-final" autocomplete="off" value="final" aria-label="{% trans 'Final total' %}"
|
||||
{% if showing == 'final' %}checked{% endif %}>
|
||||
<label class="btn btn-outline-primary" for="showing-final">{% trans "Final total" %}</label>
|
||||
</div>
|
||||
</div>
|
||||
{% if total_table %}
|
||||
{% if view_type == "table" %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-hover table-bordered align-middle">
|
||||
<div class="tw:overflow-x-auto">
|
||||
<table class="tw:table tw:table-zebra">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">{% trans 'Category' %}</th>
|
||||
@@ -81,10 +80,10 @@
|
||||
<th scope="col">{% trans 'Total' %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="table-group-divider">
|
||||
<tbody>
|
||||
{% for category in total_table.values %}
|
||||
<!-- Category row -->
|
||||
<tr class="table-group-header">
|
||||
<tr class="tw:font-semibold">
|
||||
<th>{% if category.name %}{{ category.name }}{% else %}{% trans 'Uncategorized' %}{% endif %}</th>
|
||||
<td> {# income #}
|
||||
{% for currency in category.currencies.values %}
|
||||
@@ -176,9 +175,9 @@
|
||||
{% if show_tags %}
|
||||
{% for tag_id, tag in category.tags.items %}
|
||||
{% if tag.name or not tag.name and category.tags.values|length > 1 %}
|
||||
<tr class="table-row-nested">
|
||||
<td class="ps-4">
|
||||
<i class="fa-solid fa-hashtag fa-fw me-2 text-muted"></i>{% if tag.name %}{{ tag.name }}{% else %}{% trans 'Untagged' %}{% endif %}
|
||||
<tr class="tw:bg-base-200">
|
||||
<td class="tw:ps-4">
|
||||
<i class="fa-solid fa-hashtag fa-fw tw:me-2 tw:text-base-content/60"></i>{% if tag.name %}{{ tag.name }}{% else %}{% trans 'Untagged' %}{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% for currency in tag.currencies.values %}
|
||||
@@ -269,9 +268,9 @@
|
||||
{% if show_entities %}
|
||||
{% for entity_id, entity in tag.entities.items %}
|
||||
{% if entity.name or not entity.name and tag.entities.values|length > 1 %}
|
||||
<tr class="table-row-nested-2">
|
||||
<td class="ps-5">
|
||||
<i class="fa-solid fa-user-group fa-fw me-2 text-muted"></i>{% if entity.name %}{{ entity.name }}{% else %}{% trans 'No entity' %}{% endif %}
|
||||
<tr class="tw:bg-base-300">
|
||||
<td class="tw:ps-5">
|
||||
<i class="fa-solid fa-user-group fa-fw tw:me-2 tw:text-base-content/60"></i>{% if entity.name %}{{ entity.name }}{% else %}{% trans 'No entity' %}{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% for currency in entity.currencies.values %}
|
||||
@@ -372,7 +371,7 @@
|
||||
|
||||
{% elif view_type == "bars" %}
|
||||
<div>
|
||||
<div class="chart-container" _="init call setupChart() end" style="position: relative; height:78vh; width:100%">
|
||||
<div class="chart-container tw:relative tw:h-[78vh] tw:w-full" _="init call setupChart() end">
|
||||
<canvas id="categoryChart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,68 +3,62 @@
|
||||
|
||||
<div hx-get="{% url 'insights_emergency_fund' %}" hx-trigger="updated from:window" class="show-loading"
|
||||
hx-swap="outerHTML">
|
||||
<div class="accordion" id="emergency-fund-accordion">
|
||||
<div class="tw:join tw:join-vertical tw:w-full" id="emergency-fund-accordion">
|
||||
{% for id, data in data.items %}
|
||||
{% if data.average %}
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header">
|
||||
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse"
|
||||
data-bs-target="#flush-collapse-{{ id }}" aria-expanded="false"
|
||||
aria-controls="flush-collapse-{{ id }}">
|
||||
<span>
|
||||
<span class="tw:text-gray-300">{% trans "You've spent an average of" %}</span>
|
||||
<div class="tw:collapse tw:collapse-arrow tw:join-item tw:border-base-300 tw:border">
|
||||
<input type="radio" name="emergency-fund-accordion" />
|
||||
<div class="tw:collapse-title tw:text-base tw:font-medium">
|
||||
<span>
|
||||
<span class="tw:text-base-content/60">{% trans "You've spent an average of" %}</span>
|
||||
<c-amount.display
|
||||
:amount="data.average"
|
||||
:prefix="data.currency.prefix"
|
||||
:suffix="data.currency.suffix"
|
||||
:decimal_places="data.currency.decimal_places"
|
||||
custom_class="tw:text-3xl"
|
||||
divless></c-amount.display>
|
||||
<span class="tw:text-base-content/60">{% trans 'on the last 12 months, at this rate you could go by' %}</span>
|
||||
<span class="tw:text-3xl">{{ data.months }}</span>
|
||||
<span class="tw:text-base-content/60">{% trans 'months without any income.' %}</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="tw:collapse-content">
|
||||
<div class="tw:flex tw:justify-between tw:items-baseline tw:mt-2">
|
||||
<div class="tw:text-end tw:font-mono">
|
||||
<div class="tw:text-base-content/60">{% translate 'average expenses' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line tw:flex-grow"></div>
|
||||
<div class="tw:text-end tw:font-mono">
|
||||
<c-amount.display
|
||||
:amount="data.average"
|
||||
:prefix="data.currency.prefix"
|
||||
:suffix="data.currency.suffix"
|
||||
:decimal_places="data.currency.decimal_places"
|
||||
custom_class="tw:text-3xl"
|
||||
divless></c-amount.display>
|
||||
<span class="tw:text-gray-300">{% trans 'on the last 12 months, at this rate you could go by' %}</span>
|
||||
<span class="tw:text-3xl">{{ data.months }}</span>
|
||||
<span class="tw:text-gray-300">{% trans 'months without any income.' %}</span>
|
||||
</span>
|
||||
</button>
|
||||
</h2>
|
||||
<div id="flush-collapse-{{ id }}" class="accordion-collapse collapse"
|
||||
data-bs-parent="#emergency-fund-accordion">
|
||||
<div class="accordion-body">
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw:text-gray-400">{% translate 'average expenses' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div class="text-end font-monospace">
|
||||
<c-amount.display
|
||||
:amount="data.average"
|
||||
:prefix="data.currency.prefix"
|
||||
:suffix="data.currency.suffix"
|
||||
:decimal_places="data.currency.decimal_places"
|
||||
color="red"></c-amount.display>
|
||||
</div>
|
||||
color="red"></c-amount.display>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw:text-gray-400">{% translate 'liquid total' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div class="text-end font-monospace">
|
||||
<c-amount.display
|
||||
:amount="data.total_current"
|
||||
:prefix="data.currency.prefix"
|
||||
:suffix="data.currency.suffix"
|
||||
:decimal_places="data.currency.decimal_places"
|
||||
color="{% if data.total_current > 0 %}green{% elif data.total_current < 0 %}red{% endif %}"></c-amount.display>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tw:flex tw:justify-between tw:items-baseline tw:mt-2">
|
||||
<div class="tw:text-end tw:font-mono">
|
||||
<div class="tw:text-base-content/60">{% translate 'liquid total' %}</div>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between align-items-baseline mt-2">
|
||||
<div class="text-end font-monospace">
|
||||
<div class="tw:text-gray-400">{% translate 'months left' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line flex-grow-1"></div>
|
||||
<div class="text-end font-monospace">
|
||||
<span>{{ data.months }}</span>
|
||||
</div>
|
||||
<div class="dotted-line tw:flex-grow"></div>
|
||||
<div class="tw:text-end tw:font-mono">
|
||||
<c-amount.display
|
||||
:amount="data.total_current"
|
||||
:prefix="data.currency.prefix"
|
||||
:suffix="data.currency.suffix"
|
||||
:decimal_places="data.currency.decimal_places"
|
||||
color="{% if data.total_current > 0 %}green{% elif data.total_current < 0 %}red{% endif %}"></c-amount.display>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tw:flex tw:justify-between tw:items-baseline tw:mt-2">
|
||||
<div class="tw:text-end tw:font-mono">
|
||||
<div class="tw:text-base-content/60">{% translate 'months left' %}</div>
|
||||
</div>
|
||||
<div class="dotted-line tw:flex-grow"></div>
|
||||
<div class="tw:text-end tw:font-mono">
|
||||
<span>{{ data.months }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<div class="show-loading" hx-get="{% url 'insights_sankey_by_currency' %}" hx-trigger="updated from:window"
|
||||
hx-swap="outerHTML" hx-include="#picker-form, #picker-type">
|
||||
{% endif %}
|
||||
<div class="chart-container position-relative tw:min-h-[85vh] tw:max-h-[85vh] tw:h-full tw:w-full"
|
||||
<div class="chart-container tw:relative tw:min-h-[85vh] tw:max-h-[85vh] tw:h-full tw:w-full"
|
||||
id="sankeyContainer"
|
||||
_="init call setupSankeyChart() end">
|
||||
<canvas id="sankeyChart"></canvas>
|
||||
|
||||
Reference in New Issue
Block a user