Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pids: pass optional DOI transitions in the upload form #2958

Merged
merged 2 commits into from
Jan 21, 2025
Merged
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
21 changes: 21 additions & 0 deletions invenio_app_rdm/records_ui/views/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -403,3 +403,24 @@ def view(**kwargs):
return view

return decorator


def no_cache_response(f):
"""Add appropriate response headers to force no caching.

This decorator is used to prevent caching of the response in the browser. This is needed
in the deposit form as we initialize the form with the record metadata included in the html page
and we don't want the browser to cache this page so that the user always gets the latest version of the record.
"""

@wraps(f)
def view(*args, **kwargs):
response = make_response(f(*args, **kwargs))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: I would check if the func already returns a Response, in that case we don't need the make_response, so it can be used by all funcs.

Suggested change
response = make_response(f(*args, **kwargs))
result = f(*args, **kwargs)
if isinstance(result, Response):
response = result
else:
response = make_response(result)```


response.cache_control.no_cache = True
response.cache_control.no_store = True
response.cache_control.must_revalidate = True

return response

return view
40 changes: 38 additions & 2 deletions invenio_app_rdm/records_ui/views/deposits.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from invenio_rdm_records.proxies import current_rdm_records
from invenio_rdm_records.records.api import get_files_quota
from invenio_rdm_records.resources.serializers import UIJSONSerializer
from invenio_rdm_records.services.components.pids import _get_optional_doi_transitions
from invenio_rdm_records.services.schemas import RDMRecordSchema
from invenio_rdm_records.services.schemas.utils import dump_empty
from invenio_records_resources.services.errors import PermissionDeniedError
Expand All @@ -34,6 +35,7 @@

from ..utils import set_default_value
from .decorators import (
no_cache_response,
pass_draft,
pass_draft_community,
pass_draft_files,
Expand All @@ -45,7 +47,7 @@
#
# Helpers
#
def get_form_pids_config():
def get_form_pids_config(record=None):
"""Prepare configuration for the pids field.

Currently supporting only doi.
Expand All @@ -55,17 +57,45 @@ def get_form_pids_config():
# FIXME: User provider.is_managed() requires tiny fix in config
can_be_managed = True
can_be_unmanaged = True
# We initialize the optional doi to empty to indicate that there is no restriction on the transitions
# This is valid for new uploads and when the DOI is required in an instance
optional_doi_transitions = []
for scheme in service.config.pids_providers.keys():
if not scheme == "doi":
continue

record_pid_config = current_app.config["RDM_PERSISTENT_IDENTIFIERS"]
scheme_label = record_pid_config.get(scheme, {}).get("label", scheme)
is_doi_required = record_pid_config.get(scheme, {}).get("required")
default_selected = (
record_pid_config.get(scheme, {}).get("ui", {}).get("default_selected")
)
if record is not None and not is_doi_required:
sitename = current_app.config.get("THEME_SITENAME", "this repository")
previous_published_record = (
service.record_cls.get_latest_published_by_parent(record.parent)
)
optional_doi_transitions = _get_optional_doi_transitions(
previous_published_record
)
if optional_doi_transitions:
optional_doi_transitions["message"] = optional_doi_transitions.get(
"message"
).format(sitename=sitename)
if set(optional_doi_transitions.get("allowed_providers", [])) - set(
["external", "not_needed"]
):
# In case we have locally managed provider as an allowed one, we need to
# select it by default. That is relevant for the case when the
# user creates a new version of the record and the previous version
# had a datacite DOI.
default_selected = "no"

# if the DOI is required but the default selected is not_needed then we set it to yes
# to force the user to mint a DOI
if is_doi_required and default_selected == "not_needed":
default_selected = "yes"

pids_provider = {
"scheme": scheme,
"field_label": "Digital Object Identifier",
Expand All @@ -89,6 +119,7 @@ def get_form_pids_config():
"unambiguously cited. Example: 10.1234/foo.bar"
).format(scheme_label=scheme_label),
"default_selected": default_selected,
"optional_doi_transitions": optional_doi_transitions,
}
pids_providers.append(pids_provider)

Expand Down Expand Up @@ -332,14 +363,16 @@ def get_form_config(**kwargs):
if record_quota:
quota["maxStorage"] = record_quota["quota_size"]

record = kwargs.pop("record", None)

return dict(
vocabularies=VocabulariesOptions().dump(),
autocomplete_names=conf.get(
"APP_RDM_DEPOSIT_FORM_AUTOCOMPLETE_NAMES", "search"
),
current_locale=str(current_i18n.locale),
default_locale=conf.get("BABEL_DEFAULT_LOCALE", "en"),
pids=get_form_pids_config(),
pids=get_form_pids_config(record=record),
quota=quota,
decimal_size_display=conf.get("APP_RDM_DISPLAY_DECIMAL_FILE_SIZES", True),
links=dict(
Expand Down Expand Up @@ -390,6 +423,7 @@ def new_record():
# Views
#
@login_required
@no_cache_response
@pass_draft_community
def deposit_create(community=None):
"""Create a new deposit."""
Expand Down Expand Up @@ -441,6 +475,7 @@ def deposit_create(community=None):
@secret_link_or_login_required()
@pass_draft(expand=True)
@pass_draft_files
@no_cache_response
def deposit_edit(pid_value, draft=None, draft_files=None, files_locked=True):
"""Edit an existing deposit."""
# don't show draft's deposit form if the user can't edit it
Expand Down Expand Up @@ -490,6 +525,7 @@ def deposit_edit(pid_value, draft=None, draft_files=None, files_locked=True):
# hide react community component
hide_community_selection=community_use_jinja_header,
is_doi_required=is_doi_required,
record=draft._record,
)

if is_doi_required and not record.get("pids", {}).get("doi"):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ export class RDMDepositForm extends Component {
btnLabelGetPID={pid.btn_label_get_pid}
canBeManaged={pid.can_be_managed}
canBeUnmanaged={pid.can_be_unmanaged}
optionalDOItransitions={pid.optional_doi_transitions}
fieldPath={`pids.${pid.scheme}`}
fieldLabel={pid.field_label}
isEditingPublishedRecord={
Expand Down
Loading