added parent delete popup + endpoint
This commit is contained in:
parent
8b0b56cb7b
commit
35d5a81e6f
@ -30,6 +30,7 @@ urlpatterns = [
|
||||
path("table/<date:start_date>/<date:end_date>/", views.get_table_data, name="table_data"),
|
||||
path("table/", views.table_view, name="table"),
|
||||
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>/", views.parent_view, name="parent"),
|
||||
path("projects/<int:id>/", views.project_view, name="project"),
|
||||
path("projects/<int:id>/set_parent", views.set_parent, name="set_parent"),
|
||||
|
@ -109,3 +109,7 @@ button, select {
|
||||
a {
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
ul {
|
||||
padding-left: 2em;
|
||||
}
|
@ -72,7 +72,7 @@ function formatPercentage(ratio) {
|
||||
return percentage + "%"
|
||||
}
|
||||
|
||||
function req(url, options) {
|
||||
function req(url, options = {}) {
|
||||
let headers = options.headers || {}
|
||||
let csrftoken = document.querySelector("input[name='csrfmiddlewaretoken']").value
|
||||
headers["X-CSRFToken"] = csrftoken
|
||||
|
@ -21,6 +21,7 @@
|
||||
display: flex;
|
||||
gap: 0.8em;
|
||||
flex-direction: column;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.list li {
|
||||
@ -35,3 +36,60 @@
|
||||
.list li .actions {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.popup {
|
||||
background-color: #00000040;
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
}
|
||||
|
||||
.popup:not(.show) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.popup .popup-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1em;
|
||||
padding: 2em;
|
||||
background-color: var(--dark1);
|
||||
border-radius: 1em;
|
||||
width: 100%;
|
||||
max-width: 40em;
|
||||
box-shadow: 0 0.2em 0.8em var(--dark3);
|
||||
}
|
||||
|
||||
.popup .popup-container .elmt-name {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.popup .popup-container .actions {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
gap: 1em;
|
||||
}
|
||||
|
||||
.popup .popup-container .actions button {
|
||||
padding: 0.4em 1.2em;
|
||||
}
|
||||
|
||||
.popup .popup-container .actions .cancel {
|
||||
background-color: var(--light2);
|
||||
}
|
||||
|
||||
.popup .popup-container .actions .cancel:hover {
|
||||
background-color: var(--light3);
|
||||
}
|
||||
|
||||
.popup .popup-container .actions .delete {
|
||||
--col: #f95f4b;
|
||||
color: var(--col);
|
||||
border-color: var(--col);
|
||||
background-color: var(--dark1);
|
||||
}
|
||||
|
||||
.popup .popup-container .actions .delete:hover {
|
||||
background-color: var(--dark2);
|
||||
}
|
@ -1,3 +1,31 @@
|
||||
function showDeletePopup(id, name) {
|
||||
let popup = document.getElementById("delete-popup")
|
||||
popup.dataset.id = id
|
||||
popup.querySelectorAll(".elmt-name").forEach(elmt => {
|
||||
elmt.innerText = name
|
||||
})
|
||||
popup.classList.add("show")
|
||||
}
|
||||
|
||||
function deleteElement(id) {
|
||||
let url = window.location.href
|
||||
if (!url.endsWith("/")) {
|
||||
url += "/"
|
||||
}
|
||||
url += `${id}/`
|
||||
req(url, {
|
||||
method: "DELETE"
|
||||
}).then(res => {
|
||||
return res.json()
|
||||
}).then(res => {
|
||||
if (res.status === "success") {
|
||||
window.location.reload()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
let onBeforeDelete = null
|
||||
|
||||
window.addEventListener("load", () => {
|
||||
document.querySelector("button.new").addEventListener("click", () => {
|
||||
window.location.href = "new/"
|
||||
@ -8,5 +36,20 @@ window.addEventListener("load", () => {
|
||||
row.querySelector("button.edit").addEventListener("click", () => {
|
||||
window.location.href = `${id}/`
|
||||
})
|
||||
|
||||
row.querySelector("button.delete")?.addEventListener("click", async () => {
|
||||
if (onBeforeDelete) {
|
||||
await onBeforeDelete(row)
|
||||
}
|
||||
showDeletePopup(id, row.dataset.name)
|
||||
})
|
||||
})
|
||||
|
||||
let deletePopup = document.getElementById("delete-popup")
|
||||
deletePopup.querySelector(".actions .cancel").addEventListener("click", () => {
|
||||
deletePopup.classList.remove("show")
|
||||
})
|
||||
deletePopup.querySelector(".actions .delete").addEventListener("click", () => {
|
||||
deleteElement(deletePopup.dataset.id)
|
||||
})
|
||||
})
|
11
dispatcher/static/parents.js
Normal file
11
dispatcher/static/parents.js
Normal file
@ -0,0 +1,11 @@
|
||||
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(".project-count").innerText = res.projects
|
||||
popup.querySelector(".task-count").innerText = res.tasks
|
||||
}
|
||||
})
|
||||
}
|
@ -5,7 +5,7 @@ window.addEventListener("load", () => {
|
||||
selector.addEventListener("change", () => {
|
||||
let fd = new FormData()
|
||||
fd.set("parent_id", selector.value)
|
||||
req(`${id}/set_parent`, {
|
||||
req(`${id}/set_parent/`, {
|
||||
method: "POST",
|
||||
body: fd
|
||||
})
|
||||
|
@ -10,7 +10,7 @@ from django.views.decorators.http import require_POST
|
||||
|
||||
from dispatcher.core import import_tasks
|
||||
from dispatcher.forms import ProjectForm, ImportForm, ParentForm
|
||||
from dispatcher.models import Project, Parent, Clocking
|
||||
from dispatcher.models import Project, Parent, Clocking, Task
|
||||
from dispatcher.serializers import ClockingSerializer
|
||||
|
||||
|
||||
@ -32,6 +32,11 @@ def projects_view(request):
|
||||
|
||||
def parent_view(request, id):
|
||||
parent = get_object_or_404(Parent, id=id)
|
||||
|
||||
if request.method == "DELETE":
|
||||
parent.delete()
|
||||
return JsonResponse({"status": "success"})
|
||||
|
||||
context = {
|
||||
"class": "parent",
|
||||
"id": id
|
||||
@ -43,6 +48,17 @@ def parent_view(request, id):
|
||||
context["form"] = ParentForm(instance=parent)
|
||||
return render(request, "edit.html", context)
|
||||
|
||||
def parent_on_delete_view(request, id):
|
||||
parent = get_object_or_404(Parent, id=id)
|
||||
projects = parent.project_set.count()
|
||||
tasks = Task.objects.filter(project__parent=parent).count()
|
||||
|
||||
return JsonResponse({
|
||||
"status": "success",
|
||||
"projects": projects,
|
||||
"tasks": tasks
|
||||
})
|
||||
|
||||
def new_parent_view(request):
|
||||
context = {
|
||||
"class": "parent"
|
||||
|
@ -6,13 +6,14 @@
|
||||
{% block extra-head %}{% endblock %}
|
||||
{% endblock %}
|
||||
{% block main %}
|
||||
{% csrf_token %}
|
||||
<div class="list-wrapper">
|
||||
<div class="list-header">
|
||||
<button class="new">New {{ class_name }}</button>
|
||||
</div>
|
||||
<ul class="list">
|
||||
{% for element in elements %}
|
||||
<li data-id="{{ element.id }}" class="{% block extra-class %}{% endblock %}">
|
||||
<li data-id="{{ element.id }}" data-name="{% block element-name %}{% endblock %}" class="{% block extra-class %}{% endblock %}">
|
||||
{% block element %}{% endblock %}
|
||||
<div class="actions">
|
||||
{% block actions %}{% endblock %}
|
||||
@ -23,4 +24,14 @@
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="popup" id="delete-popup">
|
||||
<div class="popup-container">
|
||||
<h2 class="title">Delete <span class="elmt-name"></span> ?</h2>
|
||||
<p class="desc">{% block delete-desc %}{% endblock %}</p>
|
||||
<div class="actions">
|
||||
<button class="cancel">Cancel</button>
|
||||
<button class="delete">Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
@ -3,8 +3,10 @@
|
||||
{% block title %}Parents{% endblock %}
|
||||
{% block extra-head %}
|
||||
<link rel="stylesheet" href="{% static "parents.css" %}">
|
||||
<script src="{% static "parents.js" %}"></script>
|
||||
{% endblock %}
|
||||
{% block extra-class %}{% if element.is_productive %}productive{% endif %}{% endblock %}
|
||||
{% block element-name %}{{ element.name }}{% endblock %}
|
||||
{% block element %}
|
||||
<div class="name">{{ element.name }}</div>
|
||||
{% if element.project_num %}
|
||||
@ -13,4 +15,13 @@
|
||||
{% endblock %}
|
||||
{% block actions %}
|
||||
<button class="edit">Edit</button>
|
||||
<button class="delete">Delete</button>
|
||||
{% endblock %}
|
||||
{% block delete-desc %}
|
||||
Are sure you want to delete <span class="elmt-name"></span> ?
|
||||
This action is <u>IRREVERSIBLE</u> ! By deleting this element, you will also delete:
|
||||
<ul>
|
||||
<li><span class="project-count"></span> project(s)</li>
|
||||
<li><span class="task-count"></span> task imputation(s)</li>
|
||||
</ul>
|
||||
{% endblock %}
|
Loading…
x
Reference in New Issue
Block a user