Improved project item management

This commit is contained in:
Tris Forster 2026-08-27 09:42:09 +10:00
parent 56827fa6b2
commit 24cb447579
3 changed files with 52 additions and 13 deletions

View File

@ -2,7 +2,7 @@
{% load polyphonic %} {% load polyphonic %}
{% block admin %} {% block admin %}
<a href="{% url 'item_list_append' project.pk %}" class="button is-link"> <a href="{% url 'project_work_list' project.pk %}" class="button is-link">
{% icon "add_circle" %} {% icon "add_circle" %}
<span>Add</span> <span>Add</span>
</a> </a>
@ -15,15 +15,6 @@
{% block page %} {% block page %}
<div class="columns"> <div class="columns">
<div class="column">
<h3 class="subtitle">Add from collection</h3>
<div>
{% for access in project.ensemble.allowed_collections.all %}
<a href="" class="button is-link">{{ access.collection.name }}</a>
{% endfor %}
</div>
</div>
<div class="column card"> <div class="column card">
<table style="max-width: 600px; margin: 10pt auto;" class="table is-striped is-narrow"> <table style="max-width: 600px; margin: 10pt auto;" class="table is-striped is-narrow">
<thead> <thead>
@ -39,7 +30,7 @@
<td>{{ item.work.name }}</td> <td>{{ item.work.name }}</td>
<td style="min-width: 100px;">{% firstof item.work.duration '-:--' %}</td> <td style="min-width: 100px;">{% firstof item.work.duration '-:--' %}</td>
<td style="text-align: center;"> <td style="text-align: center;">
<span class="clickable cursor-pointer" title="Remove" onClick="removeItem({{ item.pk }})"> <span class="clickable is-clickable" title="Remove" onClick="removeItem({{ item.pk }})">
{% icon "delete" %} {% icon "delete" %}
</span> </span>
<span class="clickable drag-handle cursor-drag" title="Reorder"> <span class="clickable drag-handle cursor-drag" title="Reorder">
@ -109,6 +100,7 @@ workList.addEventListener('dragstart', function(e) {
if (!dragSrc) return; if (!dragSrc) return;
dragSrcNext = dragSrc.nextElementSibling; dragSrcNext = dragSrc.nextElementSibling;
dragSrc.classList.add('dragging'); dragSrc.classList.add('dragging');
e.dataTransfer.setDragImage(e.target, 0, 0);
e.dataTransfer.effectAllowed = 'move'; e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('text/plain', dragSrc.dataset.pk); e.dataTransfer.setData('text/plain', dragSrc.dataset.pk);
}); });

View File

@ -9,6 +9,12 @@
<span>Add a work</span> <span>Add a work</span>
</a> </a>
{% endif %} {% endif %}
{% if project %}
<a href="{% url 'item_list_manage' project.pk %}" class="button">
{% icon "add_notes" %}
<span>Back</span>
</a>
{% endif %}
{% endblock %} {% endblock %}
{% block page %} {% block page %}
@ -54,7 +60,13 @@
<td title="{{ work.composer }}">{{ work.composer|truncatewords:3 }}</td> <td title="{{ work.composer }}">{{ work.composer|truncatewords:3 }}</td>
<td class="is-hidden-mobile" title="{{ work.edition }}">{{ work.edition|truncatewords:2 }}</td> <td class="is-hidden-mobile" title="{{ work.edition }}">{{ work.edition|truncatewords:2 }}</td>
{% if not collection and not project %}<td class="is-hidden-touch">{{ work.collection.name }}</td>{% endif %} {% if not collection and not project %}<td class="is-hidden-touch">{{ work.collection.name }}</td>{% endif %}
{% if project %}<td><a href"" class="button is-primary is-small">Add</a>{% endif %} {% if project %}
<td>
<button data-work="{{ work.pk }}" onclick="addToProject({{ work.pk }})" class="button is-primary is-small">
{% if work.pk in current %} Added {% else %} Add {% endif %}
</button>
</td>
{% endif %}
</tr> </tr>
{% empty %} {% empty %}
<tr><td colspan="4">No works found</td></tr> <tr><td colspan="4">No works found</td></tr>
@ -102,3 +114,24 @@ Query="{{ meta.query }}"
</footer> </footer>
{% endblock %} {% endblock %}
{% block scripts %}
<script>
async function addToProject(work) {
console.log("ADD", work);
const response = await fetch("", {
method: "POST",
headers: {"Content-Type": "application/x-www-form-urlencoded"},
body: new URLSearchParams({ work, csrfmiddlewaretoken: "{{ csrf_token }}" }),
});
if (response.status === 201) {
document.querySelector(`[data-work='${work}']`).innerHTML = "Added";
} else {
alert("Failed to add work\nCheck console for details");
console.error(response);
}
console.log(response);
}
</script>
{% endblock %}

View File

@ -1,5 +1,5 @@
from django.shortcuts import get_object_or_404, redirect, resolve_url from django.shortcuts import get_object_or_404, redirect, resolve_url
from django.http import HttpRequest from django.http import HttpRequest, HttpResponse
from django.views.generic import TemplateView from django.views.generic import TemplateView
from django.views.generic.detail import DetailView, SingleObjectMixin, View from django.views.generic.detail import DetailView, SingleObjectMixin, View
from django.views.generic.list import ListView from django.views.generic.list import ListView
@ -11,6 +11,7 @@ from django.utils.timezone import now
from django.template.loader import render_to_string from django.template.loader import render_to_string
from django.core.exceptions import SuspiciousOperation from django.core.exceptions import SuspiciousOperation
from django.core.paginator import Paginator from django.core.paginator import Paginator
from django.http import Http404, HttpResponseRedirect from django.http import Http404, HttpResponseRedirect
import json import json
@ -301,9 +302,21 @@ class CollectionWorkListView(WorkListView):
class ProjectWorkListView(WorkListView, ProjectMixin): class ProjectWorkListView(WorkListView, ProjectMixin):
http_method_names = ["get", "post"]
def is_authorized(self): def is_authorized(self):
return ProjectMixin.is_authorized(self) return ProjectMixin.is_authorized(self)
def post(self, request, project):
work = request.POST.get("work")
print("WORK", work)
self.project.items.create(
work_id=work, checkout=now(), approved_by=request.user, order=100
)
return HttpResponse(status=201)
def get_works(self): def get_works(self):
collections = self.get_collections() or [] collections = self.get_collections() or []
print(collections) print(collections)
@ -317,6 +330,7 @@ class ProjectWorkListView(WorkListView, ProjectMixin):
def get_context_data(self, *args, **kwargs): def get_context_data(self, *args, **kwargs):
data = super(ProjectWorkListView, self).get_context_data(*args, **kwargs) data = super(ProjectWorkListView, self).get_context_data(*args, **kwargs)
data["title"] = f"Library for {self.project.ensemble}" data["title"] = f"Library for {self.project.ensemble}"
data["current"] = set(self.project.items.values_list("work_id", flat=True))
return data return data