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

IQSS/8431 Optional Version Note #11068

Open
wants to merge 52 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
75f4669
Version creation note column, flag, api
qqmyers Oct 31, 2024
3eda854
check for flag in apis
qqmyers Oct 31, 2024
464aad4
fix flag string
qqmyers Oct 31, 2024
6ae9a52
basic creationNote in version table
qqmyers Oct 31, 2024
6a52b7c
creationNote dialog
qqmyers Nov 1, 2024
4407cb7
typo on hides
qqmyers Nov 1, 2024
3de6956
Add separate method/success msg
qqmyers Nov 1, 2024
1e8da09
add edit in table
qqmyers Nov 1, 2024
db08d5a
call save again
qqmyers Nov 1, 2024
f529c51
typo
qqmyers Nov 1, 2024
f6b8a98
really add save
qqmyers Nov 1, 2024
fbda72e
pass workingVersion, only allow edit when on draft page
qqmyers Nov 1, 2024
13d1815
shorten name
qqmyers Nov 1, 2024
41232ac
Add div to cause button to be on next line
qqmyers Nov 1, 2024
96a0cf5
add note to json, ddi, datacite
qqmyers Nov 1, 2024
49a191a
add null check
qqmyers Nov 1, 2024
95e7142
fix curate command handling of creation note
qqmyers Nov 1, 2024
76e13f6
fix update
qqmyers Nov 1, 2024
0f1eb8c
update ORE export
qqmyers Nov 1, 2024
0750359
Only :draft for non-superuser
qqmyers Nov 11, 2024
0e770a4
flyway script
qqmyers Nov 11, 2024
6bf3a78
change labels to Version Note
qqmyers Nov 11, 2024
bc3ea41
fix - use separate variable in pub dialog
qqmyers Nov 12, 2024
cd1cbef
changing api creationNote -> versionNote
qqmyers Nov 20, 2024
6eef228
update flyway number before merge
qqmyers Nov 20, 2024
addc30b
Merge remote-tracking branch 'IQSS/develop' into IQSS/8431_Version_Cr…
qqmyers Nov 20, 2024
adc9648
versionN->deaccessionN, creationN->versionN
qqmyers Dec 6, 2024
d5704c5
update deaccession validator
qqmyers Dec 6, 2024
c6fec23
remove unused method
qqmyers Dec 6, 2024
8c51948
creationNote->versionNote changes
qqmyers Dec 6, 2024
a54a6fe
merge archiveNote->deaccesionLink, handle non-URL vals
qqmyers Dec 6, 2024
a309082
update flyway with additional changes
qqmyers Dec 6, 2024
a3b9de9
missed changes, cleanup
qqmyers Dec 6, 2024
986c753
add search
qqmyers Dec 6, 2024
6dfab2e
release/change notes
qqmyers Dec 6, 2024
56988a0
test fix
qqmyers Dec 6, 2024
ef90fa3
docs
qqmyers Dec 6, 2024
6e1c8ad
Merge remote-tracking branch 'IQSS/develop' into
qqmyers Dec 6, 2024
92f4fa7
use outputLink, typos
qqmyers Dec 6, 2024
6e70474
Merge remote-tracking branch 'IQSS/develop' into
qqmyers Dec 12, 2024
ee2b1a1
single quotes
qqmyers Dec 13, 2024
622024f
check if archivenote exists
qqmyers Dec 13, 2024
ffc71d8
use do
qqmyers Dec 13, 2024
65458a1
Merge remote-tracking branch 'IQSS/develop' into IQSS/8431_Version_Cr…
qqmyers Dec 13, 2024
4faa5cd
missing quote
qqmyers Dec 13, 2024
58958ab
add max length for deaccessionLink
qqmyers Dec 13, 2024
42d1332
typo
qqmyers Dec 14, 2024
c53ba93
avoid duplicate id
qqmyers Dec 14, 2024
16f0830
add getVersionNote api call
qqmyers Dec 17, 2024
43c56bf
get version note api
qqmyers Dec 17, 2024
d69b052
doc update
qqmyers Dec 17, 2024
b7bd6a7
fix overflows in version table/difference details
qqmyers Dec 19, 2024
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
2 changes: 2 additions & 0 deletions conf/solr/schema.xml
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,8 @@
<field name="fileChecksumValue" type="string" stored="true" indexed="true" multiValued="false"/>
<field name="fileContentType" type="string" stored="true" indexed="true" multiValued="false"/>
<field name="deaccessionReason" type="string" stored="true" indexed="false" multiValued="false"/>
<field name="versionNote" type="string" stored="true" indexed="false" multiValued="false"/>


