Compare commits

..

7 Commits
0.1.8 ... 0.1.9

Author SHA1 Message Date
Herculino Trotta
6f69f15474 Merge pull request #20
feat: archived tabs for categories, tags and entities
2025-01-05 01:46:01 -03:00
Herculino Trotta
905e80cffe fix: overflowing empty message 2025-01-05 01:45:11 -03:00
Herculino Trotta
baae6bb96a feat(entities): add tab to show archived entities 2025-01-05 01:43:24 -03:00
Herculino Trotta
f5132e24bd feat(tags): add tab to show archived tags 2025-01-05 01:36:30 -03:00
Herculino Trotta
41303f39a0 fix: typo 2025-01-05 01:35:34 -03:00
Herculino Trotta
0fc8b0ee49 feat(tags): add tab to show archived tags 2025-01-05 01:35:25 -03:00
Herculino Trotta
037014d024 feat(categories): add tab to show archived categories 2025-01-05 01:22:14 -03:00
13 changed files with 302 additions and 142 deletions

View File

@@ -53,6 +53,8 @@ urlpatterns = [
),
path("tags/", views.tags_index, name="tags_index"),
path("tags/list/", views.tags_list, name="tags_list"),
path("tags/table/active/", views.tags_table_active, name="tags_table_active"),
path("tags/table/archived/", views.tags_table_archived, name="tags_table_archived"),
path("tags/add/", views.tag_add, name="tag_add"),
path(
"tags/<int:tag_id>/edit/",
@@ -66,6 +68,16 @@ urlpatterns = [
),
path("entities/", views.entities_index, name="entities_index"),
path("entities/list/", views.entities_list, name="entities_list"),
path(
"entities/table/active/",
views.entities_table_active,
name="entities_table_active",
),
path(
"entities/table/archived/",
views.entities_table_archived,
name="entities_table_archived",
),
path("entities/add/", views.entity_add, name="entity_add"),
path(
"entities/<int:entity_id>/edit/",
@@ -79,6 +91,16 @@ urlpatterns = [
),
path("categories/", views.categories_index, name="categories_index"),
path("categories/list/", views.categories_list, name="categories_list"),
path(
"categories/table/active/",
views.categories_table_active,
name="categories_table_active",
),
path(
"categories/table/archived/",
views.categories_table_archived,
name="categories_table_archived",
),
path("categories/add/", views.category_add, name="category_add"),
path(
"categories/<int:category_id>/edit/",

View File

@@ -25,11 +25,33 @@ def categories_index(request):
@login_required
@require_http_methods(["GET"])
def categories_list(request):
categories = TransactionCategory.objects.all().order_by("id")
return render(
request,
"categories/fragments/list.html",
{"categories": categories},
)
@only_htmx
@login_required
@require_http_methods(["GET"])
def categories_table_active(request):
categories = TransactionCategory.objects.filter(active=True).order_by("id")
return render(
request,
"categories/fragments/table.html",
{"categories": categories, "active": True},
)
@only_htmx
@login_required
@require_http_methods(["GET"])
def categories_table_archived(request):
categories = TransactionCategory.objects.filter(active=False).order_by("id")
return render(
request,
"categories/fragments/table.html",
{"categories": categories, "active": False},
)

View File

@@ -24,11 +24,33 @@ def entities_index(request):
@login_required
@require_http_methods(["GET"])
def entities_list(request):
entities = TransactionEntity.objects.all().order_by("id")
return render(
request,
"entities/fragments/list.html",
{"entities": entities},
)
@only_htmx
@login_required
@require_http_methods(["GET"])
def entities_table_active(request):
entities = TransactionEntity.objects.filter(active=True).order_by("id")
return render(
request,
"entities/fragments/table.html",
{"entities": entities, "active": True},
)
@only_htmx
@login_required
@require_http_methods(["GET"])
def entities_table_archived(request):
entities = TransactionEntity.objects.filter(active=False).order_by("id")
return render(
request,
"entities/fragments/table.html",
{"entities": entities, "active": False},
)

View File

@@ -24,11 +24,33 @@ def tags_index(request):
@login_required
@require_http_methods(["GET"])
def tags_list(request):
tags = TransactionTag.objects.all().order_by("id")
return render(
request,
"tags/fragments/list.html",
{"tags": tags},
)
@only_htmx
@login_required
@require_http_methods(["GET"])
def tags_table_active(request):
tags = TransactionTag.objects.filter(active=True).order_by("id")
return render(
request,
"tags/fragments/table.html",
{"tags": tags, "active": True},
)
@only_htmx
@login_required
@require_http_methods(["GET"])
def tags_table_archived(request):
tags = TransactionTag.objects.filter(active=False).order_by("id")
return render(
request,
"tags/fragments/table.html",
{"tags": tags, "active": False},
)

View File

@@ -15,53 +15,18 @@
</div>
<div class="card">
<div class="card-body table-responsive">
{% if categories %}
<c-config.search></c-config.search>
<table class="table table-hover">
<thead>
<tr>
<th scope="col" class="col-auto"></th>
<th scope="col" class="col">{% translate 'Name' %}</th>
<th scope="col" class="col">{% translate 'Muted' %}</th>
</tr>
</thead>
<tbody>
{% for category in categories %}
<tr class="category">
<td class="col-auto text-center">
<div class="btn-group" role="group" aria-label="{% translate 'Actions' %}">
<a class="btn btn-secondary btn-sm"
role="button"
data-bs-toggle="tooltip"
data-bs-title="{% translate "Edit" %}"
hx-get="{% url 'category_edit' category_id=category.id %}"
hx-target="#generic-offcanvas">
<i class="fa-solid fa-pencil fa-fw"></i></a>
<a class="btn btn-secondary btn-sm text-danger"
role="button"
data-bs-toggle="tooltip"
data-bs-title="{% translate "Delete" %}"
hx-delete="{% url 'category_delete' category_id=category.id %}"
hx-trigger='confirmed'
data-bypass-on-ctrl="true"
data-title="{% translate "Are you sure?" %}"
data-text="{% translate "You won't be able to revert this!" %}"
data-confirm-text="{% translate "Yes, delete it!" %}"
_="install prompt_swal"><i class="fa-solid fa-trash fa-fw"></i></a>
</div>
</td>
<td class="col">{{ category.name }}</td>
<td class="col">
{% if category.mute %}<i class="fa-solid fa-check text-success"></i>{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<c-msg.empty title="{% translate "No categories" %}" remove-padding></c-msg.empty>
{% endif %}
<div class="card-header">
<ul class="nav nav-pills card-header-pills" id="myTab" role="tablist">
<li class="nav-item" role="presentation">
<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>
</li>
<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 class="card-body">
<div id="categories-table"></div>
</div>
</div>
</div>

View File

@@ -0,0 +1,59 @@
{% load i18n %}
{% if active %}
<div class="show-loading" hx-get="{% url 'categories_table_active' %}" hx-trigger="updated from:window"
hx-swap="outerHTML">
{% else %}
<div class="show-loading" hx-get="{% url 'categories_table_archived' %}" hx-trigger="updated from:window"
hx-swap="outerHTML">
{% endif %}
{% if categories %}
<div class="table-responsive">
<c-config.search></c-config.search>
<table class="table table-hover">
<thead>
<tr>
<th scope="col" class="col-auto"></th>
<th scope="col" class="col">{% translate 'Name' %}</th>
<th scope="col" class="col">{% translate 'Muted' %}</th>
</tr>
</thead>
<tbody>
{% for category in categories %}
<tr class="category">
<td class="col-auto text-center">
<div class="btn-group" role="group" aria-label="{% translate 'Actions' %}">
<a class="btn btn-secondary btn-sm"
role="button"
data-bs-toggle="tooltip"
hx-swap="innerHTML"
data-bs-title="{% translate "Edit" %}"
hx-get="{% url 'category_edit' category_id=category.id %}"
hx-target="#generic-offcanvas">
<i class="fa-solid fa-pencil fa-fw"></i></a>
<a class="btn btn-secondary btn-sm text-danger"
role="button"
data-bs-toggle="tooltip"
data-bs-title="{% translate "Delete" %}"
hx-delete="{% url 'category_delete' category_id=category.id %}"
hx-trigger='confirmed'
hx-swap="innerHTML"
data-bypass-on-ctrl="true"
data-title="{% translate "Are you sure?" %}"
data-text="{% translate "You won't be able to revert this!" %}"
data-confirm-text="{% translate "Yes, delete it!" %}"
_="install prompt_swal"><i class="fa-solid fa-trash fa-fw"></i></a>
</div>
</td>
<td class="col">{{ category.name }}</td>
<td class="col">
{% if category.mute %}<i class="fa-solid fa-check text-success"></i>{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<c-msg.empty title="{% translate "No categories" %}" remove-padding></c-msg.empty>
{% endif %}
</div>

View File

@@ -4,5 +4,5 @@
{% block title %}{% translate 'Categories' %}{% endblock %}
{% block content %}
<div hx-get="{% url 'categories_list' %}" hx-trigger="load, updated from:window" class="show-loading"></div>
<div hx-get="{% url 'categories_list' %}" hx-trigger="load" class="show-loading"></div>
{% endblock %}

View File

@@ -15,49 +15,18 @@
</div>
<div class="card">
<div class="card-body table-responsive">
{% if entities %}
<c-config.search></c-config.search>
<table class="table table-hover">
<thead>
<tr>
<th scope="col" class="col-auto"></th>
<th scope="col" class="col">{% translate 'Name' %}</th>
</tr>
</thead>
<tbody>
{% for entity in entities %}
<tr class="entity">
<td class="col-auto">
<div class="btn-group" role="group" aria-label="{% translate 'Actions' %}">
<a class="btn btn-secondary btn-sm"
role="button"
data-bs-toggle="tooltip"
data-bs-title="{% translate "Edit" %}"
hx-get="{% url 'entity_edit' entity_id=entity.id %}"
hx-target="#generic-offcanvas">
<i class="fa-solid fa-pencil fa-fw"></i></a>
<a class="btn btn-secondary btn-sm text-danger"
role="button"
data-bs-toggle="tooltip"
data-bs-title="{% translate "Delete" %}"
hx-delete="{% url 'entity_delete' entity_id=entity.id %}"
hx-trigger='confirmed'
data-bypass-on-ctrl="true"
data-title="{% translate "Are you sure?" %}"
data-text="{% translate "You won't be able to revert this!" %}"
data-confirm-text="{% translate "Yes, delete it!" %}"
_="install prompt_swal"><i class="fa-solid fa-trash fa-fw"></i></a>
</div>
</td>
<td class="col">{{ entity.name }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<c-msg.empty title="{% translate "No entities" %}" remove-padding></c-msg.empty>
{% endif %}
<div class="card-header">
<ul class="nav nav-pills card-header-pills" id="myTab" role="tablist">
<li class="nav-item" role="presentation">
<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>
</li>
<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 class="card-body">
<div id="entities-table"></div>
</div>
</div>
</div>

View File

@@ -0,0 +1,55 @@
{% load i18n %}
{% if active %}
<div class="show-loading" hx-get="{% url 'entities_table_active' %}" hx-trigger="updated from:window"
hx-swap="outerHTML">
{% else %}
<div class="show-loading" hx-get="{% url 'entities_table_archived' %}" hx-trigger="updated from:window"
hx-swap="outerHTML">
{% endif %}
{% if entities %}
<div class="table-responsive">
<c-config.search></c-config.search>
<table class="table table-hover">
<thead>
<tr>
<th scope="col" class="col-auto"></th>
<th scope="col" class="col">{% translate 'Name' %}</th>
</tr>
</thead>
<tbody>
{% for entity in entities %}
<tr class="entity">
<td class="col-auto">
<div class="btn-group" role="group" aria-label="{% translate 'Actions' %}">
<a class="btn btn-secondary btn-sm"
role="button"
hx-swap="innerHTML"
data-bs-toggle="tooltip"
data-bs-title="{% translate "Edit" %}"
hx-get="{% url 'entity_edit' entity_id=entity.id %}"
hx-target="#generic-offcanvas">
<i class="fa-solid fa-pencil fa-fw"></i></a>
<a class="btn btn-secondary btn-sm text-danger"
role="button"
hx-swap="innerHTML"
data-bs-toggle="tooltip"
data-bs-title="{% translate "Delete" %}"
hx-delete="{% url 'entity_delete' entity_id=entity.id %}"
hx-trigger='confirmed'
data-bypass-on-ctrl="true"
data-title="{% translate "Are you sure?" %}"
data-text="{% translate "You won't be able to revert this!" %}"
data-confirm-text="{% translate "Yes, delete it!" %}"
_="install prompt_swal"><i class="fa-solid fa-trash fa-fw"></i></a>
</div>
</td>
<td class="col">{{ entity.name }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<c-msg.empty title="{% translate "No entities" %}" remove-padding></c-msg.empty>
{% endif %}
</div>

View File

@@ -4,5 +4,5 @@
{% block title %}{% translate 'Entities' %}{% endblock %}
{% block content %}
<div hx-get="{% url 'entities_list' %}" hx-trigger="load, updated from:window" class="show-loading"></div>
<div hx-get="{% url 'entities_list' %}" hx-trigger="load" class="show-loading"></div>
{% endblock %}

View File

@@ -15,49 +15,18 @@
</div>
<div class="card">
<div class="card-body table-responsive">
{% if tags %}
<c-config.search></c-config.search>
<table class="table table-hover">
<thead>
<tr>
<th scope="col" class="col-auto"></th>
<th scope="col" class="col">{% translate 'Name' %}</th>
</tr>
</thead>
<tbody>
{% for tag in tags %}
<tr class="tag">
<td class="col-auto">
<div class="btn-group" role="group" aria-label="{% translate 'Actions' %}">
<a class="btn btn-secondary btn-sm"
role="button"
data-bs-toggle="tooltip"
data-bs-title="{% translate "Edit" %}"
hx-get="{% url 'tag_edit' tag_id=tag.id %}"
hx-target="#generic-offcanvas">
<i class="fa-solid fa-pencil fa-fw"></i></a>
<a class="btn btn-secondary btn-sm text-danger"
role="button"
data-bs-toggle="tooltip"
data-bs-title="{% translate "Delete" %}"
hx-delete="{% url 'tag_delete' tag_id=tag.id %}"
hx-trigger='confirmed'
data-bypass-on-ctrl="true"
data-title="{% translate "Are you sure?" %}"
data-text="{% translate "You won't be able to revert this!" %}"
data-confirm-text="{% translate "Yes, delete it!" %}"
_="install prompt_swal"><i class="fa-solid fa-trash fa-fw"></i></a>
</div>
</td>
<td class="col">{{ tag.name }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<c-msg.empty title="{% translate "No tags" %}" remove-padding></c-msg.empty>
{% endif %}
<div class="card-header">
<ul class="nav nav-pills card-header-pills" id="myTab" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" data-bs-toggle="tab" type="button" role="tab" aria-selected="true" hx-get="{% url 'tags_table_active' %}" hx-trigger="load, click" hx-target="#tags-table">{% translate 'Active' %}</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" hx-get="{% url 'tags_table_archived' %}" hx-target="#tags-table" data-bs-toggle="tab" type="button" role="tab" aria-selected="false">{% translate 'Archived' %}</button>
</li>
</ul>
</div>
<div class="card-body">
<div id="tags-table"></div>
</div>
</div>
</div>

View File

@@ -0,0 +1,55 @@
{% load i18n %}
{% if active %}
<div class="show-loading" hx-get="{% url 'tags_table_active' %}" hx-trigger="updated from:window"
hx-swap="outerHTML">
{% else %}
<div class="show-loading" hx-get="{% url 'tags_table_archived' %}" hx-trigger="updated from:window"
hx-swap="outerHTML">
{% endif %}
{% if tags %}
<div class="table-responsive">
<c-config.search></c-config.search>
<table class="table table-hover">
<thead>
<tr>
<th scope="col" class="col-auto"></th>
<th scope="col" class="col">{% translate 'Name' %}</th>
</tr>
</thead>
<tbody>
{% for tag in tags %}
<tr class="tag">
<td class="col-auto">
<div class="btn-group" role="group" aria-label="{% translate 'Actions' %}">
<a class="btn btn-secondary btn-sm"
role="button"
hx-swap="innerHTML"
data-bs-toggle="tooltip"
data-bs-title="{% translate "Edit" %}"
hx-get="{% url 'tag_edit' tag_id=tag.id %}"
hx-target="#generic-offcanvas">
<i class="fa-solid fa-pencil fa-fw"></i></a>
<a class="btn btn-secondary btn-sm text-danger"
role="button"
data-bs-toggle="tooltip"
hx-swap="innerHTML"
data-bs-title="{% translate "Delete" %}"
hx-delete="{% url 'tag_delete' tag_id=tag.id %}"
hx-trigger='confirmed'
data-bypass-on-ctrl="true"
data-title="{% translate "Are you sure?" %}"
data-text="{% translate "You won't be able to revert this!" %}"
data-confirm-text="{% translate "Yes, delete it!" %}"
_="install prompt_swal"><i class="fa-solid fa-trash fa-fw"></i></a>
</div>
</td>
<td class="col">{{ tag.name }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<c-msg.empty title="{% translate "No tags" %}" remove-padding></c-msg.empty>
{% endif %}
</div>

View File

@@ -4,5 +4,5 @@
{% block title %}{% translate 'Tags' %}{% endblock %}
{% block content %}
<div hx-get="{% url 'tags_list' %}" hx-trigger="load, updated from:window" class="show-loading"></div>
<div hx-get="{% url 'tags_list' %}" hx-trigger="load" class="show-loading"></div>
{% endblock %}