Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 4 additions & 10 deletions src/coda/apps/fundingrequests/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,10 @@
from coda.apps.fundingrequests.views.requestimport import import_fundingrequests
from coda.apps.fundingrequests.views.wizard.create_article import ArticleRequestWizard
from coda.apps.fundingrequests.views.wizard.create_monograph import MonographRequestWizard
from coda.apps.fundingrequests.views.wizard.steps.journal_step import (
clear_journal_error,
find_journal,
)
from coda.apps.fundingrequests.views.wizard.steps._search_views import clear_validation_error
from coda.apps.fundingrequests.views.wizard.steps.journal_step import find_journal
from coda.apps.fundingrequests.views.wizard.steps.publication_step import add_linkrow, parse_authors
from coda.apps.fundingrequests.views.wizard.steps.publisher_step import (
clear_publisher_error,
find_publisher,
)
from coda.apps.fundingrequests.views.wizard.steps.publisher_step import find_publisher
from coda.apps.fundingrequests.views.wizard.update_article import (
UpdateExtraInformationView,
UpdateFundingView,
Expand Down Expand Up @@ -226,6 +221,5 @@
path("partial/search-publisher/", find_publisher, name="wizard_find_publisher"),
path("partial/search-journal/", find_journal, name="wizard_find_journal"),
path("contract/inactive", include_inactive_contracts, name="include_inactive_contracts"),
path("clear-journal-error/", clear_journal_error, name="clear_journal_error"),
path("clear-publisher-error/", clear_publisher_error, name="clear_publisher_error"),
path("clear-validation-error/", clear_validation_error, name="clear_validation_error"),
]
8 changes: 1 addition & 7 deletions src/coda/apps/fundingrequests/views/doi_preview.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,14 +217,13 @@ def _format_error(self, e: DOIAlreadyImported) -> SafeString:

