Many interface changes

This commit is contained in:
Tris Forster 2023-03-03 16:07:30 +11:00
parent 69f747d5b5
commit d1328ae1b1
11 changed files with 188 additions and 94 deletions

View File

@ -21,14 +21,16 @@
{% block page %}
<h3 class="title">Projects for {{ensemble.name }}</h3>
<p>{{ ensemble.details|markdown }}</p>
<div class="content">
{{ ensemble.details|markdown }}
</div>
<p>
Administrators:
<div class="block">
Contacts:
{% for admin in ensemble.admins.all %}
<a href="mailto:{{ admin.email }}">{% firstof admin.get_full_name admin.get_username %}</a>
<a href="mailto:{{ admin.email }}" class="tag">{% firstof admin.get_full_name admin.get_username %}</a>
{% endfor %}
</p>
</div>
{% include 'interface/project_items.html' %}
@ -39,11 +41,10 @@ Administrators:
<p class="card-header-title">Admin Details</p>
</header>
<div class="card-content">
<p>
Joining instructions for participants<br/><br/>
URL: <a href="{{ ensemble_link }}">{{ ensemble_link }}</a><br/>
</p>
<ul>
<li><a href="{{ ensemble_link }}">Ensemble Sharing Link</a></li>
<li><a href="{% url 'project_create' ensemble.pk %}">Add a new project</a></li>
</ul>
</div>
</div>
</div>

View File

@ -2,9 +2,7 @@
{% block content %}
<div class="columns">
<div class="columns mx-2">
<div class="column is-narrow is-hidden-touch" id="projectMenu">
<div style="margin: auto 2em;">
<aside class="menu">
@ -27,7 +25,7 @@
<li><a class="nav-link" href="{% url 'item_list' project=project.pk %}">My Music</a></li>
{% endif %}
{% for page in project.wiki_pages.all %}
<li><a class="nav-link
<li><a class="nav-link"
href="{% url 'wiki' project=project.id pk=page.id %}">{{ page.title }}</a></li>
{% endfor %}
<li><a role="tab" href="{% url 'resource_list' project=project.pk %}">Resources</a></li>
@ -76,9 +74,9 @@
</div>
{% endif %}
<div class="block" style="margin: auto 2em">
<div class="block">
{% if request.is_admin %}
<div class="admin-tools is-pulled-right">
<div class="admin-tools is-pulled-right is-hidden-mobile">
{% block admin %}
{% endblock %}
</div>

View File

@ -14,60 +14,71 @@
{% endblock %}
{% block page %}
<div class="box">
{% if project.event_date %}
<h3 class="subtitle is-centered">
<b>{{ project.event_date|date:"l jS F Y, g:i A" }}</b>
{% if project.has_happened %}
({{ project.event_date|roughtimesince }} ago)
{% else %}
(in {{ project.event_date|roughtimeuntil }})
{% endif %}
</h3>
{% endif %}
<div class="block">
{% if project.description %}
<p class="content">{{ project.description|markdown }}</p>
{% else %}
<p>No description</p>
<div class="columns is-multiline">
<div class="column ">
<div class="box">
{% if project.event_date %}
<h3 class="subtitle is-centered">
<b>{{ project.event_date|date:"l jS F Y, g:i A" }}</b>
{% if project.has_happened %}
({{ project.event_date|roughtimesince }} ago)
{% else %}
(in {{ project.event_date|roughtimeuntil }})
{% endif %}
</h3>
{% endif %}
<div class="block">
{% if project.description %}
<p class="content">{{ project.description|markdown }}</p>
{% else %}
<p>No description</p>
{% endif %}
</div>
{% if project.owner %}
<div class="block">
{% if project.owner.email %}
The project owner is <a href="mailto:{{ project.owner.email }}">{{ project.owner }}</a>
{% else %}
The project owner is {{ project.owner }}.
{% endif %}
</div>
{% endif %}
</div>
</div>
{% if 'library' in modules %}
<div class="block">
<div class="column is-one-third">
{% include 'library/project_detail.html' %}
</div>
</div>
{% endif %}
{% if 'submission' in modules %}
<div class="block">
<div class="column">
{% include 'submissions/project_detail.html' %}
</div>
{% endif %}
{% if project.owner %}
<div class="block">
{% if project.owner.email %}
The project owner is <a href="mailto:{{ project.owner.email }}">{{ project.owner }}</a>
{% else %}
The project owner is {{ project.owner }}.
{% endif %}
</div>
{% endif %}
{% if request.is_admin %}
<div class="block">
<a href="{{ project_link }}">Project Link</a>
</div>
</div>
{% endif %}
</div>
{% if request.is_admin %}
<div class="box">
<h3 class="subtitle">Admin Actions</h3>
<ul>
<li><a href="{{ project_link }}">Project Link</a></li>
{% if 'library' in modules %}
<li><a href="{% url 'item_list_manage' project=project.pk %}">Manage items</a></li>
{% endif %}
</ul>
</div>
{% endif %}
<!--
<div>
<a href="{% url 'forget_resource' 'project' project.pk %}">Forget this project</a>
</div>
-->
{% endblock %}

