diff --git a/scipost_django/journals/forms.py b/scipost_django/journals/forms.py index da5ce8ebce3373cbc789b8eb9e653976b3144a79..43307f04c0a97986180dd6420c29c5124b78ea43 100644 --- a/scipost_django/journals/forms.py +++ b/scipost_django/journals/forms.py @@ -21,6 +21,9 @@ from crispy_forms.helper import FormHelper from crispy_forms.layout import Layout, Div, Field, ButtonHolder, Submit from crispy_bootstrap5.bootstrap5 import FloatingField from dal import autocomplete +from common.forms import HTMXInlineCRUDModelForm + +from journals.models.resource import PublicationResource from .constants import ( STATUS_DRAFT, @@ -650,15 +653,32 @@ class DraftAccompanyingPublicationForm(forms.Form): title = forms.CharField(max_length=300) abstract = forms.CharField(widget=forms.Textarea()) doi_label_suffix = forms.CharField(max_length=128) + pubtype = forms.ChoiceField( + choices=Publication.PUBTYPE_CHOICES, + widget=forms.RadioSelect(), + label="Publication type", + ) + inherit = forms.MultipleChoiceField( + choices=[ + ("abstract_jats", "Abstract (JATS)"), + ("metadata.funding_statement", "Funding statement"), + ], + widget=forms.CheckboxSelectMultiple(attrs={"checked": "checked"}), + ) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.helper = FormHelper() self.helper.layout = Layout( - Field("anchor"), - FloatingField("title"), - Field("abstract"), - FloatingField("doi_label_suffix"), + Field("anchor", css_class="mb-3"), + Field("pubtype", css_class="d-flex flex-wrap gap-3 mb-3"), + Field("title", css_class="mb-3"), + Field("abstract", css_class="mb-3"), + Field("doi_label_suffix", css_class="mb-3"), + Field( + "inherit", + css_class="d-flex flex-wrap gap-2 mb-3", + ), ButtonHolder(Submit("submit", "Submit", css_class="btn btn-primary")), ) @@ -681,6 +701,7 @@ class DraftAccompanyingPublicationForm(forms.Form): submission_date=anchor.submission_date, acceptance_date=anchor.acceptance_date, publication_date=anchor.publication_date, + pubtype=self.cleaned_data["pubtype"], ) companion.save() # Handle ManyToMany fields @@ -717,6 +738,36 @@ class DraftAccompanyingPublicationForm(forms.Form): fraction=pubfrac.fraction, ) + # Add DOI of each companion to the anchor's metadata and vice versa + anchor.metadata["citation_list"].append( + { + "doi": companion.doi_string, + "key": "ref" + str(len(anchor.metadata["citation_list"]) + 1), + } + ) + anchor.save() + + companion.metadata.setdefault("citation_list", []) + companion.metadata["citation_list"].append( + { + "doi": anchor.doi_string, + "key": "ref" + str(len(companion.metadata["citation_list"]) + 1), + } + ) + + # Inherit the selected fields from the anchor + for field in self.cleaned_data["inherit"]: + if "." not in field: + setattr(companion, field, getattr(anchor, field)) + # Inherit the selected fields from the anchor's field as a dict + else: + field, key = field.split(".") + field_dict = getattr(companion, field) + field_dict[key] = getattr(anchor, field).get(key) + setattr(companion, field, field_dict) + + companion.save() + return companion @@ -990,3 +1041,29 @@ class PublicationDynSelForm(forms.Form): return publications else: return Publication.objects.none() + + +class HTMXInlinePublicationResourceForm(HTMXInlineCRUDModelForm): + class Meta: + model = PublicationResource + fields = ["publication", "_type", "url", "comments"] + widgets = { + "publication": forms.HiddenInput(), + } + + def __init__(self, *args, **kwargs): + doi = kwargs.pop("doi_label", None) + super().__init__(*args, **kwargs) + self.fields["_type"].choices = PublicationResource.TYPE_CHOICES + self.fields["_type"].label = "Resource type" + self.fields["url"].label = "URL" + + if doi: + self.fields["publication"].initial = Publication.objects.get(doi_label=doi) + + self.helper.layout = Layout( + Div(FloatingField("publication"), css_class="col-12"), + Div(FloatingField("_type"), css_class="col-3"), + Div(FloatingField("url"), css_class="col-9"), + Div(FloatingField("comments"), css_class="col"), + ) diff --git a/scipost_django/journals/templates/journals/_publication_actions.html b/scipost_django/journals/templates/journals/_publication_actions.html index 00b3b33c16a602f55717c9094955c05e6c5e09ed..08eaa107dd87125e54166e93aa13da4f59a5c4ea 100644 --- a/scipost_django/journals/templates/journals/_publication_actions.html +++ b/scipost_django/journals/templates/journals/_publication_actions.html @@ -6,6 +6,7 @@ <li><a href="{% url 'journals:create_citation_list_metadata' publication.doi_label %}">Create/update citation list metadata</a></li> <li><a href="{% url 'journals:create_funding_info_metadata' publication.doi_label %}">Create/update funding info metadata</a></li> <li><a href="{% url 'journals:create_metadata_xml' publication.doi_label %}">Create/update the XML metadata</a></li> + <li><a href="{% url 'journals:manage_publication_resources' publication.doi_label %}">Manage publication resources</a></li> <li><a href="{% url 'journals:metadata_xml_deposit' publication.doi_label 'test' %}">Test metadata deposit (via Crossref test server)</a></li> <li><a href="{% url 'journals:metadata_xml_deposit' publication.doi_label 'deposit' %}">Deposit the metadata to Crossref</a></li> <li><a href="{% url 'journals:produce_metadata_DOAJ' doi_label=publication.doi_label %}">Produce DOAJ metadata</a></li> diff --git a/scipost_django/journals/templates/journals/manage_publication_resources.html b/scipost_django/journals/templates/journals/manage_publication_resources.html new file mode 100644 index 0000000000000000000000000000000000000000..c75204aadc2ac4f66699f0c29043ec85851daf70 --- /dev/null +++ b/scipost_django/journals/templates/journals/manage_publication_resources.html @@ -0,0 +1,19 @@ + +{% extends "scipost/base.html" %} + +{% load bootstrap %} + +{% block breadcrumb_items %} + {{ block.super }} + <span class="breadcrumb-item">Publication resources</span> +{% endblock breadcrumb_items %} + +{% block pagetitle %} + : Publication resources +{% endblock pagetitle %} + +{% block content %} + <h2>Publication resources</h2> + <div hx-get="{% url "journals:_hx_publication_resource_list" doi_label=publication.doi_label %}" + hx-trigger="load once"></div> +{% endblock content %} diff --git a/scipost_django/journals/templates/journals/publication_resource_li.html b/scipost_django/journals/templates/journals/publication_resource_li.html new file mode 100644 index 0000000000000000000000000000000000000000..f642019034a5b21e4c6bd9c03ec29d69584e34ee --- /dev/null +++ b/scipost_django/journals/templates/journals/publication_resource_li.html @@ -0,0 +1,5 @@ +<div class="d-flex flex-column"> + <div class="fs-4 font-bold">{{ instance.get__type_display }}</div> + <a href="{{ instance.url }}">{{ instance.url }}</a> + <div class="fs-6">{{ instance.comments }}</div> +</div> diff --git a/scipost_django/journals/urls/general.py b/scipost_django/journals/urls/general.py index 0ec0d9fb6a25f43efbcc2311d93d46bc1e209022..27375abf33a66b38214722fc23b9a07a9e303070 100644 --- a/scipost_django/journals/urls/general.py +++ b/scipost_django/journals/urls/general.py @@ -174,6 +174,21 @@ urlpatterns = [ journals_views.draft_accompanying_publication, name="draft_accompanying_publication", ), + path( + "admin/<publication_doi_label:doi_label>/manage_publication_resources", + journals_views.manage_publication_resources, + name="manage_publication_resources", + ), + path( + "admin/<publication_doi_label:doi_label>/_hx_publication_resource/<int:pk>", + journals_views.HTMXInlinePublicationResourceFormView.as_view(), + name="_hx_publication_resource", + ), + path( + "admin/<publication_doi_label:doi_label>/_hx_publication_resource_list", + journals_views.HTMXInlinePublicationResourceListView.as_view(), + name="_hx_publication_resource_list", + ), # Admin: Volumes and Issues path( "admin/volumes/", diff --git a/scipost_django/journals/views.py b/scipost_django/journals/views.py index 8992284356e389778a63a4a1e6fec664a6047b39..119b3ab0dc7f2330ea9ecdd3577f5957d0ee455e 100644 --- a/scipost_django/journals/views.py +++ b/scipost_django/journals/views.py @@ -27,6 +27,7 @@ from django.contrib import messages from django.db import transaction from django.db.models import Q from django.http import Http404, HttpResponse +from django.template.response import TemplateResponse from django.utils import timezone from django.utils.decorators import method_decorator from django.utils.html import format_html @@ -56,10 +57,12 @@ from .models import ( OrgPubFraction, PublicationUpdate, AutogeneratedFileContentTemplate, + PublicationResource, ) from .forms import ( AbstractJATSForm, FundingInfoForm, + HTMXInlinePublicationResourceForm, VolumeForm, IssueForm, AuthorsTableOrganizationSelectForm, @@ -82,6 +85,7 @@ from .utils import JournalUtils from comments.models import Comment from common.utils import get_current_domain +from common.views import HTMXInlineCRUDModelFormView, HTMXInlineCRUDModelListView from funders.forms import FunderSelectForm, GrantSelectForm from funders.models import Grant, Funder from mails.views import MailEditorSubview @@ -684,6 +688,38 @@ def draft_accompanying_publication(request, doi_label): return render(request, "journals/draft_accompanying_publication.html", context) +def manage_publication_resources(request, doi_label): + publication = get_object_or_404(Publication, doi_label=doi_label) + context = { + "publication": publication, + } + return TemplateResponse( + request, "journals/manage_publication_resources.html", context + ) + + +class HTMXInlinePublicationResourceListView(HTMXInlineCRUDModelListView): + model = PublicationResource + model_form_view_url = "journals:_hx_publication_resource" + add_form_class = HTMXInlinePublicationResourceForm + + def get_queryset(self): + self.doi = self.kwargs.get("doi_label") + self.publication = get_object_or_404(Publication, doi_label=self.doi) + resources = PublicationResource.objects.filter(publication=self.publication) + return self._append_model_form_view_url(resources, doi_label=self.doi) + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["publication"] = self.publication + return context + + +class HTMXInlinePublicationResourceFormView(HTMXInlineCRUDModelFormView): + form_class = HTMXInlinePublicationResourceForm + instance_li_template_name = "journals/publication_resource_li.html" + + class DraftPublicationApprovalView(PermissionsMixin, UpdateView): permission_required = "scipost.can_draft_publication" queryset = Publication.objects.drafts()