added project delete + changed to list template

This commit is contained in:
Louis Heredero 2025-02-02 23:01:17 +01:00
parent 35d5a81e6f
commit 092812b9b7
Signed by: HEL
GPG Key ID: 8D83DE470F8544E7
8 changed files with 74 additions and 44 deletions

View File

@ -25,15 +25,16 @@ register_converter(DateConverter, "date")
urlpatterns = [ urlpatterns = [
path("", views.dashboard_view, name="dashboard"), path("", views.dashboard_view, name="dashboard"),
path("import/", views.import_view, name="import"), path("import/", views.import_view, name="import"),
path("projects/", views.projects_view, name="projects"), path("projects/", views.ProjectsView.as_view(), name="projects"),
path("parents/", views.ParentsView.as_view(), name="parents"), path("parents/", views.ParentsView.as_view(), name="parents"),
path("table/<date:start_date>/<date:end_date>/", views.get_table_data, name="table_data"), path("table/<date:start_date>/<date:end_date>/", views.get_table_data, name="table_data"),
path("table/", views.table_view, name="table"), path("table/", views.table_view, name="table"),
path("parents/new/", views.new_parent_view, name="new_parent"), path("parents/new/", views.new_parent_view, name="new_parent"),
path("parents/<int:id>/on_delete/", views.parent_on_delete_view, name="parent_on_delete"), path("parents/<int:id>/on_delete/", views.parent_on_delete_view, name="parent_on_delete"),
path("parents/<int:id>/", views.parent_view, name="parent"), path("parents/<int:id>/", views.parent_view, name="parent"),
path("projects/<int:id>/on_delete/", views.project_on_delete_view, name="project_on_delete"),
path("projects/<int:id>/set_parent/", views.set_parent, name="set_parent"),
path("projects/<int:id>/", views.project_view, name="project"), path("projects/<int:id>/", views.project_view, name="project"),
path("projects/<int:id>/set_parent", views.set_parent, name="set_parent"),
path("stats/by-month/<int:year>/<int:month>/", views.get_stats_by_month, name="stats_by_month"), path("stats/by-month/<int:year>/<int:month>/", views.get_stats_by_month, name="stats_by_month"),
path("stats/between/<date:start_date>/<date:end_date>/", views.get_stats_between, name="stats_between"), path("stats/between/<date:start_date>/<date:end_date>/", views.get_stats_between, name="stats_between"),
path("clockings/<date:date>/", views.set_clocking, name="set_clocking") path("clockings/<date:date>/", views.set_clocking, name="set_clocking")

View File

@ -82,6 +82,7 @@ main {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
padding: 2em; padding: 2em;
overflow-y: auto;
} }
button, input, select { button, input, select {

View File

@ -5,6 +5,7 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 1em; gap: 1em;
overflow-y: auto;
} }
.list-header { .list-header {
@ -22,6 +23,7 @@
gap: 0.8em; gap: 0.8em;
flex-direction: column; flex-direction: column;
padding: 0; padding: 0;
overflow-y: auto;
} }
.list li { .list li {

View File

@ -33,7 +33,7 @@ window.addEventListener("load", () => {
document.querySelectorAll(".list li").forEach(row => { document.querySelectorAll(".list li").forEach(row => {
let id = row.dataset.id let id = row.dataset.id
row.querySelector("button.edit").addEventListener("click", () => { row.querySelector("button.edit")?.addEventListener("click", () => {
window.location.href = `${id}/` window.location.href = `${id}/`
}) })

View File

@ -1,4 +1,8 @@
.productive {
box-shadow: 0.2em 0 0 var(--accent) inset;
}
/*
.projects { .projects {
width: 100%; width: 100%;
max-width: 40em; max-width: 40em;
@ -22,3 +26,4 @@
.projects tbody tr:nth-child(even) { .projects tbody tr:nth-child(even) {
background-color: var(--dark2); background-color: var(--dark2);
} }
*/

View File

@ -1,5 +1,16 @@
onBeforeDelete = async row => {
await req(`${row.dataset.id}/on_delete/`).then(res => {
return res.json()
}).then(res => {
if (res.status === "success") {
let popup = document.getElementById("delete-popup")
popup.querySelector(".task-count").innerText = res.tasks
}
})
}
window.addEventListener("load", () => { window.addEventListener("load", () => {
document.querySelectorAll(".projects tbody tr").forEach(row => { document.querySelectorAll(".list li").forEach(row => {
let id = row.dataset.id let id = row.dataset.id
let selector = row.querySelector(".parent-sel") let selector = row.querySelector(".parent-sel")
selector.addEventListener("change", () => { selector.addEventListener("change", () => {
@ -10,9 +21,5 @@ window.addEventListener("load", () => {
body: fd body: fd
}) })
}) })
row.querySelector("button.edit").addEventListener("click", () => {
window.location.href = `${id}/`
})
}) })
}) })

View File

@ -59,6 +59,15 @@ def parent_on_delete_view(request, id):
"tasks": tasks "tasks": tasks
}) })
def project_on_delete_view(request, id):
project = get_object_or_404(Project, id=id)
tasks = project.task_set.count()
return JsonResponse({
"status": "success",
"tasks": tasks
})
def new_parent_view(request): def new_parent_view(request):
context = { context = {
"class": "parent" "class": "parent"
@ -72,6 +81,11 @@ def new_parent_view(request):
def project_view(request, id): def project_view(request, id):
project = get_object_or_404(Project, id=id) project = get_object_or_404(Project, id=id)
if request.method == "DELETE":
project.delete()
return JsonResponse({"status": "success"})
context = { context = {
"class": "project", "class": "project",
"id": id "id": id
@ -88,7 +102,7 @@ def table_view(request):
@require_POST @require_POST
def set_parent(request, id): def set_parent(request, id):
project = get_object_or_404(Project, id=id) project = get_object_or_404(Project, id=id)
parent_id = request.POST.get("parent_id") parent_id = request.POST.get("parent_id") or None
try: try:
parent = Parent.objects.get(id=parent_id) parent = Parent.objects.get(id=parent_id)
except Parent.DoesNotExist: except Parent.DoesNotExist:
@ -181,6 +195,16 @@ class ParentsView(generic.ListView):
template_name = "parents.html" template_name = "parents.html"
context_object_name = "elements" context_object_name = "elements"
class ProjectsView(generic.ListView):
model = Project
template_name = "projects.html"
context_object_name = "elements"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["parents"] = Parent.objects.all()
return context
def get_table_data(request, start_date: datetime.date, end_date: datetime.date): def get_table_data(request, start_date: datetime.date, end_date: datetime.date):
end_date = end_date + timedelta(days=1) end_date = end_date + timedelta(days=1)

View File

@ -1,39 +1,29 @@
{% extends "base.html" %} {% extends "list.html" %}
{% load static %} {% load static %}
{% block title %}Projects{% endblock %} {% block title %}Projects{% endblock %}
{% block head %} {% block extra-head %}
<link rel="stylesheet" href="{% static "projects.css" %}"> <link rel="stylesheet" href="{% static "projects.css" %}">
<script src="{% static "projects.js" %}"></script> <script src="{% static "projects.js" %}"></script>
{% endblock %} {% endblock %}
{% block footer %}{% endblock %} {% block extra-class %}{% if element.parent.is_productive %}productive{% endif %}{% endblock %}
{% block main %} {% block element-name %}{{ element.name }}{% endblock %}
{% csrf_token %} {% block element %}
<table class="projects"> <div class="name">{{ element.name }}</div>
<thead> {% endblock %}
<tr> {% block actions %}
<th>Project</th>
<th>Parent</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for project in projects %}
<tr data-id="{{ project.id }}">
<td>{{ project.name }}</td>
<td>
<select class="parent-sel"> <select class="parent-sel">
<option value=""></option> <option value=""></option>
{% for parent in parents %} {% for parent in parents %}
<option value="{{ parent.id }}" {% if project.parent.id == parent.id %}selected{% endif %}>{{ parent.name }}</option> <option value="{{ parent.id }}" {% if element.parent.id == parent.id %}selected{% endif %}>{{ parent.name }}</option>
{% endfor %} {% endfor %}
</select> </select>
</td>
<td>
<button class="edit">Edit</button> <button class="edit">Edit</button>
<button class="delete">Delete</button> <button class="delete">Delete</button>
</td> {% endblock %}
</tr> {% block delete-desc %}
{% endfor %} Are sure you want to delete <span class="elmt-name"></span> ?
</tbody> This action is <u>IRREVERSIBLE</u> ! By deleting this element, you will also delete:
</table> <ul>
<li><span class="task-count"></span> task imputation(s)</li>
</ul>
{% endblock %} {% endblock %}