def _render_article_type_form(
request: HttpRequest,
session_key: str,
*,
error: str = "",
) -> HttpResponse:
"""Render the article type-change form partial. Journal search is handled by wizard_find_journal."""
context: dict[str, Any] = {
"session_key": session_key,
"journals": [],
"suggested_journal": request.POST.get("journal_title", ""),
}
if error:
context["error"] = error
Expand All @@ -233,17 +232,14 @@ def _render_article_type_form(

def _render_monograph_type_form(
request: HttpRequest,
session_key: str,
original_metadata: dict[str, Any],
*,
error: str = "",
) -> HttpResponse:
"""Render the monograph type-change form partial, pre-filling from original metadata."""
suggested_publisher = request.POST.get("publisher_name", original_metadata.get("publisher", ""))
context: dict[str, Any] = {
"session_key": session_key,
"suggested_publisher": suggested_publisher,
"publishers": [],
}
if error:
context["error"] = error
Expand Down Expand Up @@ -304,7 +300,6 @@ def doi_preview_apply_type_change(request: HttpRequest, session_key: str) -> Htt
if not journal_id_str:
return _render_article_type_form(
request,
session_key,
error="Please select a journal before applying.",
)

Expand All @@ -315,7 +310,6 @@ def doi_preview_apply_type_change(request: HttpRequest, session_key: str) -> Htt
if not publisher_id_str:
return _render_monograph_type_form(
request,
session_key,
original_metadata,
error="Please select a publisher before applying.",
)
Expand Down
20 changes: 5 additions & 15 deletions src/coda/apps/fundingrequests/views/wizard/steps/_search_views.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
"""
Factory for HTMX entity search views.

All generated views require POST and login. The ``row_template`` context variable
is injected so callers can override it per deployment context — for example, the
DOI import preview page supplies a stripped-down row template that omits wizard-
specific HTMX interactions (clear_*_error) that don't exist in that context.
"""

from collections.abc import Callable, Iterable
Expand All @@ -22,7 +17,6 @@ def make_search_view(
search_fn: Callable[[str], Iterable[Any]],
results_key: str,
results_template: str,
default_row_template: str,
) -> Callable[[HttpRequest], HttpResponse]:
"""Return an HTMX search view for a given entity type.

Expand All @@ -32,29 +26,25 @@ def make_search_view(
returns a sequence of matching model instances.
results_key: Template context key under which results are passed.
results_template: Path to the search-results partial template.
default_row_template: Path to the row partial used when no override
is supplied by the caller.
"""

@login_required
@require_POST
def _view(request: HttpRequest) -> HttpResponse:
search_term = request.POST.get(param_name, "").strip()
results = search_fn(search_term)
row_template_override = request.POST.get("row_template", "")
row_template = (
row_template_override
if row_template_override.startswith("fundingrequests/partials/")
else default_row_template
)
return render(
request,
results_template,
{
results_key: results,
"search_term": search_term,
"row_template": row_template,
},
)

return _view

@require_POST
def clear_validation_error(request: HttpRequest) -> HttpResponse:
"""Empty acknowledgement; htmx swaps it into an inline error list to clear it."""
return HttpResponse()
18 changes: 1 addition & 17 deletions src/coda/apps/fundingrequests/views/wizard/steps/journal_step.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import logging
from typing import Any

from django.contrib.auth.decorators import login_required
from django.http import HttpRequest, HttpResponse
from django.http import HttpRequest
from django.shortcuts import get_object_or_404
from django.shortcuts import render

from coda.apps.fundingrequests.forms import ContractFormset
from coda.apps.fundingrequests.views.wizard.steps._search_views import make_search_view
Expand All @@ -14,8 +12,6 @@
from coda.apps.journals import services as journal_services
from coda.apps.wizard import Store, TemplateStep

from django.views.decorators.http import require_POST


class JournalContractStep(ComposedStep):
def __init__(self) -> None:
Expand Down Expand Up @@ -63,21 +59,9 @@ def done(self, request: HttpRequest, store: Store) -> None:
logging.info(f"Journal step done. Journal: {store['journal']}")


@login_required
@require_POST
def clear_journal_error(request: HttpRequest) -> HttpResponse:
journal_title = request.POST.get("journal_title", "")
return render(
request,
"fundingrequests/partials/clear_journal_error.html",
{"journal_title": journal_title},
)


find_journal = make_search_view(
param_name="journal_title",
search_fn=journal_services.find_by_title,
results_key="journals",
results_template="fundingrequests/partials/journal_search_results.html",
default_row_template="fundingrequests/partials/journal_row.html",
)
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
from typing import Any

from django.contrib.auth.decorators import login_required
from django.http import HttpRequest, HttpResponse
from django.shortcuts import render
from django.views.decorators.http import require_POST
from django.http import HttpRequest

from coda.apps.dto import CodaBaseDto
from coda.apps.fundingrequests.forms import ContractFormset
Expand Down Expand Up @@ -80,21 +77,9 @@ def done(self, request: HttpRequest, store: Store) -> None:
store.save()


@login_required
@require_POST
def clear_publisher_error(request: HttpRequest) -> HttpResponse:
publisher_name = request.POST.get("publisher_name", "")
return render(
request,
"fundingrequests/partials/clear_publisher_error.html",
{"publisher_name": publisher_name},
)


find_publisher = make_search_view(
param_name="publisher_name",
search_fn=publisher_services.find_by_name_contains,
results_key="publishers",
results_template="fundingrequests/partials/publisher_search_results.html",
default_row_template="fundingrequests/partials/publisher_row.html",
)
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@ <h2 class="mb-2">Find Journal</h2>
class="inline-search-pill pill-right">Search</button>
</fieldset>
{% if journal_error and request.method == "POST" and not selected_journal %}
<ul class="errorlist" id="journal-error">
<ul class="errorlist"
id="journal-error"
hx-post="{% url 'fundingrequests:clear_validation_error' %}"
hx-trigger="change from:input[name='journal'] once"
hx-target="this"
hx-swap="innerHTML">
<li>{{ journal_error }}</li>
</ul>
{% endif %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@ <h2 class="mb-2">Find Publisher</h2>
class="inline-search-pill pill-right">Search</button>
</fieldset>
{% if publisher_error and request.method == "POST" and not selected_publisher %}
<ul class="errorlist" id="publisher-error">
<ul class="errorlist"
id="publisher-error"
hx-post="{% url 'fundingrequests:clear_validation_error' %}"
hx-trigger="change from:input[name='publisher'] once"
hx-target="this"
hx-swap="innerHTML">
<li>{{ publisher_error }}</li>
</ul>
{% endif %}
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,29 +1,26 @@
{# Form for changing to article type - requires journal selection #}
{# Parameters: session_key, journals, selected_journal, error #}
{# Note: form submission requires JavaScript (HTMX). Non-JS fallback is not supported. #}
<form method="post"
action="{% url 'fundingrequests:doi_preview_apply_type_change' session_key=session_key %}"
hx-post="{% url 'fundingrequests:doi_preview_apply_type_change' session_key=session_key %}"
hx-target="#type-change-form"
hx-swap="innerHTML">
{% csrf_token %}
<input type="hidden" name="publication_type" value="article">
<input type="hidden"
name="row_template"
value="fundingrequests/partials/doi_journal_row.html">
<h4 class="mt-1">Select Journal</h4>
<p class="text-muted">Search for the journal where this article was published.</p>
{% if error %}<p class="error">{{ error }}</p>{% endif %}
<fieldset role="group">
<input type="search"
name="journal_title"
id="journal_title"
placeholder="Search journal by title...">
<button type="button"
hx-post="{% url 'fundingrequests:wizard_find_journal' %}"
hx-target="#journal-search-results"
hx-swap="outerHTML"
class="inline-search-pill pill-right">Search</button>
</fieldset>
{% include "fundingrequests/partials/journal_search_results.html" %}
</form>
{# Parameters: journals, suggested_journal, error #}
{# Note: the whole flow requires JavaScript (HTMX). Non-JS fallback is not supported. #}
{# There is deliberately no form element: the Apply button posts while hx-including #}
{# the #type-change-form wrapper, and keeping the inputs out of a form means Enter in #}
{# the search field can only trigger the journal search, never a submit. #}
<h4 class="mt-1">Select Journal</h4>
<p class="text-muted">Search for the journal where this article was published.</p>
{% if error %}<p class="error">{{ error }}</p>{% endif %}
<fieldset role="group"
hx-post="{% url 'fundingrequests:wizard_find_journal' %}"
hx-target="#journal-search-results"
hx-include="#journal_title"
hx-swap="outerHTML"
hx-trigger="keydown[key=='Enter'] from:#journal_title, click from:#journal_search_button">
<input type="search"
name="journal_title"
id="journal_title"
placeholder="Search journal by title..."
value="{{ suggested_journal }}">
<button type="button"
id="journal_search_button"
class="inline-search-pill pill-right">Search</button>
</fieldset>
<input type="hidden" name="publication_type" value="article">
{% include "fundingrequests/partials/journal_search_results.html" %}
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
{# Form for changing to monograph type - requires publisher selection #}
{# Parameters: session_key, suggested_publisher, publishers, selected_publisher, error #}
{# Note: form submission requires JavaScript (HTMX). Non-JS fallback is not supported. #}
{# Note: publisher results are loaded via wizard_find_publisher HTMX endpoint (outerHTML swap), #}
{# not from template context, so the submit button is always visible unlike the article form. #}
<form method="post">
{% csrf_token %}
<input type="hidden" name="publication_type" value="monograph">
<h4 class="mt-1">Select Publisher</h4>
<p class="text-muted">Search for the publisher of this monograph.</p>
{% if error %}<p class="error">{{ error }}</p>{% endif %}
<fieldset role="group">
<input type="search"
name="publisher_name"
id="publisher_name"
placeholder="Search publisher by name..."
value="{{ suggested_publisher }}">
<button type="button"
hx-post="{% url 'fundingrequests:wizard_find_publisher' %}"
hx-include="[name='publisher_name']"
hx-target="#publisher-search-results"
hx-swap="outerHTML"
class="inline-search-pill pill-right">Search</button>
</fieldset>
{% include "fundingrequests/partials/publisher_search_results.html" %}
</form>
{# Parameters: suggested_publisher, error #}
{# Note: the whole flow requires JavaScript (HTMX). Non-JS fallback is not supported. #}
{# Publisher results are loaded via the wizard_find_publisher HTMX endpoint (outerHTML #}
{# swap), not from template context. There is deliberately no form element: the Apply #}
{# button hx-includes the #type-change-form wrapper, so Enter can only trigger the #}
{# publisher search. #}
<h4 class="mt-1">Select Publisher</h4>
<p class="text-muted">Search for the publisher of this monograph.</p>
{% if error %}<p class="error">{{ error }}</p>{% endif %}
<fieldset role="group"
hx-post="{% url 'fundingrequests:wizard_find_publisher' %}"
hx-target="#publisher-search-results"
hx-include="#publisher_name"
hx-swap="outerHTML"
hx-trigger="keydown[key=='Enter'] from:#publisher_name, click from:#publisher_search_button">
<input type="search"
name="publisher_name"
id="publisher_name"
placeholder="Search publisher by name..."
value="{{ suggested_publisher }}">
<button type="button"
id="publisher_search_button"
class="inline-search-pill pill-right">Search</button>
</fieldset>
<input type="hidden" name="publication_type" value="monograph">
{% include "fundingrequests/partials/publisher_search_results.html" %}
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{# Context: journal, selected_journal #}
<tr>
<td>{{ journal.title }}</td>
<td>
<label for="journal-{{ journal.pk }}">{{ journal.title }}</label>
</td>
<td>{{ journal.publisher.name }}</td>
<td>
<input type="radio"
id="journal-{{ journal.pk }}"
name="journal"
hx-target="#journal-error"
hx-swap="outerHTML"
hx-post="{% url 'fundingrequests:clear_journal_error' %}"
value="{{ journal.pk }}"
{% if journal.pk == selected_journal.pk %}checked{% endif %}>
</td>
Expand Down
Loading