<!-- Added for Dataverse 4.0 alpha 1. This is a required field so we don't have to go to the database to get the database id of the entity. On cards we use the id in links -->
<field name="entityId" type="plong" stored="true" indexed="true" multiValued="false"/>
Expand Down
12 changes: 12 additions & 0 deletions doc/release-notes/8431-versionNotes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Dataverse now supports the option of adding a versionNote before/during publication of a dataset that can be used to indicate why a version was created and/or how it differs from the prior version. Whether this feature is enabled is controlled by a flag. Version notes are shown in the user interface (dataset page version table), indexed, available via the API, and have been added to the JSON, DDI, DataCite, and OAI-ORE exports.
pdurbin marked this conversation as resolved.
Show resolved Hide resolved

With the addition of this feature, work has been done to clean-up and rename fields that have been used for specifying the reason for deaccessioning a dataset and providing an optional link to a non-Dataverse location where the dataset still can be found. The former was listed in some JSON-based API calls and exports as "versionNote" and is now "deaccessionNote", while the latter was referred to as "archiveNote" and is now "deacccessionLink". These result in incompatibilities in the UI related to deaccessioned datasets.

Further, some database consolidation has been done to combine the deaccessionlink and archivenote fields which appear to have both been used for the same purpose (the deaccessionlink db field is older and was not displayed in the current UI. Going forward, only the deaccessionlink column exists.

New Feature Flags:

VERSION_NOTE - false by default.

Update of the solr schema (using the standard instructions) is needed.

8 changes: 8 additions & 0 deletions doc/sphinx-guides/source/api/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ This API changelog is experimental and we would love feedback on its usefulness.
:local:
:depth: 1

v6.5
----

- The JSON representation for a datasetVersion sent or received in API calls has changed such that
- "versionNote" -> "deaccessionNote"
- "archiveNote" --> "deaccessionLink"
that may be non-null for deaccessioned versions and an optional new "versionNote" field indicating the reason a version was created may be present on any datasetversion.

v6.4
----

Expand Down
42 changes: 42 additions & 0 deletions doc/sphinx-guides/source/api/native-api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3248,6 +3248,48 @@ The fully expanded example above (without environment variables) looks like this
.. code-block:: bash

curl -H "X-Dataverse-key:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" -X DELETE "https://demo.dataverse.org/api/datasets/datasetTypes/3"

.. _api-dataset-version-note:

Dataset Version Notes
~~~~~~~~~~~~~~~~~~~~~

Intended as :ref:`provenance` information about why the version was created/how it differs from the prior version

Depositors who can edit the dataset and curators can add a version note for the draft version. Superusers can add/delete version notes for any version.

.. code-block:: bash

export API_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
export SERVER_URL=https://demo.dataverse.org
export ID=3
export VERSION=:draft
export NOTE=Files updated to correct typos

curl -H "X-Dataverse-key:$API_TOKEN" -X PUT -d "$NOTE" "$SERVER_URL/api/datasets/$ID/versions/$VERSION/versionNote"

The fully expanded example above (without environment variables) looks like this:

.. code-block:: bash

curl -H "X-Dataverse-key:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" -X PUT -d "Files updated to correct typos" "https://demo.dataverse.org/api/datasets/3/versions/:draft/versionNote"


.. code-block:: bash

export API_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
export SERVER_URL=https://demo.dataverse.org
export ID=3
export VERSION=2.0

curl -H "X-Dataverse-key:$API_TOKEN" -X DELETE "$SERVER_URL/api/datasets/$ID/versions/$VERSION/versionNote"

The fully expanded example above (without environment variables) looks like this:

.. code-block:: bash

curl -H "X-Dataverse-key:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" -X DELETE "https://demo.dataverse.org/api/datasets/3/versions/2.0/versionNote"


Files
-----
Expand Down
6 changes: 5 additions & 1 deletion doc/sphinx-guides/source/installation/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3328,7 +3328,7 @@ This setting is required in conjunction with the ``globus-use-experimental-async
Feature Flags
-------------

Certain features might be deactivated because they are experimental and/or opt-in previews. If you want to enable these,
Certain features might be deactivated because they are experimental and/or opt-in capabilities. If you want to enable these,
please find all known feature flags below. Any of these flags can be activated using a boolean value
(case-insensitive, one of "true", "1", "YES", "Y", "ON") for the setting.

Expand Down Expand Up @@ -3364,6 +3364,10 @@ please find all known feature flags below. Any of these flags can be activated u
* - globus-use-experimental-async-framework
- Activates a new experimental implementation of Globus polling of ongoing remote data transfers that does not rely on the instance staying up continuously for the duration of the transfers and saves the state information about Globus upload requests in the database. Added in v6.4. Affects :ref:`:GlobusPollingInterval`. Note that the JVM option :ref:`dataverse.files.globus-monitoring-server` described above must also be enabled on one (and only one, in a multi-node installation) Dataverse instance.
- ``Off``
* - enable-version-note
- Turns on the ability to add/view per-dataset-version notes intended to provide :ref:`provenance` information about why the dataset/version was created.
- ``Off``


**Note:** Feature flags can be set via any `supported MicroProfile Config API source`_, e.g. the environment variable
``DATAVERSE_FEATURE_XXX`` (e.g. ``DATAVERSE_FEATURE_API_SESSION_AUTH=1``). These environment variables can be set in your shell before starting Payara. If you are using :doc:`Docker for development </container/dev-usage>`, you can set them in the `docker compose <https://docs.docker.com/compose/environment-variables/set-environment-variables/>`_ file.
Expand Down
21 changes: 20 additions & 1 deletion doc/sphinx-guides/source/user/dataset-management.rst
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,26 @@ When you access a dataset's file-level permissions page, you will see two sectio
Data Provenance
===============

Data Provenance is a record of where your data came from and how it reached its current form. It describes the origin of a data file, any transformations that have been made to that file, and any persons or organizations associated with that file. A data file's provenance can aid in reproducibility and compliance with legal regulations. The Dataverse Software can help you keep track of your data's provenance. Currently, the Dataverse Software only makes provenance information available to those who have edit permissions on your dataset, but in the future we plan to expand this feature to make provenance information available to the public.
Dataset-Level
-------------
When configured, the Dataverse software can allow data depositors, curators, and administrators
to provide information about why a new version of a dataset was created and/or how its contents
differ from a prior version. These users can add an optional "Version Note" to a draft dataset
version in the dataset page/versions tab or during publication. This information is publicly
available via the user interface (dataset page/versions tab), API, and in metadata exports
(including the DataCite, JSON, DDI, and OAI_ORE exports).

File-Level
----------

Data Provenance is a record of where your data came from and how it reached its current form.
It describes the origin of a data file, any transformations that have been made to that file,
and any persons or organizations associated with that file. A data file's provenance can aid in
reproducibility and compliance with legal regulations. When configured to support provenance,
the Dataverse Software can help you keep track of your data's provenance. Currently, the Dataverse
Software only makes provenance information available to those who have edit permissions on your
dataset, but in the future we plan to expand this feature to make provenance information available
to the public.

.. COMMENTED OUT UNTIL PROV FILE DOWNLOAD IS ADDED: , and make it available to those who need it.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,28 +13,28 @@
*
* @author skraffmi
*/
public class DatasetVersionNoteValidator implements ConstraintValidator<ValidateVersionNote, DatasetVersion> {
public class DatasetDeaccessionNoteValidator implements ConstraintValidator<ValidateDeaccessionNote, DatasetVersion> {

private String versionState;
private String versionNote;
private String deaccessionNote;

@Override
public void initialize(ValidateVersionNote constraintAnnotation) {
public void initialize(ValidateDeaccessionNote constraintAnnotation) {
versionState = constraintAnnotation.versionState();
versionNote = constraintAnnotation.versionNote();
deaccessionNote = constraintAnnotation.deaccessionNote();
}


@Override
public boolean isValid(DatasetVersion value, ConstraintValidatorContext context) {

if (versionState.equals(DatasetVersion.VersionState.DEACCESSIONED) && versionNote.isEmpty()){
if (versionState.equals(DatasetVersion.VersionState.DEACCESSIONED) && deaccessionNote.isEmpty()){
if (context != null) {
context.buildConstraintViolationWithTemplate(value + " " + BundleUtil.getStringFromBundle("file.deaccessionDialog.dialog.textForReason.error")).addConstraintViolation();
}
return false;
}
if (versionState.equals(DatasetVersion.VersionState.DEACCESSIONED) && versionNote.length() > DatasetVersion.VERSION_NOTE_MAX_LENGTH){
if (versionState.equals(DatasetVersion.VersionState.DEACCESSIONED) && deaccessionNote.length() > DatasetVersion.VERSION_NOTE_MAX_LENGTH){
if (context != null) {
context.buildConstraintViolationWithTemplate(value + " " + BundleUtil.getStringFromBundle("file.deaccessionDialog.dialog.limitChar.error")).addConstraintViolation();
}
Expand Down
45 changes: 32 additions & 13 deletions src/main/java/edu/harvard/iq/dataverse/DatasetPage.java
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ public class DatasetPage implements java.io.Serializable {

public enum EditMode {

CREATE, INFO, FILE, METADATA, LICENSE
CREATE, INFO, FILE, METADATA, LICENSE, VERSIONNOTE
};

public enum DisplayMode {
Expand Down Expand Up @@ -2118,6 +2118,7 @@ private String init(boolean initFull) {
if (workingVersion.isDraft() && canUpdateDataset()) {
readOnly = false;
}
publishDialogVersionNote = workingVersion.getVersionNote();
// This will default to all the files in the version, if the search term
// parameter hasn't been specified yet:
fileMetadatasSearch = selectFileMetadatasForDisplay();
Expand Down Expand Up @@ -2774,6 +2775,7 @@ public String releaseDataset() {
if(!dataset.getOwner().isReleased()){
releaseParentDV();
}
workingVersion.setVersionNote(publishDialogVersionNote);
if(publishDatasetPopup()|| publishBothPopup() || !dataset.getLatestVersion().isMinorUpdate()){
return releaseDataset(false);
}
Expand Down Expand Up @@ -2840,35 +2842,35 @@ private DatasetVersion setDatasetVersionDeaccessionReasonAndURL(DatasetVersion d
String deacessionReasonDetail = getDeaccessionReasonText() != null ? ( getDeaccessionReasonText()).trim() : "";
switch (deaccessionReasonCode) {
case 1:
dvIn.setVersionNote(BundleUtil.getStringFromBundle("file.deaccessionDialog.reason.selectItem.identifiable") );
dvIn.setDeaccessionNote(BundleUtil.getStringFromBundle("file.deaccessionDialog.reason.selectItem.identifiable") );
break;
case 2:
dvIn.setVersionNote(BundleUtil.getStringFromBundle("file.deaccessionDialog.reason.selectItem.beRetracted") );
dvIn.setDeaccessionNote(BundleUtil.getStringFromBundle("file.deaccessionDialog.reason.selectItem.beRetracted") );
break;
case 3:
dvIn.setVersionNote(BundleUtil.getStringFromBundle("file.deaccessionDialog.reason.selectItem.beTransferred") );
dvIn.setDeaccessionNote(BundleUtil.getStringFromBundle("file.deaccessionDialog.reason.selectItem.beTransferred") );
break;
case 4:
dvIn.setVersionNote(BundleUtil.getStringFromBundle("file.deaccessionDialog.reason.selectItem.IRB"));
dvIn.setDeaccessionNote(BundleUtil.getStringFromBundle("file.deaccessionDialog.reason.selectItem.IRB"));
break;
case 5:
dvIn.setVersionNote(BundleUtil.getStringFromBundle("file.deaccessionDialog.reason.selectItem.legalIssue"));
dvIn.setDeaccessionNote(BundleUtil.getStringFromBundle("file.deaccessionDialog.reason.selectItem.legalIssue"));
break;
case 6:
dvIn.setVersionNote(BundleUtil.getStringFromBundle("file.deaccessionDialog.reason.selectItem.notValid"));
dvIn.setDeaccessionNote(BundleUtil.getStringFromBundle("file.deaccessionDialog.reason.selectItem.notValid"));
break;
case 7:
break;
}
if (!deacessionReasonDetail.isEmpty()){
if (!StringUtil.isEmpty(dvIn.getVersionNote())){
dvIn.setVersionNote(dvIn.getVersionNote() + " " + deacessionReasonDetail);
if (!StringUtil.isEmpty(dvIn.getDeaccessionNote())){
dvIn.setDeaccessionNote(dvIn.getDeaccessionNote() + " " + deacessionReasonDetail);
} else {
dvIn.setVersionNote(deacessionReasonDetail);
dvIn.setDeaccessionNote(deacessionReasonDetail);
}
}

dvIn.setArchiveNote(getDeaccessionForwardURLFor());
dvIn.setDeaccessionLink(getDeaccessionForwardURLFor());
return dvIn;
}

Expand Down Expand Up @@ -3934,7 +3936,7 @@ public void validateForwardURL(FacesContext context, UIComponent toValidate, Obj
return;
}

if (value.toString().length() <= DatasetVersion.ARCHIVE_NOTE_MAX_LENGTH) {
if (value.toString().length() <= DatasetVersion.DEACCESSION_NOTE_MAX_LENGTH) {
((UIInput) toValidate).setValid(true);
} else {
((UIInput) toValidate).setValid(false);
Expand Down Expand Up @@ -4105,8 +4107,9 @@ public String save() {
}
if (editMode.equals(EditMode.FILE)) {
JsfHelper.addSuccessMessage(BundleUtil.getStringFromBundle("dataset.message.filesSuccess"));
} if (editMode.equals(EditMode.VERSIONNOTE)) {
JsfHelper.addSuccessMessage(BundleUtil.getStringFromBundle("dataset.message.versionNoteSuccess"));
}

} else {
// must have been a bulk file update or delete:
if (bulkFileDeleteInProgress) {
Expand Down Expand Up @@ -6763,5 +6766,21 @@ public String getSignpostingLinkHeader() {
public boolean isDOI() {
return AbstractDOIProvider.DOI_PROTOCOL.equals(dataset.getGlobalId().getProtocol());
}

public void saveVersionNote() {
this.editMode=EditMode.VERSIONNOTE;
publishDialogVersionNote = workingVersion.getVersionNote();
save();
}
String publishDialogVersionNote = null;

// Make separate property for versionNote - can't have two p:dialogs changing the same property
public String getPublishDialogVersionNote() {
return publishDialogVersionNote;
}

public void setPublishDialogVersionNote(String note) {
publishDialogVersionNote =note;
}

}
Loading
Loading