feat: remove bootstrap's collapses; improve animations

This commit is contained in:
Herculino Trotta
2025-12-14 11:06:55 -03:00
parent cf7d4b1404
commit 4aa29545ec
14 changed files with 189 additions and 514 deletions

View File

@@ -0,0 +1,39 @@
{% load active_link %}
{% load i18n %}
<c-vars id="collapsible-panel" />
<li>
<div role="button"
_="on click toggle .hidden on #{{ id }} then toggle .slide-in-left on #{{ id }}"
class="text-xs flex items-center no-underline ps-3 p-2 rounded-box sidebar-item cursor-pointer {% active_link views=active css_class='sidebar-active' %}">
<i class="{{ icon }} fa-fw"></i>
<span class="ml-3 font-medium lg:group-hover:truncate lg:group-focus:truncate lg:group-hover:text-ellipsis lg:group-focus:text-ellipsis">
{{ title }}
</span>
<i class="fa-solid fa-chevron-right fa-fw ml-auto pe-2"></i>
</div>
</li>
<div id="{{ id }}"
class="p-0 absolute bottom-0 left-0 w-full z-30 max-h-dvh {% active_link views=active css_class='slide-in-left' inactive_class='hidden' %}">
<div class="h-dvh bg-base-300 flex flex-col">
<div class="items-center p-4 border-b border-base-content/10 sidebar-submenu-header text-base-content">
<div class="flex items-center sidebar-submenu-title">
<i class="{{ icon }} fa-fw lg:group-hover:me-2 me-2 lg:me-0"></i>
<h5 class="text-lg font-semibold text-base-content m-0">
{{ title }}
</h5>
</div>
<button type="button" class="btn btn-ghost btn-sm btn-circle" aria-label="{% trans 'Close' %}"
_="on click remove .slide-in-left from #{{ id }} then add .slide-out-left to #{{ id }} then wait 150ms then add .hidden to #{{ id }} then remove .slide-out-left from #{{ id }}">
<i class="fa-solid fa-xmark"></i>
</button>
</div>
<ul class="sidebar-item-list list-none p-3 flex flex-col gap-1 whitespace-nowrap lg:group-hover:animate-[disable-pointer-events] overflow-y-auto lg:overflow-y-hidden lg:hover:overflow-y-auto overflow-x-hidden"
style="animation-duration: 100ms">
{{ slot }}
</ul>
</div>
</div>

View File

@@ -1,12 +1,14 @@
<li class="lg:hidden lg:group-hover:block">
<div class="flex items-center" data-bs-toggle="collapse" href="#{{ title|slugify }}" role="button"
aria-expanded="false" aria-controls="{{ title|slugify }}">
<li class="lg:hidden lg:group-hover:block" x-data="{ open: false }">
<div class="flex items-center" @click="open = !open" role="button"
:aria-expanded="open">
<span
class="text-base-content/60 text-sm font-bold uppercase lg:hidden lg:group-hover:inline me-2">{{ title }}</span>
<hr class="flex-grow"/>
<i class="fas fa-chevron-down text-base-content/60 lg:before:hidden lg:group-hover:before:inline ml-2 lg:ml-0 lg:group-hover:ml-2"></i>
<i class="fas fa-chevron-down text-base-content/60 lg:before:hidden lg:group-hover:before:inline ml-2 lg:ml-0 lg:group-hover:ml-2"
:class="{ 'rotate-180': open }"
style="transition: transform 0.2s ease"></i>
</div>
<div x-show="open" x-collapse>
{{ slot }}
</div>
</li>
<div class="collapse lg:hidden lg:group-hover:block" id="{{ title|slugify }}">
{{ slot }}
</div>

View File

