mirror of
https://github.com/eitchtee/WYGIWYH.git
synced 2026-04-25 18:19:02 +02:00
feat: more changes and fixes
This commit is contained in:
@@ -59,7 +59,7 @@
|
||||
{
|
||||
label: "{% trans 'Projected Expenses' %}",
|
||||
data: accountData.datasets[3].data,
|
||||
backgroundColor: '#f8717180', // Added transparency
|
||||
backgroundColor: '#f8717180',
|
||||
stack: 'stack0'
|
||||
},
|
||||
{
|
||||
@@ -77,7 +77,7 @@
|
||||
{
|
||||
label: "{% trans 'Projected Income' %}",
|
||||
data: accountData.datasets[2].data,
|
||||
backgroundColor: '#4dde8080', // Added transparency
|
||||
backgroundColor: '#4dde8080',
|
||||
stack: 'stack0'
|
||||
},
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
{
|
||||
label: "{% trans 'Projected Expenses' %}",
|
||||
data: currencyData.datasets[3].data,
|
||||
backgroundColor: '#f8717180', // Added transparency
|
||||
backgroundColor: '#f8717180',
|
||||
stack: 'stack0'
|
||||
},
|
||||
{
|
||||
@@ -77,7 +77,7 @@
|
||||
{
|
||||
label: "{% trans 'Projected Income' %}",
|
||||
data: currencyData.datasets[2].data,
|
||||
backgroundColor: '#4dde8080', // Added transparency
|
||||
backgroundColor: '#4dde8080',
|
||||
stack: 'stack0'
|
||||
},
|
||||
|
||||
|
||||
@@ -1,37 +1,45 @@
|
||||
{% load i18n %}
|
||||
{% load crispy_forms_tags %}
|
||||
|
||||
<form _="install init_tom_select
|
||||
on change trigger updated
|
||||
init trigger updated" id="category-form">
|
||||
{% crispy category_form %}
|
||||
</form>
|
||||
|
||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-3">
|
||||
<div class="w-full">
|
||||
<div class="card bg-base-100 shadow-xl h-full">
|
||||
<div class="card-header bg-base-200 p-4 font-semibold">
|
||||
{% trans "Income/Expense by Account" %}
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div id="account-card" class="show-loading" hx-get="{% url 'category_sum_by_account' %}"
|
||||
hx-trigger="updated from:window" hx-include="#category-form, #picker-form, #picker-type">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full">
|
||||
<div class="card bg-base-100 shadow-xl h-full">
|
||||
<div class="card-header bg-base-200 p-4 font-semibold">
|
||||
{% trans "Income/Expense by Currency" %}
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div id="currency-card" class="show-loading" hx-get="{% url 'category_sum_by_currency' %}"
|
||||
hx-trigger="updated from:window" hx-include="#category-form, #picker-form, #picker-type">
|
||||
<div class="flex flex-col gap-3">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card card-border bg-base-100">
|
||||
<div class="card-body">
|
||||
<form _="install init_tom_select
|
||||
on change trigger updated
|
||||
init trigger updated" id="category-form">
|
||||
{% crispy category_form %}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12 lg:col-6">
|
||||
<div class="card bg-base-100 shadow-xl h-full">
|
||||
<div class="card-header bg-base-200 p-4 font-semibold rounded-box shadow">
|
||||
{% trans "Income/Expense by Account" %}
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div id="account-card" class="show-loading" hx-get="{% url 'category_sum_by_account' %}"
|
||||
hx-trigger="updated from:window" hx-include="#category-form, #picker-form, #picker-type">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-6">
|
||||
<div class="card bg-base-100 shadow-xl h-full">
|
||||
<div class="card-header bg-base-200 p-4 font-semibold rounded-box shadow">
|
||||
{% trans "Income/Expense by Currency" %}
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div id="currency-card" class="show-loading" hx-get="{% url 'category_sum_by_currency' %}"
|
||||
hx-trigger="updated from:window" hx-include="#category-form, #picker-form, #picker-type">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -3,56 +3,58 @@
|
||||
<div hx-get="{% url 'category_overview' %}" hx-trigger="updated from:window" class="show-loading" hx-swap="outerHTML"
|
||||
hx-include="#picker-form, #picker-type, #view-type, #show-tags, #showing, #show-entities">
|
||||
<div class="h-full text-center mb-4">
|
||||
<div class="join" role="group" id="view-type" _="on change trigger updated">
|
||||
<input type="radio" class="join-item btn btn-outline btn-primary rounded-full"
|
||||
name="view_type"
|
||||
id="table-view"
|
||||
autocomplete="off"
|
||||
value="table"
|
||||
aria-label="{% trans 'Table' %}"
|
||||
{% if view_type == "table" %}checked{% endif %}>
|
||||
|
||||
<input type="radio"
|
||||
class="join-item btn btn-outline btn-primary rounded-full"
|
||||
name="view_type"
|
||||
id="bars-view"
|
||||
autocomplete="off"
|
||||
value="bars"
|
||||
aria-label="{% trans 'Bars' %}"
|
||||
{% if view_type == "bars" %}checked{% endif %}>
|
||||
<div class="tabs tabs-box mx-auto w-fit" role="group" id="view-type" _="on change trigger updated">
|
||||
<label class="tab">
|
||||
<input type="radio"
|
||||
name="view_type"
|
||||
id="table-view"
|
||||
autocomplete="off"
|
||||
value="table"
|
||||
aria-label="{% trans 'Table' %}"
|
||||
{% if view_type == "table" %}checked{% endif %}>
|
||||
<i class="fa-solid fa-table fa-fw me-2"></i>
|
||||
{% trans 'Table' %}
|
||||
</label>
|
||||
<label class="tab">
|
||||
<input type="radio"
|
||||
name="view_type"
|
||||
id="bars-view"
|
||||
autocomplete="off"
|
||||
value="bars"
|
||||
aria-label="{% trans 'Bars' %}"
|
||||
{% if view_type == "bars" %}checked{% endif %}>
|
||||
<i class="fa-solid fa-chart-bar fa-fw me-2"></i>
|
||||
{% trans 'Bars' %}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-3 mb-1 flex flex-col md:flex-row justify-between">
|
||||
<div class="my-3 flex flex-col gap-3 md:flex-row justify-between">
|
||||
<div class="flex gap-4">
|
||||
{% if view_type == 'table' %}
|
||||
<div class="form-control" id="show-tags">
|
||||
<input type="hidden" name="show_tags" value="off">
|
||||
<label class="label cursor-pointer gap-2">
|
||||
<input type="checkbox" class="toggle" id="show-tags-switch" name="show_tags"
|
||||
<div id="show-tags">
|
||||
<label class="label">
|
||||
<input type="hidden" name="show_tags" value="off">
|
||||
<input type="checkbox" class="toggle toggle-primary toggle-sm" id="show-tags-switch" name="show_tags"
|
||||
_="on change trigger updated" {% if show_tags %}checked{% endif %}>
|
||||
{% spaceless %}
|
||||
<span class="label-text">
|
||||
<span>
|
||||
{% 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 %}
|
||||
</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>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-control" id="show-entities" {% if not show_tags %}style="display: none;"{% endif %}>
|
||||
<input type="hidden" name="show_entities" value="off">
|
||||
<label class="label cursor-pointer gap-2">
|
||||
<input type="checkbox" class="toggle" id="show-entities-switch" name="show_entities"
|
||||
<div id="show-entities" class="{% if not show_tags %}hidden{% endif %}">
|
||||
<label class="label">
|
||||
<input type="hidden" name="show_entities" value="off">
|
||||
<input type="checkbox" class="toggle toggle-primary toggle-sm" id="show-entities-switch" name="show_entities"
|
||||
_="on change trigger updated" {% if show_entities %}checked{% endif %}>
|
||||
{% spaceless %}
|
||||
<span class="label-text">
|
||||
<span>
|
||||
{% 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 %}
|
||||
</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>
|
||||
</label>
|
||||
</div>
|
||||
{% endif %}
|
||||
@@ -70,8 +72,10 @@
|
||||
</div>
|
||||
{% if total_table %}
|
||||
{% if view_type == "table" %}
|
||||
<div class="overflow-x-auto">
|
||||
<table class="table table-zebra">
|
||||
<div class="card bg-base-100 card-border">
|
||||
<c-config.search></c-config.search>
|
||||
<div class="overflow-x-auto">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">{% trans 'Category' %}</th>
|
||||
@@ -176,7 +180,7 @@
|
||||
{% for tag_id, tag in category.tags.items %}
|
||||
{% if tag.name or not tag.name and category.tags.values|length > 1 %}
|
||||
<tr class="bg-base-200">
|
||||
<td class="ps-4">
|
||||
<td class="ps-6">
|
||||
<i class="fa-solid fa-hashtag fa-fw me-2 text-base-content/60"></i>{% if tag.name %}{{ tag.name }}{% else %}{% trans 'Untagged' %}{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
@@ -269,7 +273,7 @@
|
||||
{% for entity_id, entity in tag.entities.items %}
|
||||
{% if entity.name or not entity.name and tag.entities.values|length > 1 %}
|
||||
<tr class="bg-base-300">
|
||||
<td class="ps-5">
|
||||
<td class="ps-10">
|
||||
<i class="fa-solid fa-user-group fa-fw me-2 text-base-content/60"></i>{% if entity.name %}{{ entity.name }}{% else %}{% trans 'No entity' %}{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
@@ -366,13 +370,16 @@
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{% elif view_type == "bars" %}
|
||||
<div>
|
||||
<div class="chart-container relative h-[78vh] w-full" _="init call setupChart() end">
|
||||
<canvas id="categoryChart"></canvas>
|
||||
<div class="card bg-base-100 card-border">
|
||||
<div class="card-body">
|
||||
<div class="chart-container relative h-[75vh] w-full" _="init call setupChart() end">
|
||||
<canvas id="categoryChart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{% load i18n %}
|
||||
|
||||
|
||||
<div hx-get="{% url 'insights_late_transactions' %}" hx-trigger="updated from:window" class="show-loading"
|
||||
<div hx-get="{% url 'insights_latest_transactions' %}" hx-trigger="updated from:window" class="show-loading"
|
||||
id="transactions-list" hx-swap="outerHTML">
|
||||
{% if transactions %}
|
||||
{% for transaction in transactions %}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<div class="show-loading" hx-get="{% url 'insights_sankey_by_currency' %}" hx-trigger="updated from:window"
|
||||
hx-swap="outerHTML" hx-include="#picker-form, #picker-type">
|
||||
{% endif %}
|
||||
<div class="chart-container relative min-h-[85vh] max-h-[85vh] h-full w-full"
|
||||
<div class="card bg-base-100 card-border chart-container relative min-h-[85vh] max-h-[85vh] h-full w-full"
|
||||
id="sankeyContainer"
|
||||
_="init call setupSankeyChart() end">
|
||||
<canvas id="sankeyChart"></canvas>
|
||||
@@ -15,7 +15,14 @@
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var style = getComputedStyle(document.body);
|
||||
var incomeColor = style.getPropertyValue('--color-success');
|
||||
var expenseColor = style.getPropertyValue('--color-error');
|
||||
var primaryColor = style.getPropertyValue('--color-primary');
|
||||
var contentColor = style.getPropertyValue('--color-base-content');
|
||||
console.log('Sankey colors:', incomeColor, expenseColor, primaryColor, contentColor);
|
||||
var data = {{ sankey_data|safe }};
|
||||
console.log(convertColorToRgba(incomeColor))
|
||||
|
||||
function setupSankeyChart(chartId = 'sankeyChart') {
|
||||
function formatCurrency(value, currency) {
|
||||
@@ -35,11 +42,11 @@
|
||||
const colors = {};
|
||||
data.nodes.forEach(node => {
|
||||
if (node.id.startsWith('income_')) {
|
||||
colors[node.id] = '#4dde80'; // Green for income
|
||||
colors[node.id] = convertColorToRgba(incomeColor); // Green for income
|
||||
} else if (node.id.startsWith('expense_')) {
|
||||
colors[node.id] = '#f87171'; // Red for expenses
|
||||
colors[node.id] = convertColorToRgba(expenseColor); // Red for expenses
|
||||
} else {
|
||||
colors[node.id] = '#fbb700'; // Primary for others
|
||||
colors[node.id] = convertColorToRgba(primaryColor); // Primary for others
|
||||
}
|
||||
});
|
||||
|
||||
@@ -63,7 +70,7 @@
|
||||
colorMode: 'gradient',
|
||||
alpha: 0.5,
|
||||
size: 'max',
|
||||
color: "white",
|
||||
color: contentColor,
|
||||
nodePadding: 30,
|
||||
priority: data.nodes.reduce((acc, node) => {
|
||||
acc[node.id] = node.priority;
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
|
||||
{% block content %}
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-12 md:col-3">
|
||||
<div class="row gy-3">
|
||||
<div class="col-12 md:col-3 gy-3">
|
||||
<div class="flex flex-col gap-3">
|
||||
<div class="card bg-base-100 card-borderS">
|
||||
<div class="card-body">
|
||||
@@ -73,22 +73,22 @@
|
||||
remove .btn-active from <.insights-list button/>
|
||||
add .btn-active to event.target
|
||||
set event.target's @aria-selected to 'true'">
|
||||
<button class="btn btn-ghost justify-start"
|
||||
<button class="btn btn-ghost justify-start text-start"
|
||||
type="button" role="tab" aria-controls="v-pills-content" aria-selected="false"
|
||||
hx-get="{% url 'insights_sankey_by_account' %}">
|
||||
{% trans 'Account Flow' %}
|
||||
</button>
|
||||
<button class="btn btn-ghost justify-start" data-bs-target="#v-pills-content"
|
||||
<button class="btn btn-ghost justify-start text-start" data-bs-target="#v-pills-content"
|
||||
type="button" role="tab" aria-controls="v-pills-content" aria-selected="false"
|
||||
hx-get="{% url 'insights_sankey_by_currency' %}"
|
||||
>{% trans 'Currency Flow' %}
|
||||
</button>
|
||||
<button class="btn btn-ghost justify-start" data-bs-target="#v-pills-content"
|
||||
<button class="btn btn-ghost justify-start text-start" data-bs-target="#v-pills-content"
|
||||
type="button" role="tab" aria-controls="v-pills-content" aria-selected="false"
|
||||
hx-get="{% url 'category_explorer_index' %}">
|
||||
{% trans 'Category Explorer' %}
|
||||
</button>
|
||||
<button class="btn btn-ghost justify-start" data-bs-target="#v-pills-content"
|
||||
<button class="btn btn-ghost justify-start text-start" data-bs-target="#v-pills-content"
|
||||
type="button" role="tab" aria-controls="v-pills-content" aria-selected="false"
|
||||
hx-get="{% url 'category_overview' %}"
|
||||
>{% trans 'Categories Overview' %}
|
||||
@@ -106,17 +106,17 @@
|
||||
remove .btn-active from <.insights-list button/>
|
||||
add .btn-active to event.target
|
||||
set event.target's @aria-selected to 'true'">
|
||||
<button class="btn btn-ghost justify-start" data-bs-target="#v-pills-content"
|
||||
<button class="btn btn-ghost justify-start text-start" data-bs-target="#v-pills-content"
|
||||
type="button" role="tab" aria-controls="v-pills-content" aria-selected="false"
|
||||
hx-get="{% url 'insights_late_transactions' %}">
|
||||
{% trans 'Late Transactions' %}
|
||||
</button>
|
||||
<button class="btn btn-ghost justify-start" data-bs-target="#v-pills-content"
|
||||
<button class="btn btn-ghost justify-start text-start" data-bs-target="#v-pills-content"
|
||||
type="button" role="tab" aria-controls="v-pills-content" aria-selected="false"
|
||||
hx-get="{% url 'insights_latest_transactions' %}">
|
||||
{% trans 'Latest Transactions' %}
|
||||
</button>
|
||||
<button class="btn btn-ghost justify-start" data-bs-target="#v-pills-content"
|
||||
<button class="btn btn-ghost justify-start text-start" data-bs-target="#v-pills-content"
|
||||
type="button" role="tab" aria-controls="v-pills-content" aria-selected="false"
|
||||
hx-get="{% url 'insights_emergency_fund' %}">
|
||||
{% trans 'Emergency Fund' %}
|
||||
@@ -126,7 +126,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-9">
|
||||
<div class="col-12 md:col-9 gy-3">
|
||||
<div id="tab-content" class="show-loading"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user