View File

@ -9,6 +9,7 @@
{% endblock %}
{% block page %}
<h3 class="subtitle">Resources</h3>
<div class="columns is-multiline">
{% for resource in object_list %}
{% with download=resource.file.url %}
@ -51,7 +52,7 @@
{% endwith %}
{% empty %}
<div class="column">
<p>There are resources for this project</p>
<p>There are no resources for this project</p>
</div>
{% endfor %}
</div>

View File

@ -9,6 +9,7 @@ from django.core.files.storage import get_storage_class
from django.db.models import Q, Count, Min, Max
import re
import os.path
from byostorage.user import BYOStorage
from byostorage.cached import CachedStorage
@ -218,6 +219,9 @@ class Work(models.Model):
#return [ s[1] for s in sections ]
sections = list(dict(sections).items()) # primitive unique()
return sections
def pdfs(self):
return self.docs.filter(doctype=Document.DOCTYPE_PDF)
@property
def physical_parts(self):
@ -344,6 +348,9 @@ class Document(models.Model):
def delete(self, *args, **kwargs):
self.upload.delete(save=False)
return super().delete(*args, **kwargs)
def filename(self):
return os.path.basename(self.upload.name)
def __str__(self):
return self.upload.name

View File

@ -78,8 +78,8 @@
{% for tag, inst in document.work.music_tags %}
<li class="is-clickable" onclick="assignInstrument('{{tag}}', this)")>{{ inst }}</li>
{% endfor %}
<li><a onclick="document.getElementById('add-modal').classList.add('is-active')">Add instrument</a></li>
</ul>
<a onclick="document.getElementById('add-modal').classList.add('is-active')">Add Tag</a>
</div>
<div class="column is-narrow">
<div class="has-text-centered">
@ -122,7 +122,7 @@
<input type="number" class="input" max="4" min="1" size="3" id="add-instrument-variant"/>
</span>
<span class="control">
<button class="button is-primary" onclick="addInstrument()">Add</button>
<button class="button is-primary" onclick="addInstrument();">Add</button>
</span>
</div>
</section>
@ -301,7 +301,14 @@
variant.value = '';
name.value = '';
let li = document.createElement('li');
li.classList.add("is-clickable");
li.addEventListener('click', () => assignInstrument(tag, li));
li.innerHTML = get_instrument(tag);
document.getElementById('unassigned-area').appendChild(li);
addTag(tag, pageNum, pageNum);
closeAddModal();
}
function assignInstrument(tag, el) {
@ -334,11 +341,6 @@
del.className = "icon is-action";
del.innerHTML = '<i class="fas fa-trash-alt" title="Remove this tag"></i>';
del.addEventListener('click', () => {
let li = document.createElement('li');
li.classList.add("is-clickable");
li.addEventListener('click', () => assignInstrument(tag, li));
li.innerHTML = get_instrument(el.dataset.tag);
document.getElementById('unassigned-area').appendChild(li);
el.remove();
dirty=true;
});

View File

@ -1,21 +1,14 @@
{% extends "interface/project_base.html" %}
{% block admin %}
<a class="button is-link" href="{% url 'item_list_manage' project.pk %}">
<span class="icon"><i class="fas fa-list"></i></span>
<span>Change items</span>
</a>
{% endblock %}
{% block page %}
<form action="" method="post" target="_blank">
{% csrf_token %}
<div>
<div class="field is-grouped is-grouped-centered">
<div class="field has-addons control">
<div class="field is-grouped is-grouped-centered is-grouped-multiline">
<div class="field has-addons control has-addons-centered is-expanded">
<span class="control">
<a class="button is-static">Your Instrument</a>
<span class="control is-hidden-mobile">
<a class="button is-static">Instrument</a>
</span>
<span class="control">
@ -47,12 +40,12 @@
</div>
</div>
<table class="table is-striped is-fullwidth">
<table class="table is-striped mx-auto">
<thead>
<tr>
<th/>
<th>Piece</th>
<th>Running time</th>
<th class="is-hidden-mobile">Running time</th>
<th>Part</th>
<th/>
</tr>
@ -68,11 +61,11 @@
{{ item.work.name }}
{% endif %}
</td>
<td>{% firstof item.work.running_time "------" %}</td>
<td class="is-hidden-mobile">{% firstof item.work.running_time "------" %}</td>
<td class="select-cell">
<input type="hidden" name="works" value="{{ item.work.pk }}"/>
<span class="select is-small">
<select name="instruments">
<span class="select is-small" style="width: 100%">
<select name="instruments" id="part-{{ item.work.pk }}" style="width: 100%">
<option value='-'>None</option>
{% for tag, name in item.work.digital_parts %}
<option value='{{ tag }}'>{{ name }}</option>
@ -81,7 +74,9 @@
</span>
</td>
<td>
<a href=""><i class="fas fa-download"></i></a>
<span class="is-action" onclick="downloadPart({{ item.work.collection_id }}, {{ item.work.pk }})">
<i class="fas fa-download" title="Download Part"></i>
</span>
</td>
</tr>
{% endfor %}
@ -90,11 +85,13 @@
<tr>
<td/>
<td/>
<td>{{ running_time }}</td>
<td>{% firstof running_time "------" %}</td>
<td/>
<td>
<!--
<button class="button is-link is-small" type="submit"><span class="icon"><i class="fas fa-copy"></i></span><span>Single combined PDF</span></button>
<a class="button is-link is-small"><span class="icon"><i class="fas fa-archive"></i></span><span>Individual files (zipped)</span></a>
-->
</td>
</tr>
</tfoot>
@ -154,6 +151,17 @@ function selectParts(inst, part) {
}
function downloadPart(collection, work) {
let part = document.getElementById("part-" + work).value;
if (part == '-') {
alert("No part selected!");
return;
}
console.log(part);
let url = "/collections/" + collection + "/works/" + work + "/download?tag=" + part;
window.location = url;
}
document.getElementById("instrument-name").value = localStorage.getItem('instrument-name', 'All');
document.getElementById("part-preference").value = localStorage.getItem('part-preference', 'Any');
updateParts();

View File

@ -1,12 +1,50 @@
<h4 class="is-size-4">Items</h4>
<ul>
{% for item in project.items.all %}
{% with work=item.work %}
<li>
<a href="{% url 'work_detail' item.work.collection.pk item.work.pk %}">{{ item.work.name }}</a>
</li>
{% endwith %}
{% empty %}
<li>There are no items listed yet for this project - please check back later...</li>
{% endfor %}
</ul>
<div class="panel">
<p class="panel-heading">
Items
</p>
{% for item in project.items.all %}
{% with work=item.work %}
<a class="panel-block" onclick="showDownloadOptions('{% url 'work_parts' work.collection_id work.pk %}')">
{{ item.work.name }}
</a>
{% endwith %}
{% empty %}
<span class="panel-block">
There are no items listed yet for this project - please check back later...
</span>
{% endfor %}
</div>
<div class="modal" id="download-modal">
<div class="modal-background" onclick="closeDownloadModal()"></div>
<div class="modal-card">
<header class="modal-card-head">
<p class="modal-card-title">Parts</p>
<button class="delete" aria-label="close" onclick="closeDownloadModal()"></button>
</header>
<section class="modal-card-body" id="download-target">
</section>
</div>
</div>
<script>
function showDownloadOptions(url) {
let target = document.getElementById("download-target");
target.innerHTML = "Loading available parts...";
document.getElementById("download-modal").classList.add('is-active');
fetch(url).then((data) => {
console.log(data);
data.text().then((text) => {
target.innerHTML = text;
});
});
}
function closeDownloadModal() {
document.getElementById("download-modal").classList.remove('is-active');
}
</script>

View File

@ -0,0 +1,25 @@
<h3 class="subtitle">{{ work.name }}</h3>
<div class="block">
{% for tag, name in work.digital_parts %}
<a class="tag is-info" href="{% url 'work_download' work.collection_id work.pk %}?tag={{ tag }}">{{ name }}</a>
{% endfor %}
</div>
<h3 class="subtitle">Files</h3>
<table class="table is-narrow is-fullwidth">
<tbody>
{% for doc in work.pdfs %}
<tr>
<td><a href="{{ doc.upload.url }}">{{ doc.filename }}</a></td>
</tr>
{% empty %}
<tr>
<td>There are no files available for this work</td>
</tr>
{% endfor %}
</tbody>
</table>
<p>
<a href="{% url 'work_detail' work.collection_id work.pk %}">More details...</a>
</p>

View File

@ -25,6 +25,7 @@ urlpatterns = [
path('collections/<int:collection>/works/<int:pk>', views.WorkDetailView.as_view(), name="work_detail"),
path('collections/<int:collection>/works/<int:pk>/edit', views.WorkUpdateView.as_view(), name="work_edit"),
path('collections/<int:collection>/works/<int:pk>/partset', views.WorkPartSetView.as_view(), name="work_partset"),
path('collections/<int:collection>/works/<int:pk>/parts', views.WorkPartsView.as_view(), name="work_parts"),
path('collections/<int:collection>/works/<int:pk>/add_to_project', views.WorkAddToProject.as_view(), name="work_add_to_project"),
path('collections/<int:collection>/works/<int:pk>/upload', views.WorkAddDocumentView.as_view(), name="document_add"),
path('collections/<int:collection>/works/<int:pk>/download', views.WorkDownloadView.as_view(), name="work_download"),

View File

@ -273,7 +273,9 @@ class WorkAddToProject(CollectionMixin, FormView):
work.project_items.create(project=project, approved_by=self.request.user, checkout=now())
return redirect('item_list', project=project.pk)
class WorkPartsView(CollectionMixin, DetailView):
model = models.Work
template_name = "library/work_parts_fragment.html"
class WorkPartSetView(CollectionMixin, DetailView):
template_name = "library/work_partset.html"