@@ -1,94 +0,0 @@
<div class="card bg-base-100 shadow-xl mb-2 transaction-item">
<div class="card-body p-2 flex items-center gap-3" data-bs-toggle="collapse" data-bs-target="#{{ transaction.id }}" role="button" aria-expanded="false" aria-controls="{{ transaction.id }}">
<!-- Main visible content -->
<div class="flex flex-col lg:flex-row lg:items-center w-full gap-3">
<!-- Type indicator -->
<div class="w-8">
{% if transaction.type == 'IN' %}
<span class="badge badge-success"></span>
{% else %}
<span class="badge badge-error"></span>
{% endif %}
</div>
<!-- Payment status -->
<div class="w-8">
{% if transaction.is_paid %}
<span class="badge badge-success"></span>
{% else %}
<span class="badge badge-warning"></span>
{% endif %}
</div>
<!-- Description -->
<div class="flex-grow">
<span class="font-medium">{{ transaction.description }}</span>
</div>
<!-- Amount -->
<div class="text-right whitespace-nowrap">
<span class="{% if transaction.type == 'IN' %}text-green-400{% else %}text-red-400{% endif %}">
{{ transaction.amount }}
</span>
{% if transaction.exchanged_amount %}
<br>
<small class="text-base-content/60">
{{ transaction.exchanged_amount.prefix }}{{ transaction.exchanged_amount.amount }}{{ transaction.exchanged_amount.suffix }}
</small>
{% endif %}
</div>
</div>
</div>
<!-- Expandable details -->
<div class="collapse" id="{{ transaction.id }}">
<div class="card-body p-3 transaction-details">
<div class="grid grid-cols-1 md:grid-cols-2">
<div>
<dl class="grid grid-cols-3">
<dt class="col-span-1">Date</dt>
<dd class="col-span-2">{{ transaction.date|date:"Y-m-d" }}</dd>
<dt class="col-span-1">Reference Date</dt>
<dd class="col-span-2">{{ transaction.reference_date|date:"Y-m" }}</dd>
<dt class="col-span-1">Account</dt>
<dd class="col-span-2">{{ transaction.account.name }}</dd>
<dt class="col-span-1">Category</dt>
<dd class="col-span-2">{{ transaction.category|default:"-" }}</dd>
</dl>
</div>
<div>
<dl class="grid grid-cols-3">
{% if transaction.tags.exists %}
<dt class="col-span-1">Tags</dt>
<dd class="col-span-2">
{% for tag in transaction.tags.all %}
<span class="badge badge-secondary">{{ tag.name }}</span>
{% endfor %}
</dd>
{% endif %}
{% if transaction.installment_plan %}
<dt class="col-span-1">Installment</dt>
<dd class="col-span-2">
{{ transaction.installment_id }} of {{ transaction.installment_plan.total_installments }}
</dd>
{% endif %}
{% if transaction.recurring_transaction %}
<dt class="col-span-1">Recurring</dt>
<dd class="col-span-2">Yes</dd>
{% endif %}
{% if transaction.notes %}
<dt class="col-span-1">Notes</dt>
<dd class="col-span-2">{{ transaction.notes }}</dd>
{% endif %}
</dl>
</div>
</div>
</div>
</div>
</div>

View File

