From d4ad751e3fc68ea4c98aba587d34b6d7298e9cf8 Mon Sep 17 00:00:00 2001 From: George Katsikas <giorgakis.katsikas@gmail.com> Date: Tue, 19 Sep 2023 16:01:44 +0200 Subject: [PATCH] add expected_editors to collections --- scipost_django/series/admin.py | 2 + .../0007_collection_expected_editors.py | 25 +++ scipost_django/series/models.py | 7 +- .../_hx_collection_expected_authors.html | 51 ++--- .../_hx_collection_expected_editors.html | 46 +++++ .../templates/series/collection_detail.html | 177 ++++++++++-------- scipost_django/series/urls.py | 10 + scipost_django/series/views.py | 36 +++- 8 files changed, 248 insertions(+), 106 deletions(-) create mode 100644 scipost_django/series/migrations/0007_collection_expected_editors.py create mode 100644 scipost_django/series/templates/series/_hx_collection_expected_editors.html diff --git a/scipost_django/series/admin.py b/scipost_django/series/admin.py index ba0ab8217..a644eec5d 100644 --- a/scipost_django/series/admin.py +++ b/scipost_django/series/admin.py @@ -36,6 +36,8 @@ class CollectionAdmin(admin.ModelAdmin): "series", "submissions", "publications", + "expected_authors", + "expected_editors", ] diff --git a/scipost_django/series/migrations/0007_collection_expected_editors.py b/scipost_django/series/migrations/0007_collection_expected_editors.py new file mode 100644 index 000000000..2dfb93175 --- /dev/null +++ b/scipost_django/series/migrations/0007_collection_expected_editors.py @@ -0,0 +1,25 @@ +# Generated by Django 3.2.18 on 2023-09-19 13:25 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('profiles', '0035_alter_profile_title'), + ('colleges', '0039_nomination_add_events'), + ('series', '0006_collection_expected_authors'), + ] + + operations = [ + migrations.AddField( + model_name='collection', + name='expected_editors', + field=models.ManyToManyField(blank=True, related_name='collections_editing', to='colleges.Fellowship'), + ), + migrations.AlterField( + model_name='collection', + name='expected_authors', + field=models.ManyToManyField(blank=True, related_name='collections_authoring', to='profiles.Profile'), + ), + ] diff --git a/scipost_django/series/models.py b/scipost_django/series/models.py index b3b0394a0..568bc2aa7 100644 --- a/scipost_django/series/models.py +++ b/scipost_django/series/models.py @@ -60,7 +60,12 @@ class Collection(models.Model): event_end_date = models.DateField(null=True, blank=True) image = models.ImageField(upload_to="series/collections/images/", blank=True) - expected_authors = models.ManyToManyField("profiles.Profile", blank=True) + expected_authors = models.ManyToManyField( + "profiles.Profile", blank=True, related_name="collections_authoring" + ) + expected_editors = models.ManyToManyField( + "colleges.Fellowship", blank=True, related_name="collections_editing" + ) submissions = models.ManyToManyField("submissions.Submission", blank=True) publications = models.ManyToManyField( "journals.Publication", through="series.CollectionPublicationsTable", blank=True diff --git a/scipost_django/series/templates/series/_hx_collection_expected_authors.html b/scipost_django/series/templates/series/_hx_collection_expected_authors.html index 48536a939..69f401aac 100644 --- a/scipost_django/series/templates/series/_hx_collection_expected_authors.html +++ b/scipost_django/series/templates/series/_hx_collection_expected_authors.html @@ -5,39 +5,40 @@ {% include 'scipost/messages.html' %} <table class="table"> <thead> - <tr> - <th>Profile</th> - <th>Actions</th> - </tr> + <tr> + <th>Profile</th> + <th>Actions</th> + </tr> </thead> + {% for profile in collection.expected_authors.all %} - <tr> - <td><a href="{{ profile.get_absolute_url }}">{{ profile }}</a></td> - <td> - <a - class="btn btn-sm btn-outline-danger" - hx-get="{% url 'series:_hx_collection_expected_author_action' slug=collection.slug profile_id=profile.id action='remove' %}" - hx-target="#profiles" - hx-confirm="Are you sure you want to remove {{ profile }} from expected authors in this Collection?" - ><small>Remove</small></a> - </td> - </tr> + <tr> + <td> + <a href="{{ profile.get_absolute_url }}">{{ profile }}</a> + </td> + <td> + <a class="btn btn-sm btn-outline-danger" + hx-get="{% url 'series:_hx_collection_expected_author_action' slug=collection.slug profile_id=profile.id action='remove' %}" + hx-target="#author_profiles" + hx-confirm="Are you sure you want to remove {{ profile }} from expected authors in this Collection?"><small>Remove</small></a> + </td> + </tr> {% empty %} - <tr> - <td colspan="4">No expected authors yet</td> - </tr> + <tr> + <td colspan="4">No expected authors yet</td> + </tr> {% endfor %} + </table> </div> <div class="col-md-4 p-4"> <h4>Add an expected author</h4> - <form - hx-post="{% url 'profiles:_hx_profile_dynsel_list' %}" - hx-trigger="keyup delay:200ms, change" - hx-target="#profile_search_results" - > - <div id="profile_search_form">{% crispy profile_search_form %}</div> + <form hx-post="{% url 'profiles:_hx_profile_dynsel_list' %}" + hx-trigger="keyup delay:200ms, change" + hx-target="#author_profile_search_results"> + <div id="author_profile_search_form">{% crispy author_profile_search_form %}</div> </form> - <div id="profile_search_results" class="border border-light m-2 p-1"></div> + <div id="author_profile_search_results" + class="border border-light m-2 p-1"></div> </div> </div> diff --git a/scipost_django/series/templates/series/_hx_collection_expected_editors.html b/scipost_django/series/templates/series/_hx_collection_expected_editors.html new file mode 100644 index 000000000..bdd964de4 --- /dev/null +++ b/scipost_django/series/templates/series/_hx_collection_expected_editors.html @@ -0,0 +1,46 @@ +{% load crispy_forms_tags %} + +<div class="row"> + <div class="col-md-8"> + {% include 'scipost/messages.html' %} + <table class="table"> + <thead> + <tr> + <th>Fellow</th> + <th>Actions</th> + </tr> + </thead> + + {% for editor in collection.expected_editors.all %} + {% with profile=editor.contributor.profile %} + <tr> + <td> + <a href="{{ profile.get_absolute_url }}">{{ profile }}</a> + </td> + <td> + <a class="btn btn-sm btn-outline-danger" + hx-get="{% url 'series:_hx_collection_expected_editor_action' slug=collection.slug fellowship_id=editor.id action='remove' %}" + hx-target="#editor_fellowships" + hx-confirm="Are you sure you want to remove {{ profile }} from expected editors in this Collection?"><small>Remove</small></a> + </td> + </tr> + {% endwith %} + {% empty %} + <tr> + <td colspan="4">No expected editors yet</td> + </tr> + {% endfor %} + + </table> + </div> + <div class="col-md-4 p-4"> + <h4>Add an expected editor</h4> + <form hx-post="{% url 'colleges:_hx_fellowship_dynsel_list' %}" + hx-trigger="keyup delay:200ms, change" + hx-target="#editor_fellowship_search_results"> + <div id="editor_fellowship_search_form">{% crispy editor_fellowship_search_form %}</div> + </form> + <div id="editor_fellowship_search_results" + class="border border-light m-2 p-1"></div> + </div> +</div> diff --git a/scipost_django/series/templates/series/collection_detail.html b/scipost_django/series/templates/series/collection_detail.html index 0811be7e2..6043ca827 100644 --- a/scipost_django/series/templates/series/collection_detail.html +++ b/scipost_django/series/templates/series/collection_detail.html @@ -12,8 +12,13 @@ <span class="breadcrumb-item">{{ collection.name }}</span> {% endblock %} -{% block meta_description %}{{ block.super }} Collection detail {{ collection.series.name }} {{ collection.name }}{% endblock meta_description %} -{% block pagetitle %}: Collection detail{% endblock pagetitle %} +{% block meta_description %} + {{ block.super }} Collection detail {{ collection.series.name }} {{ collection.name }} +{% endblock meta_description %} + +{% block pagetitle %} + : Collection detail +{% endblock pagetitle %} {% block content %} @@ -22,42 +27,47 @@ <div class="row"> <div class="col-12"> <h1 class="highlight"> - <a href="{{ collection.series.get_absolute_url }}">{{ collection.series.name }}</a> - {% if collection.series.container_journals %} - <br> - <small><em> - <ul class="list list-inline mt-2 mb-0"> - <li class="list-inline-item mx-0">a series contained in</li> - {% for container in collection.series.container_journals.all %} - <li class="list-inline-item"> - <a href="{{ container.get_absolute_url }}">{{ container }}</a> - </li> - {% endfor %} - </ul> - </em></small> - {% endif %} + <a href="{{ collection.series.get_absolute_url }}">{{ collection.series.name }}</a> + + {% if collection.series.container_journals %} + <br /> + <small><em> + <ul class="list list-inline mt-2 mb-0"> + <li class="list-inline-item mx-0">a series contained in</li> + + {% for container in collection.series.container_journals.all %} + <li class="list-inline-item"> + <a href="{{ container.get_absolute_url }}">{{ container }}</a> + </li> + {% endfor %} + + </ul> + </em></small> + {% endif %} + </h1> - <h2 class="highlight"> - Collection {{ collection.name }} - </h2> + <h2 class="highlight">Collection {{ collection.name }}</h2> </div> </div> <div class="row"> <div class="col-12"> - <div class="p-2"> - {% automarkup collection.description %} - </div> + <div class="p-2">{% automarkup collection.description %}</div> + {% if collection.event_start_date and collection.event_end_date %} - <p class="p-2"> - Dates: from {{ collection.event_start_date }} to {{ collection.event_end_date }}. - </p> + <p class="p-2">Dates: from {{ collection.event_start_date }} to {{ collection.event_end_date }}.</p> {% endif %} + {% if collection.image %} - <div class="p-2"> - <img class="d-flex me-3 p-2" style="max-height: 350px; max-width: 100%;" alt="image" src="{{ collection.image.url }}"> - </div> + <div class="p-2"> + <img class="d-flex me-3 p-2" + style="max-height: 350px; + max-width: 100%" + alt="image" + src="{{ collection.image.url }}" /> + </div> {% endif %} + </div> </div> @@ -66,77 +76,88 @@ <h3>Editorial Administration</h3> <div class="card my-4"> - <div class="card-header"> - Expected authors for this Collection - </div> - <div class="card-body"> - <div - id="profiles" - hx-get="{% url 'series:_hx_collection_expected_authors' slug=collection.slug %}" - hx-trigger="load" - > - </div> - </div> + <div class="card-header">Expected authors for this Collection</div> + <div class="card-body"> + <div id="author_profiles" + hx-get="{% url 'series:_hx_collection_expected_authors' slug=collection.slug %}" + hx-trigger="load"></div> + </div> + </div> + + <div class="card my-4"> + <div class="card-header">Expected editors for this Collection</div> + <div class="card-body"> + <div id="editor_fellowships" + hx-get="{% url 'series:_hx_collection_expected_editors' slug=collection.slug %}" + hx-trigger="load"></div> + </div> </div> <div class="card my-4"> - <div class="card-header"> - Publications - </div> - <div class="card-body"> - <div - id="publications" - hx-get="{% url 'series:_hx_collection_publications' slug=collection.slug %}" - hx-trigger="load" - > - </div> - </div> + <div class="card-header">Publications</div> + <div class="card-body"> + <div id="publications" + hx-get="{% url 'series:_hx_collection_publications' slug=collection.slug %}" + hx-trigger="load"></div> + </div> </div> </div> {% endif %} {% with active_submissions=collection.submissions.under_consideration %} + {% if active_submissions|length > 0 %} <div class="row"> - <div class="col-12"> - <h3 class="highlight">Submissions to this Collection</h3> - <ul> - {% for submission in active_submissions.accepted %} - <li><strong class="text-success">accepted:</strong> - <a href="{{ submission.get_absolute_url }}" target="_blank">{{ submission }}</a> - </li> - {% endfor %} - {% for submission in active_submissions.revision_requested %} - <li><strong class="text-primary">awaiting resubmission:</strong> - <a href="{{ submission.get_absolute_url }}" target="_blank">{{ submission }}</a> - </li> - {% endfor %} - {% for submission in active_submissions.in_refereeing %} - <li><strong class="text-warning">under refereeing:</strong> - <a href="{{ submission.get_absolute_url }}" target="_blank">{{ submission }}</a> - </li> - {% endfor %} - </ul> - </div> + <div class="col-12"> + <h3 class="highlight">Submissions to this Collection</h3> + <ul> + + {% for submission in active_submissions.accepted %} + <li> + <strong class="text-success">accepted:</strong> + <a href="{{ submission.get_absolute_url }}" target="_blank">{{ submission }}</a> + </li> + {% endfor %} + + {% for submission in active_submissions.revision_requested %} + <li> + <strong class="text-primary">awaiting resubmission:</strong> + <a href="{{ submission.get_absolute_url }}" target="_blank">{{ submission }}</a> + </li> + {% endfor %} + + {% for submission in active_submissions.in_refereeing %} + <li> + <strong class="text-warning">under refereeing:</strong> + <a href="{{ submission.get_absolute_url }}" target="_blank">{{ submission }}</a> + </li> + {% endfor %} + + </ul> + </div> </div> {% endif %} + {% endwith %} <div class="row"> <div class="col-12"> <h3 class="highlight">Publications in this Collection</h3> <ul> - {% for publication in collection.publications.all %} - <li><a href="{{ publication.get_absolute_url }}">{{ publication }}</a></li> - {% empty %} - <li>No Publication has yet been associated to this Collection</li> - {% endfor %} + + {% for publication in collection.publications.all %} + <li> + <a href="{{ publication.get_absolute_url }}">{{ publication }}</a> + </li> + {% empty %} + <li>No Publication has yet been associated to this Collection</li> + {% endfor %} + </ul> </div> </div> {% endblock content %} -{% block footer_script %} - {{ expected_author_form.media }} -{% endblock %} + +{% block footer_script %}{{ expected_author_form.media }}{% endblock %} diff --git a/scipost_django/series/urls.py b/scipost_django/series/urls.py index e6e1b4867..ecd8c4dc3 100644 --- a/scipost_django/series/urls.py +++ b/scipost_django/series/urls.py @@ -24,11 +24,21 @@ urlpatterns = [ views._hx_collection_expected_authors, name="_hx_collection_expected_authors", ), + path( + "_hx_collection_expected_editors", + views._hx_collection_expected_editors, + name="_hx_collection_expected_editors", + ), path( "_hx_collection_expected_author_action/<int:profile_id>/<str:action>", views._hx_collection_expected_author_action, name="_hx_collection_expected_author_action", ), + path( + "_hx_collection_expected_editor_action/<int:fellowship_id>/<str:action>", + views._hx_collection_expected_editor_action, + name="_hx_collection_expected_editor_action", + ), path( "_hx_collection_publications", views._hx_collection_publications, diff --git a/scipost_django/series/views.py b/scipost_django/series/views.py index d342bcc59..261affb4e 100644 --- a/scipost_django/series/views.py +++ b/scipost_django/series/views.py @@ -13,6 +13,8 @@ from journals.models import Publication from journals.forms import PublicationDynSelForm from profiles.models import Profile from profiles.forms import ProfileSelectForm, ProfileDynSelForm +from colleges.forms import FellowshipDynSelForm +from colleges.models import Fellowship from .models import Series, Collection, CollectionPublicationsTable @@ -62,11 +64,11 @@ def _hx_collection_expected_authors(request, slug): initial={ "action_url_name": "series:_hx_collection_expected_author_action", "action_url_base_kwargs": {"slug": collection.slug, "action": "add"}, - "action_target_element_id": "profiles", + "action_target_element_id": "author_profiles", "action_target_swap": "innerHTML", } ) - context = {"collection": collection, "profile_search_form": form} + context = {"collection": collection, "author_profile_search_form": form} return render(request, "series/_hx_collection_expected_authors.html", context) @@ -91,6 +93,36 @@ def _hx_collection_expected_author_action(request, slug, profile_id, action): ) +@permission_required("scipost.can_manage_series") +def _hx_collection_expected_editors(request, slug): + collection = get_object_or_404(Collection, slug=slug) + form = FellowshipDynSelForm( + initial={ + "action_url_name": "series:_hx_collection_expected_editor_action", + "action_url_base_kwargs": {"slug": collection.slug, "action": "add"}, + "action_target_element_id": "editor_fellowships", + "action_target_swap": "innerHTML", + } + ) + context = {"collection": collection, "editor_fellowship_search_form": form} + return render(request, "series/_hx_collection_expected_editors.html", context) + + +@permission_required("scipost.can_manage_series") +def _hx_collection_expected_editor_action(request, slug, fellowship_id, action): + collection = get_object_or_404(Collection, slug=slug) + fellowship = get_object_or_404(Fellowship, pk=fellowship_id) + if action == "add": + collection.expected_editors.add(fellowship) + if action == "remove": + collection.expected_editors.remove(fellowship) + return redirect( + reverse( + "series:_hx_collection_expected_editors", kwargs={"slug": collection.slug} + ) + ) + + @permission_required("scipost.can_manage_series") def _hx_collection_publications(request, slug): collection = get_object_or_404(Collection, slug=slug) -- GitLab