diff --git a/scipost_django/scipost/templates/scipost/portal/_hx_submissions.html b/scipost_django/scipost/templates/scipost/portal/_hx_submissions.html index 701068c675b1c12232f0b1cbff28d4dee9ad00a0..20e7cabebed8a02e574b81b6e2d153308b095aae 100644 --- a/scipost_django/scipost/templates/scipost/portal/_hx_submissions.html +++ b/scipost_django/scipost/templates/scipost/portal/_hx_submissions.html @@ -1,12 +1,50 @@ {% load journals_extras %} -<h2 class="mb-0 px-3">Submissions in {{ session_acad_field }}: {% if session_specialty %}{{ session_specialty }}{% else %}(all specialties){% endif %}</h2> +{% load crispy_forms_tags %} -<hr> -<div hx-get="{% url 'scipost:_hx_submissions_page' %}?page=1" - hx-trigger="load" - hx-target="#submissions-list" -> +<div class="d-flex justify-content-between"> + <button class="btn btn-outline-primary" data-bs-toggle="collapse" data-bs-target="#submissionsSearch" aria-expanded="false" aria-controls="submissionsSearch"> + Simple search / filter + </button> + <a class="btn btn-outline-primary ms-2" href="{% url 'scipost:search' %}"> + ... or use our advanced search API {% include 'bi/arrow-right.html' %} + </a> </div> -<ul id="submissions-list" - class="list-group list-group-flush list-unstyled px-3 mb-3"></ul> +<div class="collapse" id="submissionsSearch"> + <div class="card card-body"> + <form + hx-post="{% url 'scipost:portal_hx_submissions_page' %}?page=1" + hx-trigger="load, keyup delay: 500ms, change" + hx-target="#submissions-search-results" + hx-indicator="#indicator-submissions-search" + > + <div id="submissions-search-form">{% crispy submissions_search_form %}</div> + </form> + </div> + <div id="indicator-submissions-search" class="htmx-indicator p-2"> + <button class="btn btn-warning" type="button" disabled> + <strong>Loading...</strong> + <div class="spinner-grow spinner-grow-sm ms-2" role="status" aria-hidden="true"></div> + </button> + </div> +</div> + +<h2 class="highlight mb-0">Submissions in {{ session_acad_field }}: {% if session_specialty %}{{ session_specialty }}{% else %}(all specialties){% endif %}</h2> + +<ul id="submissions-search-results" class="list-unstyled pool-list mt-2"></ul> + + + +{% block footer_script %} + <script nonce="{{ requeest.csp_nonce }}"> + /* If Proceedings is chosen as Journal, display Proceedings selector */ + document.getElementById("id_submitted_to").addEventListener("change", () => { + var e = document.getElementById("id_submitted_to") + if (e.options[e.selectedIndex].text.includes('Proceedings')) { + document.getElementById("row_proceedings").style.display = 'block' + } else { + document.getElementById("row_proceedings").style.display = 'none' + document.getElementById("id_proceedings").value = null + } + }) +{% endblock footer_script %} diff --git a/scipost_django/scipost/templates/scipost/portal/_hx_submissions_page.html b/scipost_django/scipost/templates/scipost/portal/_hx_submissions_page.html index 52f502f9ed2d13eea2e1806c47929d94c60fc559..862fb37b7b67b83a29a3ddd86889baca8fbe03e8 100644 --- a/scipost_django/scipost/templates/scipost/portal/_hx_submissions_page.html +++ b/scipost_django/scipost/templates/scipost/portal/_hx_submissions_page.html @@ -10,7 +10,8 @@ {% if page_obj.has_next %} <li id="next-submissions-{{ page_obj.number }}"> <button class="btn btn-primary m-2" type="button" - hx-get="{% url 'scipost:_hx_submissions_page' %}?page={{ page_obj.next_page_number }}" + hx-post="{% url 'scipost:portal_hx_submissions_page' %}?page={{ page_obj.next_page_number }}" + hx-include="#submissions-search-form" hx-target="#next-submissions-{{ page_obj.number }}" hx-swap="outerHTML" hx-indicator="#indicator-submissions-page-{{ page_obj.number }}" diff --git a/scipost_django/scipost/templates/scipost/portal/portal.html b/scipost_django/scipost/templates/scipost/portal/portal.html index 4484c3d5834591a7959d86025c0dc8909ce6a0a2..f952e7dd28c59bb7926fa8a18267f4cf6078a778 100644 --- a/scipost_django/scipost/templates/scipost/portal/portal.html +++ b/scipost_django/scipost/templates/scipost/portal/portal.html @@ -94,8 +94,8 @@ <div class="tab-pane fade" id="submissions" role="tabpanel" aria-labelledby="submissions-tab"> - <div hx-get="{% url 'scipost:_hx_submissions' %}" - hx-trigger="load, session-acad-field-set from:body, session-specialty-set from:body" + <div hx-get="{% url 'scipost:portal_hx_submissions' %}" + hx-trigger="load, clicked from:#submissions-tab, session-acad-field-set from:body, session-specialty-set from:body" > </div> </div> diff --git a/scipost_django/scipost/urls.py b/scipost_django/scipost/urls.py index f245b494183faa5684e01c0964a003759ebba91d..c846a92651c0967a61801b9e403db770426e5267 100644 --- a/scipost_django/scipost/urls.py +++ b/scipost_django/scipost/urls.py @@ -99,14 +99,14 @@ urlpatterns = [ name='portal_hx_publications_page' ), path( - '_hx_submissions', - TemplateView.as_view(template_name='scipost/portal/_hx_submissions.html'), - name='_hx_submissions' + 'portal/_hx_submissions', + views.portal_hx_submissions, + name='portal_hx_submissions' ), path( - '_hx_submissions_page', - views._hx_submissions_page, - name='_hx_submissions_page' + 'portal/_hx_submissions_page', + views.portal_hx_submissions_page, + name='portal_hx_submissions_page' ), path( '_hx_news.html', diff --git a/scipost_django/scipost/views.py b/scipost_django/scipost/views.py index dc527e2704e60b0b164d9632306f7fa5cc585fbe..d323e0c5926ff1660e97834d173b8c124a6f53d9 100644 --- a/scipost_django/scipost/views.py +++ b/scipost_django/scipost/views.py @@ -67,6 +67,7 @@ from organizations.models import Organization, Contact from organizations.forms import UpdateContactDataForm from profiles.models import Profile from submissions.models import Submission, RefereeInvitation, Report, EICRecommendation +from submissions.forms import SubmissionSearchForm from theses.models import ThesisLink @@ -222,8 +223,8 @@ def portal_hx_publications_page(request): publications = Publication.objects.published() if session_acad_field_slug and session_acad_field_slug != 'all': publications = publications.filter(acad_field__slug=session_acad_field_slug) - if session_specialty_slug: - publications = publications.filter(specialties__slug=session_specialty_slug) + if session_specialty_slug: + publications = publications.filter(specialties__slug=session_specialty_slug) paginator = Paginator(publications, 10) page_nr = request.GET.get('page') page_obj = paginator.get_page(page_nr) @@ -231,14 +232,33 @@ def portal_hx_publications_page(request): return render(request, 'scipost/portal/_hx_publications_page.html', context) -def _hx_submissions_page(request): - submissions = Submission.objects.public() +def portal_hx_submissions(request): + form = SubmissionSearchForm( + acad_field_slug=request.session.get('session_acad_field_slug', None), + specialty_slug=request.session.get('session_specialty_slug', None) + ) + context = { + 'submissions_search_form': form + } + return render(request, 'scipost/portal/_hx_submissions.html', context) + + +def portal_hx_submissions_page(request): session_acad_field_slug = request.session.get('session_acad_field_slug', None) - if session_acad_field_slug and session_acad_field_slug != 'all': - submissions = submissions.filter(acad_field__slug=session_acad_field_slug) session_specialty_slug = request.session.get('session_specialty_slug', None) - if session_specialty_slug: - submissions = submissions.filter(specialties__slug=session_specialty_slug) + form = SubmissionSearchForm( + request.POST or None, + acad_field_slug=session_acad_field_slug, + specialty_slug=session_specialty_slug, + ) + if form.is_valid(): + submissions = form.search_results() + else: + submissions = Submission.objects.public() + if session_acad_field_slug and session_acad_field_slug != 'all': + submissions = submissions.filter(acad_field__slug=session_acad_field_slug) + if session_specialty_slug: + submissions = submissions.filter(specialties__slug=session_specialty_slug) paginator = Paginator(submissions, 10) page_nr = request.GET.get('page') page_obj = paginator.get_page(page_nr) diff --git a/scipost_django/submissions/forms.py b/scipost_django/submissions/forms.py index 30c4ecdf8fdc0ecfa214d8a931ab062877130c54..f3ba6e75f7824dbb1afee896b156c110b2389fa2 100644 --- a/scipost_django/submissions/forms.py +++ b/scipost_django/submissions/forms.py @@ -65,6 +65,80 @@ FIGSHARE_IDENTIFIER_PATTERN = r'^[0-9]+\.v[0-9]{1,2}$' OSFPREPRINTS_IDENTIFIER_PATTERN = r'^[a-z0-9]+$' +class SubmissionSearchForm(forms.Form): + author = forms.CharField( + max_length=100, + required=False, + label="Author(s)" + ) + title = forms.CharField( + max_length=100, + required=False + ) + submitted_to = forms.ModelChoiceField( + queryset=Journal.objects.active(), + required=False + ) + identifier = forms.CharField( + max_length=128, + required=False + ) + proceedings = forms.ModelChoiceField( + queryset=Proceedings.objects.order_by('-submissions_close'), + required=False + ) + def __init__(self, *args, **kwargs): + self.acad_field_slug = kwargs.pop('acad_field_slug') + self.specialty_slug = kwargs.pop('specialty_slug') + super().__init__(*args, **kwargs) + if self.acad_field_slug: + self.fields['submitted_to'].queryset = Journal.objects.filter( + college__acad_field__slug=self.acad_field_slug + ) + self.helper = FormHelper() + self.helper.layout = Layout( + Div( + Div(FloatingField('author'), css_class='col-lg-6'), + Div(FloatingField('title'), css_class='col-lg-6'), + css_class='row mb-0' + ), + Div( + Div(FloatingField('submitted_to'), css_class='col-lg-6'), + Div(FloatingField('identifier'), css_class='col-lg-6'), + css_class='row mb-0' + ), + Div( + Div(FloatingField('proceedings'), css_class='col-lg-6'), + css_class='row mb-0', + css_id='row_proceedings', + style='display: none' + ), + ) + + def search_results(self): + """ + Return all Submission objects fitting search criteria. + """ + submissions = Submission.objects.public_newest() + if self.acad_field_slug != 'all': + submissions = submissions.filter(acad_field__slug=self.acad_field_slug) + if self.specialty_slug: + submissions = submissions.filter(specialties__slug=self.specialty_slug) + if self.cleaned_data.get('submitted_to'): + submissions = submissions.filter(submitted_to=self.cleaned_data.get('submitted_to')) + if self.cleaned_data.get('proceedings'): + submissions = submissions.filter(proceedings=self.cleaned_data.get('proceedings')) + if self.cleaned_data.get('author'): + submissions = submissions.filter(author_list__icontains=self.cleaned_data.get('author')) + if self.cleaned_data.get('title'): + submissions = submissions.filter(title__icontains=self.cleaned_data.get('title')) + if self.cleaned_data.get('identifier'): + submissions = submissions.filter( + preprint__identifier_w_vn_nr__icontains=self.cleaned_data.get('identifier') + ) + return submissions + + class SubmissionPoolSearchForm(forms.Form): """Filter a Submission queryset using basic search fields.""" @@ -265,7 +339,8 @@ class SubmissionPoolSearchForm(forms.Form): return submissions -class SubmissionSearchForm(forms.Form): +# Marked for deprecation +class SubmissionOldSearchForm(forms.Form): """Filter a Submission queryset using basic search fields.""" author = forms.CharField(max_length=100, required=False, label="Author(s)") diff --git a/scipost_django/submissions/views.py b/scipost_django/submissions/views.py index 95a41604b38be3a20c0e968b26088ee14a522e58..81c8370f216fc1cbcad4c8f0cc107982b9bb0746 100644 --- a/scipost_django/submissions/views.py +++ b/scipost_django/submissions/views.py @@ -47,7 +47,7 @@ from .mixins import SubmissionMixin, SubmissionAdminViewMixin from .forms import ( SciPostPrefillForm, ArXivPrefillForm, ChemRxivPrefillForm, FigsharePrefillForm, OSFPreprintsPrefillForm, - SubmissionForm, SubmissionPoolSearchForm, SubmissionSearchForm, RecommendationVoteForm, + SubmissionForm, SubmissionPoolSearchForm, SubmissionOldSearchForm, RecommendationVoteForm, ConsiderAssignmentForm, EditorialAssignmentForm, VetReportForm, SetRefereeingDeadlineForm, RefereeSearchForm, iThenticateReportForm, VotingEligibilityForm, WithdrawSubmissionForm, @@ -443,11 +443,12 @@ def withdraw_manuscript(request, identifier_w_vn_nr): return render(request, 'submissions/withdraw_manuscript.html', context) +# Marked for deprecation class SubmissionListView(PaginationMixin, ListView): """List all publicly available Submissions.""" model = Submission - form = SubmissionSearchForm + form = SubmissionOldSearchForm submission_search_list = [] paginate_by = 10