@@ -1,183 +0,0 @@
{% load cache_access %}
{% load settings %}
{% load static %}
{% load i18n %}
{% load active_link %}
<nav class="navbar navbar-expand-lg border-bottom bg-body-tertiary" hx-boost="true">
<div class="container-fluid">
<a class="navbar-brand fw-bold text-primary font-base" href="{% url 'index' %}">
<img src="{% static 'img/logo-icon.svg' %}" alt="WYGIWYH Logo" height="40" width="40" title="WYGIWYH"/>
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarContent"
aria-controls="navbarContent" aria-expanded="false" aria-label={% translate "Toggle navigation" %}>
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarContent">
<ul class="navbar-nav me-auto mb-3 mb-lg-0 nav-underline" hx-push-url="true">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle {% active_link views='monthly_overview||yearly_overview_currency||yearly_overview_account||calendar' %}"
href="#"
role="button"
data-bs-toggle="dropdown"
aria-expanded="false">
{% translate 'Overview' %}
</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item {% active_link views='monthly_overview' %}"
href="{% url 'monthly_index' %}">{% translate 'Monthly' %}</a></li>
<li><a class="dropdown-item {% active_link views='yearly_overview_currency' %}"
href="{% url 'yearly_index_currency' %}">{% translate 'Yearly by currency' %}</a></li>
<li><a class="dropdown-item {% active_link views='yearly_overview_account' %}"
href="{% url 'yearly_index_account' %}">{% translate 'Yearly by account' %}</a></li>
<li><a class="dropdown-item {% active_link views='calendar' %}"
href="{% url 'calendar_index' %}">{% translate 'Calendar' %}</a></li>
</ul>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle {% active_link views='net_worth_current||net_worth_projected' %}"
href="#" role="button"
data-bs-toggle="dropdown"
aria-expanded="false">
{% translate 'Net Worth' %}
</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item {% active_link views='net_worth_current' %}"
href="{% url 'net_worth_current' %}">{% translate 'Current' %}</a></li>
<li><a class="dropdown-item {% active_link views='net_worth_projected' %}"
href="{% url 'net_worth_projected' %}">{% translate 'Projected' %}</a></li>
</ul>
</li>
<li class="nav-item">
<a class="nav-link {% active_link views='insights_index' %}" href="{% url 'insights_index' %}">{% trans 'Insights' %}</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle {% active_link views='installment_plans_index||quick_transactions_index||recurring_trasanctions_index||transactions_all_index||transactions_trash_index' %}"
href="#" role="button"
data-bs-toggle="dropdown"
aria-expanded="false">
{% translate 'Transactions' %}
</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item {% active_link views='transactions_all_index' %}"
href="{% url 'transactions_all_index' %}">{% translate 'All' %}</a></li>
<li>
{% settings "ENABLE_SOFT_DELETE" as enable_soft_delete %}
{% if enable_soft_delete %}
<li><a class="dropdown-item {% active_link views='transactions_trash_index' %}"
href="{% url 'transactions_trash_index' %}">{% translate 'Trash Can' %}</a></li>
<li>
{% endif %}
<hr class="dropdown-divider">
</li>
<li><a class="dropdown-item {% active_link views='quick_transactions_index' %}"
href="{% url 'quick_transactions_index' %}">{% translate 'Quick Transactions' %}</a></li>
<li><a class="dropdown-item {% active_link views='installment_plans_index' %}"
href="{% url 'installment_plans_index' %}">{% translate 'Installment Plans' %}</a></li>
<li><a class="dropdown-item {% active_link views='recurring_trasanctions_index' %}"
href="{% url 'recurring_trasanctions_index' %}">{% translate 'Recurring Transactions' %}</a></li>
</ul>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle {% active_link views='dca_strategy_index||dca_strategy_detail_index||unit_price_calculator||currency_converter' %}"
href="#" role="button"
data-bs-toggle="dropdown"
aria-expanded="false">
{% translate 'Tools' %}
</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item {% active_link views='dca_strategy_index||dca_strategy_detail_index' %}"
href="{% url 'dca_strategy_index' %}">{% translate 'Dollar Cost Average Tracker' %}</a></li>
<li>
<li><a class="dropdown-item {% active_link views='unit_price_calculator' %}"
href="{% url 'unit_price_calculator' %}">{% translate 'Unit Price Calculator' %}</a></li>
<li>
<li><a class="dropdown-item {% active_link views='currency_converter' %}"
href="{% url 'currency_converter' %}">{% translate 'Currency Converter' %}</a></li>
<li>
</ul>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle {% 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' %}"
href="#" role="button"
data-bs-toggle="dropdown"
aria-expanded="false">
{% translate 'Management' %}
</a>
<ul class="dropdown-menu">
<li><h6 class="dropdown-header">{% trans 'Transactions' %}</h6></li>
<li><a class="dropdown-item {% active_link views='categories_index' %}"
href="{% url 'categories_index' %}">{% translate 'Categories' %}</a></li>
<li><a class="dropdown-item {% active_link views='tags_index' %}"
href="{% url 'tags_index' %}">{% translate 'Tags' %}</a></li>
<li><a class="dropdown-item {% active_link views='entities_index' %}"
href="{% url 'entities_index' %}">{% translate 'Entities' %}</a></li>
<li>
<hr class="dropdown-divider">
</li>
<li><h6 class="dropdown-header">{% trans 'Accounts' %}</h6></li>
<li><a class="dropdown-item {% active_link views='accounts_index' %}"
href="{% url 'accounts_index' %}">{% translate 'Accounts' %}</a></li>
<li><a class="dropdown-item {% active_link views='account_groups_index' %}"
href="{% url 'account_groups_index' %}">{% translate 'Account Groups' %}</a></li>
<li>
<hr class="dropdown-divider">
</li>
<li><h6 class="dropdown-header">{% trans 'Currencies' %}</h6></li>
<li><a class="dropdown-item {% active_link views='currencies_index' %}"
href="{% url 'currencies_index' %}">{% translate 'Currencies' %}</a></li>
<li><a class="dropdown-item {% active_link views='exchange_rates_index' %}"
href="{% url 'exchange_rates_index' %}">{% translate 'Exchange Rates' %}</a></li>
<li>
<hr class="dropdown-divider">
</li>
<li><h6 class="dropdown-header">{% trans 'Automation' %}</h6></li>
<li><a class="dropdown-item {% active_link views='rules_index' %}"
href="{% url 'rules_index' %}">{% translate 'Rules' %}</a></li>
<li><a class="dropdown-item {% active_link views='import_profiles_index' %}"
href="{% url 'import_profiles_index' %}">{% translate 'Import' %} <span class="badge text-bg-primary">beta</span></a></li>
{% if user.is_superuser %}
<li><a class="dropdown-item {% active_link views='export_index' %}"
href="{% url 'export_index' %}">{% translate 'Export and Restore' %}</a></li>
{% endif %}
<li><a class="dropdown-item {% active_link views='automatic_exchange_rates_index' %}"
href="{% url 'automatic_exchange_rates_index' %}">{% translate 'Automatic Exchange Rates' %}</a></li>
{% if user.is_superuser %}
<li>
<hr class="dropdown-divider">
</li>
<li><h6 class="dropdown-header">{% trans 'Admin' %}</h6></li>
<li><a class="dropdown-item {% active_link views='users_index' %}"
href="{% url 'users_index' %}">{% translate 'Users' %}</a></li>
<li>
<a class="dropdown-item"
href="{% url 'admin:index' %}"
hx-boost="false"
data-tippy-placement="right"
data-tippy-content="{% translate "Only use this if you know what you're doing" %}">
{% translate 'Django Admin' %}
</a>
</li>
{% endif %}
</ul>
</li>
</ul>
<ul class="navbar-nav mb-2 mb-lg-0 gap-3">
{% get_update_check as update_check %}
{% if update_check.update_available %}
<li class="nav-item my-auto">
<a class="badge text-bg-secondary text-decoration-none cursor-pointer" href="https://github.com/eitchtee/WYGIWYH/releases/latest" target="_blank"><i class="fa-solid fa-circle-info fa-fw me-2"></i>v.{{ update_check.latest_version }} {% translate 'is available' %}!</a>
</li>
{% endif %}
<li class="nav-item">
<div class="nav-link lg:text-2xl! cursor-pointer"
data-tippy-placement="left" data-tippy-content="{% trans "Calculator" %}"
_="on click trigger show on #calculator">
<i class="fa-solid fa-calculator"></i>
<span class="d-lg-none d-inline">{% trans "Calculator" %}</span>
</div>
</li>
<li class="w-100">{% include 'includes/navbar/user_menu.html' %}</li>
</ul>
</div>
</div>
</nav>

View File

@@ -135,138 +135,105 @@
<c-components.sidebar-menu-header title=""></c-components.sidebar-menu-header>
<div role="button"
data-bs-toggle="collapse"
data-bs-target="#collapsible-panel"
aria-expanded="false"
aria-controls="collapsible-panel"
class="text-xs flex items-center no-underline ps-3 p-2 rounded-box sidebar-item cursor-pointer {% active_link views='tags_index||entities_index||categories_index||accounts_index||account_groups_index||currencies_index||exchange_rates_index||rules_index||import_profiles_index||automatic_exchange_rates_index||export_index||users_index' css_class="sidebar-active" %}">
<i class="fa-solid fa-toolbox fa-fw"></i>
<span class="ml-3 font-medium lg:group-hover:truncate lg:group-focus:truncate lg:group-hover:text-ellipsis lg:group-focus:text-ellipsis">
{% translate 'Management' %}
</span>
<i class="fa-solid fa-chevron-right fa-fw ml-auto pe-2"></i>
</div>
<c-components.sidebar-collapsible-panel
title="{% translate 'Management' %}"
icon="fa-solid fa-toolbox"
active="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">
<c-components.sidebar-menu-header title="{% translate 'Transactions' %}"></c-components.sidebar-menu-header>
<c-components.sidebar-menu-item
title="{% translate 'Categories' %}"
url='categories_index'
active="categories_index"
icon="fa-solid fa-icons">
</c-components.sidebar-menu-item>
<c-components.sidebar-menu-item
title="{% translate 'Tags' %}"
url='tags_index'
active="tags_index"
icon="fa-solid fa-hashtag">
</c-components.sidebar-menu-item>
<c-components.sidebar-menu-item
title="{% translate 'Entities' %}"
url='entities_index'
active="entities_index"
icon="fa-solid fa-user-group">
</c-components.sidebar-menu-item>
<c-components.sidebar-menu-header title="{% translate 'Accounts' %}"></c-components.sidebar-menu-header>
<c-components.sidebar-menu-item
title="{% translate 'Accounts' %}"
url='accounts_index'
active="accounts_index"
icon="fa-solid fa-wallet">
</c-components.sidebar-menu-item>
<c-components.sidebar-menu-item
title="{% translate 'Account Groups' %}"
url='account_groups_index'
active="account_groups_index"
icon="fa-solid fa-wallet">
</c-components.sidebar-menu-item>
<c-components.sidebar-menu-header title="{% translate 'Currencies' %}"></c-components.sidebar-menu-header>
<c-components.sidebar-menu-item
title="{% translate 'Currencies' %}"
url='currencies_index'
active="currencies_index"
icon="fa-solid fa-coins">
</c-components.sidebar-menu-item>
<c-components.sidebar-menu-item
title="{% translate 'Exchange Rates' %}"
url='exchange_rates_index'
active="exchange_rates_index"
icon="fa-solid fa-right-left">
</c-components.sidebar-menu-item>
<c-components.sidebar-menu-header title="{% translate 'Automation' %}"></c-components.sidebar-menu-header>
<c-components.sidebar-menu-item
title="{% translate 'Rules' %}"
url='rules_index'
active="rules_index"
icon="fa-solid fa-pen-ruler">
</c-components.sidebar-menu-item>
<c-components.sidebar-menu-item
title="{% translate 'Import' %}"
url='import_profiles_index'
active="import_profiles_index"
icon="fa-solid fa-file-import">
</c-components.sidebar-menu-item>
{% if user.is_superuser %}
<c-components.sidebar-menu-item
title="{% translate 'Export and Restore' %}"
url='export_index'
active="export_index"
icon="fa-solid fa-file-export">
</c-components.sidebar-menu-item>
{% endif %}
<c-components.sidebar-menu-item
title="{% translate 'Automatic Exchange Rates' %}"
url='automatic_exchange_rates_index'
active="automatic_exchange_rates_index"
icon="fa-solid fa-right-left">
</c-components.sidebar-menu-item>
{% if user.is_superuser %}
<c-components.sidebar-menu-header title="{% translate 'Admin' %}"></c-components.sidebar-menu-header>
<c-components.sidebar-menu-item
title="{% translate 'Users' %}"
url='users_index'
active="users_index"
icon="fa-solid fa-users">
</c-components.sidebar-menu-item>
<c-components.sidebar-menu-url-item
title="{% translate 'Django Admin' %}"
tooltip="{% translate "Only use this if you know what you're doing" %}"
url='/admin/'
icon="fa-solid fa-screwdriver-wrench">
</c-components.sidebar-menu-url-item>
{% endif %}
</c-components.sidebar-collapsible-panel>
</ul>
<div class="mt-auto p-2 w-full">
<div id="collapsible-panel"
class="bs collapse p-0 absolute bottom-0 left-0 w-full z-30 max-h-dvh {% active_link views='tags_index||entities_index||categories_index||accounts_index||account_groups_index||currencies_index||exchange_rates_index||rules_index||import_profiles_index||automatic_exchange_rates_index||export_index||users_index' css_class="show" %}">
<div class="h-dvh bg-base-300 flex flex-col">
<div
class="items-center p-4 border-b border-base-content/10 sidebar-submenu-header text-base-content">
<div class="flex items-center sidebar-submenu-title">
<i class="fa-solid fa-toolbox fa-fw lg:group-hover:me-2 me-2 lg:me-0"></i>
<h5 class="text-lg font-semibold text-base-content m-0">
{% trans 'Management' %}
</h5>
</div>
<button type="button" class="btn btn-ghost btn-sm btn-circle" aria-label="{% trans 'Close' %}"
data-bs-toggle="collapse"
data-bs-target="#collapsible-panel"
aria-expanded="true"
aria-controls="collapsible-panel">
<i class="fa-solid fa-xmark"></i>
</button>
</div>
<ul class="sidebar-item-list list-none p-3 flex flex-col gap-1 whitespace-nowrap lg:group-hover:animate-[disable-pointer-events] overflow-y-auto lg:overflow-y-hidden lg:hover:overflow-y-auto overflow-x-hidden"
style="animation-duration: 100ms">
<c-components.sidebar-menu-header title="{% translate 'Transactions' %}"></c-components.sidebar-menu-header>
<c-components.sidebar-menu-item
title="{% translate 'Categories' %}"
url='categories_index'
active="categories_index"
icon="fa-solid fa-icons">
</c-components.sidebar-menu-item>
<c-components.sidebar-menu-item
title="{% translate 'Tags' %}"
url='tags_index'
active="tags_index"
icon="fa-solid fa-hashtag">
</c-components.sidebar-menu-item>
<c-components.sidebar-menu-item
title="{% translate 'Entities' %}"
url='entities_index'
active="entities_index"
icon="fa-solid fa-user-group">
</c-components.sidebar-menu-item>
<c-components.sidebar-menu-header title="{% translate 'Accounts' %}"></c-components.sidebar-menu-header>
<c-components.sidebar-menu-item
title="{% translate 'Accounts' %}"
url='accounts_index'
active="accounts_index"
icon="fa-solid fa-wallet">
</c-components.sidebar-menu-item>
<c-components.sidebar-menu-item
title="{% translate 'Account Groups' %}"
url='account_groups_index'
active="account_groups_index"
icon="fa-solid fa-wallet">
</c-components.sidebar-menu-item>
<c-components.sidebar-menu-header title="{% translate 'Currencies' %}"></c-components.sidebar-menu-header>
<c-components.sidebar-menu-item
title="{% translate 'Currencies' %}"
url='currencies_index'
active="currencies_index"
icon="fa-solid fa-coins">
</c-components.sidebar-menu-item>
<c-components.sidebar-menu-item
title="{% translate 'Exchange Rates' %}"
url='exchange_rates_index'
active="exchange_rates_index"
icon="fa-solid fa-right-left">
</c-components.sidebar-menu-item>
<c-components.sidebar-menu-header title="{% translate 'Automation' %}"></c-components.sidebar-menu-header>
<c-components.sidebar-menu-item
title="{% translate 'Rules' %}"
url='rules_index'
active="rules_index"
icon="fa-solid fa-pen-ruler">
</c-components.sidebar-menu-item>
<c-components.sidebar-menu-item
title="{% translate 'Import' %}"
url='import_profiles_index'
active="import_profiles_index"
icon="fa-solid fa-file-import">
</c-components.sidebar-menu-item>
{% if user.is_superuser %}
<c-components.sidebar-menu-item
title="{% translate 'Export and Restore' %}"
url='export_index'
active="export_index"
icon="fa-solid fa-file-export">
</c-components.sidebar-menu-item>
{% endif %}
<c-components.sidebar-menu-item
title="{% translate 'Automatic Exchange Rates' %}"
url='automatic_exchange_rates_index'
active="automatic_exchange_rates_index"
icon="fa-solid fa-right-left">
</c-components.sidebar-menu-item>
{% if user.is_superuser %}
<c-components.sidebar-menu-header title="{% translate 'Admin' %}"></c-components.sidebar-menu-header>
<c-components.sidebar-menu-item
title="{% translate 'Users' %}"
url='users_index'
active="users_index"
icon="fa-solid fa-users">
</c-components.sidebar-menu-item>
<c-components.sidebar-menu-url-item
title="{% translate 'Django Admin' %}"
tooltip="{% translate "Only use this if you know what you're doing" %}"
url='/admin/'
icon="fa-solid fa-screwdriver-wrench">
</c-components.sidebar-menu-url-item>
{% endif %}
</ul>
</div>
</div>
{% get_update_check as update_check %}
{% if update_check.update_available %}
<div class="my-3 sidebar-item">

View File

@@ -5,33 +5,19 @@
<div id="transactions-list">
{% for x in transactions_by_date %}
<div id="{{ x.grouper|slugify }}" class="transactions-divider"
_="on htmx:afterSwap from #transactions if sessionStorage.getItem(my id) is null then sessionStorage.setItem(my id, 'true')">
x-data="{ open: sessionStorage.getItem('{{ x.grouper|slugify }}') !== 'false' }"
x-init="if (sessionStorage.getItem('{{ x.grouper|slugify }}') === null) sessionStorage.setItem('{{ x.grouper|slugify }}', 'true')">
<div class="mt-3 mb-1 w-full border-b border-b-base-content/30 transactions-divider-title cursor-pointer">
<a class="no-underline inline-block w-full"
role="button"
data-bs-toggle="collapse"
data-bs-target="#c-{{ x.grouper|slugify }}-collapse"
id="c-{{ x.grouper|slugify }}-collapsible"
aria-expanded="false"
aria-controls="c-{{ x.grouper|slugify }}-collapse">
@click="open = !open; sessionStorage.setItem('{{ x.grouper|slugify }}', open)"
:aria-expanded="open">
{{ x.grouper }}
</a>
</div>
<div class="bs collapse transactions-divider-collapse overflow-visible isolation-auto" id="c-{{ x.grouper|slugify }}-collapse"
_="on shown.bs.collapse sessionStorage.setItem(the closest parent @id, 'true')
on hidden.bs.collapse sessionStorage.setItem(the closest parent @id, 'false')
on htmx:afterSettle from #transactions or toggle
set state to sessionStorage.getItem(the closest parent @id)
if state is 'true' or state is null
add .show to me
set @aria-expanded of #c-{{ x.grouper|slugify }}-collapsible to true
else
remove .show from me
set @aria-expanded of #c-{{ x.grouper|slugify }}-collapsible to false
end
on show
add .show to me
set @aria-expanded of #c-{{ x.grouper|slugify }}-collapsible to true">
<div class="transactions-divider-collapse overflow-visible isolation-auto"
x-show="open"
x-collapse>
<div class="flex flex-col">
{% for transaction in x.list %}
<c-transaction.item

View File

@@ -89,7 +89,7 @@
</div>
<div class="col-12 lg:col-8 lg:order-first! order-last!">
<div class="my-3">
<div class="my-3" x-data="{ filterOpen: false }" hx-preserve id="filter-container">
{# Hidden select to hold the order value and preserve the original update trigger #}
<select name="order" id="order" class="d-none" _="on change trigger updated on window">
<option value="default" {% if order == 'default' %}selected{% endif %}>{% translate 'Default' %}</option>
@@ -101,8 +101,8 @@
<div class="join w-full">
<button class="btn btn-secondary join-item relative" type="button"
data-bs-toggle="collapse" data-bs-target="#collapse-filter"
aria-expanded="false" aria-controls="collapse-filter" id="filter-button" hx-preserve
@click="filterOpen = !filterOpen"
:aria-expanded="filterOpen" id="filter-button"
title="{% translate 'Filter transactions' %}">
<i class="fa-solid fa-filter fa-fw"></i>
</button>
@@ -113,7 +113,6 @@
<input type="search"
class="input input-bordered join-item flex-1"
placeholder="{% translate 'Search' %}"
hx-preserve
id="quick-search"
_="on input or search or htmx:afterSwap from window
if my value is empty
@@ -165,7 +164,7 @@
</div>
{# Filter transactions form #}
<div class="bs collapse z-1" id="collapse-filter" hx-preserve>
<div class="z-1" x-show="filterOpen" x-collapse>
<div class="card card-body bg-base-200 mt-2">
<div class="text-right">
<button class="btn btn-outline btn-error btn-sm w-fit"

View File

@@ -5,33 +5,19 @@
<div id="transactions-list" class="show-loading">
{% for x in transactions_by_date %}
<div id="{{ x.grouper|slugify }}" class="transactions-divider"
_="on htmx:afterSwap from #transactions if sessionStorage.getItem(my id) is null then sessionStorage.setItem(my id, 'true')">
x-data="{ open: sessionStorage.getItem('{{ x.grouper|slugify }}') !== 'false' }"
x-init="if (sessionStorage.getItem('{{ x.grouper|slugify }}') === null) sessionStorage.setItem('{{ x.grouper|slugify }}', 'true')">
<div class="mt-3 mb-1 w-full border-b border-b-base-content/30 transactions-divider-title cursor-pointer">
<a class="no-underline inline-block w-full"
role="button"
data-bs-toggle="collapse"
data-bs-target="#c-{{ x.grouper|slugify }}-collapse"
id="c-{{ x.grouper|slugify }}-collapsible"
aria-expanded="false"
aria-controls="c-{{ x.grouper|slugify }}-collapse">
@click="open = !open; sessionStorage.setItem('{{ x.grouper|slugify }}', open)"
:aria-expanded="open">
{{ x.grouper }}
</a>
</div>
<div class="bs collapse transactions-divider-collapse overflow-visible isolation-auto" id="c-{{ x.grouper|slugify }}-collapse"
_="on shown.bs.collapse sessionStorage.setItem(the closest parent @id, 'true')
on hidden.bs.collapse sessionStorage.setItem(the closest parent @id, 'false')
on htmx:afterSettle from #transactions or toggle
set state to sessionStorage.getItem(the closest parent @id)
if state is 'true' or state is null
add .show to me
set @aria-expanded of #c-{{ x.grouper|slugify }}-collapsible to true
else
remove .show from me
set @aria-expanded of #c-{{ x.grouper|slugify }}-collapsible to false
end
on show
add .show to me
set @aria-expanded of #c-{{ x.grouper|slugify }}-collapsible to true">
<div class="transactions-divider-collapse overflow-visible isolation-auto"
x-show="open"
x-collapse>
<div class="flex flex-col">
{% for transaction in x.list %}
<c-transaction.item

View File

@@ -41,7 +41,7 @@
</div>
<div class="col-12 lg:col-8 lg:order-first! order-last!">
<div>
<div x-data="{ filterOpen: false }" hx-preserve id="filter-container">
{# Hidden select to hold the order value and preserve the original update trigger #}
<select name="order" id="order" class="d-none" _="on change trigger updated on window">
<option value="default" {% if order == 'default' %}selected{% endif %}>{% translate 'Default' %}</option>
@@ -53,8 +53,8 @@
<div class="join w-full">
<button class="btn btn-secondary join-item relative" type="button"
data-bs-toggle="collapse" data-bs-target="#collapse-filter"
aria-expanded="false" aria-controls="collapse-filter" id="filter-button" hx-preserve
@click="filterOpen = !filterOpen"
:aria-expanded="filterOpen" id="filter-button"
title="{% translate 'Filter transactions' %}">
<i class="fa-solid fa-filter fa-fw"></i>
</button>
@@ -65,7 +65,6 @@
<input type="search"
class="input input-bordered join-item flex-1"
placeholder="{% translate 'Search' %}"
hx-preserve
id="quick-search"
_="on input or search or htmx:afterSwap from window
if my value is empty
@@ -118,7 +117,7 @@
</div>
{# Filter transactions form #}
<div class="bs collapse z-1" id="collapse-filter" hx-preserve>
<div class="z-1" x-show="filterOpen" x-collapse>
<div class="card card-body bg-base-200 mt-2">
<div class="text-right">
<button class="btn btn-outline btn-error btn-sm w-fit"

View File

@@ -2,7 +2,6 @@ import './_tooltip.js';
import 'bootstrap/js/dist/dropdown';
import Toast from 'bootstrap/js/dist/toast';
import 'bootstrap/js/dist/dropdown';
import 'bootstrap/js/dist/collapse';
import Offcanvas from 'bootstrap/js/dist/offcanvas';
window.Offcanvas = Offcanvas;

View File

@@ -56,6 +56,22 @@
animation: slide-in-left 0.2s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
}
@keyframes slide-out-left {
0% {
transform: translateX(0);
opacity: 1;
}
100% {
transform: translateX(-100%);
opacity: 0;
}
}
.slide-out-left {
animation: slide-out-left 0.15s cubic-bezier(0.55, 0.085, 0.68, 0.53) both;
}
// HTMX Loading
@keyframes spin {
0% {

View File

@@ -6,8 +6,6 @@ $enable-transitions: true !default;
$enable-reduced-motion: true !default;
$transition-fade: opacity 0.15s linear !default;
$transition-collapse: height 0.35s ease !default;
$transition-collapse-width: width 0.35s ease !default;
// Fade transition
.fade {
@@ -22,35 +20,4 @@ $transition-collapse-width: width 0.35s ease !default;
&:not(.show) {
opacity: 0;
}
}
// // Collapse transitions
.bs.collapse {
&:not(.show) {
display: none;
}
}
.bs.collapsing {
height: 0;
overflow: hidden;
transition: $transition-collapse;
@if $enable-reduced-motion {
@media (prefers-reduced-motion: reduce) {
transition: none;
}
}
&.collapse-horizontal {
width: 0;
height: auto;
transition: $transition-collapse-width;
@if $enable-reduced-motion {
@media (prefers-reduced-motion: reduce) {
transition: none;
}
}
}
}

View File

@@ -45,14 +45,6 @@ select {
font-size: 14px;
}
[data-bs-toggle="collapse"] .fa-chevron-down {
transition: transform 0.25s ease-in-out;
}
[data-bs-toggle="collapse"][aria-expanded="true"] .fa-chevron-down {
transform: rotate(-180deg);
}
div:where(.swal2-container) {
z-index: 1101 !important;
}
@@ -85,4 +77,4 @@ div:where(.swal2-container) {
[x-cloak] {
display: none !important;
}
}

View File

@@ -309,13 +309,15 @@
}
.sidebar-fixed {
/* Sets the fixed, expanded width for the container */
@apply lg:w-[17%] transition-all duration-100;
/* Sets the fixed, expanded width for the container.
Using fixed rem width instead of percentage to prevent width inconsistencies
caused by scrollbar presence affecting viewport width calculations. */
@apply lg:w-80 transition-all duration-100;
}
.sidebar-fixed #sidebar {
/* Sets the fixed, expanded width for the inner navigation */
@apply lg:w-[17%] transition-all duration-100;
@apply lg:w-80 transition-all duration-100;
}
.sidebar-fixed .sidebar-item-list {
@@ -324,9 +326,7 @@
.sidebar-fixed + main {
/* Adjusts the main content margin to account for the expanded sidebar */
@apply lg:ml-[17%];
/* Using 16vw to account for padding/margins */
@apply lg:ml-80;
}
.sidebar-fixed .sidebar-item {