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

adding unlink to ui and matching link permissions #10689

Merged
Merged
Show file tree
Hide file tree
Changes from 11 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
New "Unlink Dataset" button has been added to the Dataset Page to allow a user to unlink a dataset from a Dataverse that was previously linked with the "Link Dataset" button. The user must possess the same permissions needed to unlink the Dataset as they would to link the Dataset.
The unlink can still be accomplished by a superuser/Admin or a User with Publish Dataset permissions using the [pre-existing API](https://guides.dataverse.org/en/6.3/admin/dataverses-datasets.html#unlink-a-dataset).
2 changes: 1 addition & 1 deletion doc/sphinx-guides/source/admin/dataverses-datasets.rst
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ It returns a list in the following format:
Unlink a Dataset
^^^^^^^^^^^^^^^^

Removes a link between a dataset and a Dataverse collection. Only accessible to superusers. ::
Removes a link between a dataset and a Dataverse collection. Accessible to superusers or Users with Publish Dataset permissions (as of Dataverse 6.4). ::

curl -H "X-Dataverse-key: $API_TOKEN" -X DELETE http://$SERVER/api/datasets/$linked-dataset-id/deleteLink/$linking-dataverse-alias

Expand Down
45 changes: 45 additions & 0 deletions src/main/java/edu/harvard/iq/dataverse/DatasetPage.java
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@
import edu.harvard.iq.dataverse.engine.command.exception.IllegalCommandException;
import edu.harvard.iq.dataverse.engine.command.impl.AbstractSubmitToArchiveCommand;
import edu.harvard.iq.dataverse.engine.command.impl.CreateNewDatasetCommand;
import edu.harvard.iq.dataverse.engine.command.impl.DeleteDatasetLinkingDataverseCommand;
import edu.harvard.iq.dataverse.engine.command.impl.GetLatestPublishedDatasetVersionCommand;
import edu.harvard.iq.dataverse.engine.command.impl.RequestRsyncScriptCommand;
import edu.harvard.iq.dataverse.engine.command.impl.PublishDatasetResult;
Expand Down Expand Up @@ -3562,6 +3563,16 @@ public void saveLinkingDataverses(ActionEvent evt) {
}
alreadyLinkedDataverses = null; //force update to list of linked dataverses
}
public void deleteLinkingDataverses(ActionEvent evt) {

if (deleteLink(selectedDataverseForLinking)) {
JsfHelper.addSuccessMessage(BundleUtil.getStringFromBundle("dataset.message.unlinkSuccess", getSuccessMessageArguments()));
} else {
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, BundleUtil.getStringFromBundle("dataset.notlinked"), linkingDataverseErrorMessage);
FacesContext.getCurrentInstance().addMessage(null, message);
}
alreadyLinkedDataverses = null; //force update to list of linked dataverses
}

private String linkingDataverseErrorMessage = "";

Expand Down Expand Up @@ -3596,6 +3607,25 @@ private Boolean saveLink(Dataverse dataverse){
}
return retVal;
}
private Boolean deleteLink(Dataverse dataverse){
boolean retVal = true;
linkingDataverse = dataverse;
try {
DatasetLinkingDataverse dsld = dsLinkingService.findDatasetLinkingDataverse(dataset.getId(), linkingDataverse.getId());
DeleteDatasetLinkingDataverseCommand cmd = new DeleteDatasetLinkingDataverseCommand(dvRequestService.getDataverseRequest(), dataset, dsld, true);
commandEngine.submit(cmd);
} catch (CommandException ex) {
String msg = "There was a problem removing the link between this dataset to yours: " + ex;
logger.severe(msg);
msg = BundleUtil.getStringFromBundle("dataset.notlinked.msg") + ex;
/**
* @todo how do we get this message to show up in the GUI?
Copy link
Member

Choose a reason for hiding this comment

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

If we weren't moving to the SPA, I'd ask for any thoughts on this todo. 😄

*/
linkingDataverseErrorMessage = msg;
retVal = false;
}
return retVal;
}

private String alreadyLinkedDataverses = null;

Expand All @@ -3622,6 +3652,14 @@ public List<Dataverse> completeLinkingDataverse(String query) {
return null;
}
}
public List<Dataverse> completeUnLinkingDataverse(String query) {
dataset = datasetService.find(dataset.getId());
if (session.getUser().isAuthenticated()) {
return dataverseService.filterDataversesForUnLinking(query, dvRequestService.getDataverseRequest(), dataset);
} else {
return null;
}
}

public List<Dataverse> completeHostDataverseMenuList(String query) {
if (session.getUser().isAuthenticated()) {
Expand Down Expand Up @@ -5580,12 +5618,19 @@ public void setPrivateUrlJustCreatedToFalse() {
public boolean isShowLinkingPopup() {
return showLinkingPopup;
}
public boolean isShowUnLinkingPopup() {
return showUnLinkingPopup;
}

public void setShowLinkingPopup(boolean showLinkingPopup) {
this.showLinkingPopup = showLinkingPopup;
}
public void setShowUnLinkingPopup(boolean showUnLinkingPopup) {
this.showUnLinkingPopup = showUnLinkingPopup;
}

private boolean showLinkingPopup = false;
private boolean showUnLinkingPopup = false;
private Boolean anonymizedAccess = null;

//
Expand Down
14 changes: 13 additions & 1 deletion src/main/java/edu/harvard/iq/dataverse/DataverseServiceBean.java
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,19 @@ public List<Dataverse> filterDataversesForLinking(String query, DataverseRequest

return dataverseList;
}

public List<Dataverse> filterDataversesForUnLinking(String query, DataverseRequest req, Dataset dataset) {
List<Object> alreadyLinkeddv_ids = em.createNativeQuery("SELECT linkingdataverse_id FROM datasetlinkingdataverse WHERE dataset_id = " + dataset.getId()).getResultList();
List<Dataverse> dataverseList = new ArrayList<>();
if (alreadyLinkeddv_ids != null && !alreadyLinkeddv_ids.isEmpty()) {
alreadyLinkeddv_ids.stream().map((testDVId) -> this.find(testDVId)).forEachOrdered((dataverse) -> {
if (this.permissionService.requestOn(req, dataverse).has(Permission.PublishDataset)) {
dataverseList.add(dataverse);
}
});
}
return dataverseList;
}

public List<Dataverse> filterDataversesForHosting(String pattern, DataverseRequest req) {

// Find the dataverses matching the search parameters:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,22 @@
import edu.harvard.iq.dataverse.Dataset;
import edu.harvard.iq.dataverse.DatasetLinkingDataverse;
import edu.harvard.iq.dataverse.authorization.Permission;
import edu.harvard.iq.dataverse.authorization.users.AuthenticatedUser;
import edu.harvard.iq.dataverse.batch.util.LoggingUtil;
import edu.harvard.iq.dataverse.engine.command.AbstractCommand;
import edu.harvard.iq.dataverse.engine.command.CommandContext;
import edu.harvard.iq.dataverse.engine.command.DataverseRequest;
import edu.harvard.iq.dataverse.engine.command.RequiredPermissions;
import edu.harvard.iq.dataverse.engine.command.exception.CommandException;
import edu.harvard.iq.dataverse.engine.command.exception.PermissionException;
import java.io.IOException;
import java.util.Collections;
import java.util.concurrent.Future;

import org.apache.solr.client.solrj.SolrServerException;

/**
*
* @author sarahferry
*/

@RequiredPermissions( Permission.EditDataset )
@RequiredPermissions( Permission.PublishDataset )
public class DeleteDatasetLinkingDataverseCommand extends AbstractCommand<Dataset>{
private final DatasetLinkingDataverse doomed;
private final Dataset editedDs;
Expand All @@ -41,10 +38,6 @@ public DeleteDatasetLinkingDataverseCommand(DataverseRequest aRequest, Dataset e

@Override
public Dataset execute(CommandContext ctxt) throws CommandException {
if ((!(getUser() instanceof AuthenticatedUser) || !getUser().isSuperuser())) {
throw new PermissionException("Delete dataset linking dataverse can only be called by superusers.",
this, Collections.singleton(Permission.EditDataset), editedDs);
}
Dataset merged = ctxt.em().merge(editedDs);
DatasetLinkingDataverse doomedAndMerged = ctxt.em().merge(doomed);
ctxt.em().remove(doomedAndMerged);
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/propertyFiles/Bundle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -899,6 +899,8 @@ dataverse.link.dataset.none=No linkable dataverses available.
dataverse.link.no.choice=You have one dataverse you can add linked dataverses and datasets in.
dataverse.link.no.linkable=To be able to link a dataverse or dataset, you need to have your own dataverse. Create a dataverse to get started.
dataverse.link.no.linkable.remaining=You have already linked all of your eligible dataverses.
dataverse.unlink.dataset.choose=Enter the name of the dataverse you would like to unlink this dataset from.
dataverse.unlink.dataset.none=No linked dataverses available.
dataverse.savedsearch.link=Link Search
dataverse.savedsearch.searchquery=Search
dataverse.savedsearch.filterQueries=Facets
Expand All @@ -912,6 +914,7 @@ dataverse.linked.success= {0} has been successfully linked to {1}.
dataverse.linked.success.wait= {0} has been successfully linked to {1}. Please wait for its contents to appear.
dataverse.linked.internalerror={0} has been successfully linked to {1} but contents will not appear until an internal error has been fixed.
dataverse.linked.error.alreadyLinked={0} has already been linked to {1}.
dataverse.unlinked.success= {0} has been successfully unlinked from {1}.
dataverse.page.pre=Previous
dataverse.page.next=Next
dataverse.byCategory=Dataverses by Category
Expand Down Expand Up @@ -1423,6 +1426,7 @@ dataset.accessBtn.too.big=The dataset is too large to download. Please select th
dataset.accessBtn.original.too.big=The dataset is too large to download in the original format. Please select the files you need from the files table.
dataset.accessBtn.archival.too.big=The dataset is too large to download in the archival format. Please select the files you need from the files table.
dataset.linkBtn=Link Dataset
dataset.unlinkBtn=Unlink Dataset
dataset.contactBtn=Contact Owner
dataset.shareBtn=Share

Expand Down Expand Up @@ -1530,6 +1534,8 @@ dataset.link.not.to.parent.dataverse=Can't link a dataset to its parent datavers
dataset.link.not.published=Can't link a dataset that has not been published
dataset.link.not.available=Can't link a dataset that has not been published or is not harvested
dataset.link.not.already.linked=Can't link a dataset that has already been linked to this dataverse
dataset.unlink.title=Unlink Dataset
dataset.unlink.delete=Remove Linked Dataset
dataset.email.datasetContactTitle=Contact Dataset Owner
dataset.email.hiddenMessage=
dataset.email.messageSubject=Test Message Subject
Expand Down Expand Up @@ -1611,6 +1617,7 @@ dataset.message.createSuccess=This dataset has been created.
dataset.message.createSuccess.failedToSaveFiles=Partial Success: The dataset has been created. But the file(s) could not be saved. Please try uploading the file(s) again.
dataset.message.createSuccess.partialSuccessSavingFiles=Partial Success: The dataset has been created. But only {0} out of {1} files have been saved. Please try uploading the missing file(s) again.
dataset.message.linkSuccess= {0} has been successfully linked to {1}.
dataset.message.unlinkSuccess= {0} has been successfully unlinked from {1}.
dataset.message.metadataSuccess=The metadata for this dataset have been updated.
dataset.message.termsSuccess=The terms for this dataset have been updated.
dataset.message.filesSuccess=One or more files have been updated.
Expand Down Expand Up @@ -2546,6 +2553,7 @@ dataset.registered.msg=Your dataset is now registered.
dataset.notlinked=DatasetNotLinked
dataset.notlinked.msg=There was a problem linking this dataset to yours:
dataset.linking.popop.already.linked.note=Note: This dataset is already linked to the following dataverse(s):
dataset.linking.popup.not.linked.note=Note: This dataset is not linked to any of your accessible dataverses
datasetversion.archive.success=Archival copy of Version successfully submitted
datasetversion.archive.failure=Error in submitting an archival copy
datasetversion.update.failure=Dataset Version Update failed. Changes are still in the DRAFT version.
Expand Down
76 changes: 76 additions & 0 deletions src/main/webapp/dataset.xhtml
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,16 @@
</p:commandLink>
</div>
<!-- END: LINK -->
<!-- UNLINK -->
<div class="btn-group btn-group-justified" jsf:rendered="#{dataverseSession.user.authenticated and !DatasetPage.workingVersion.deaccessioned and DatasetPage.dataset.released}">
<p:commandLink styleClass="btn btn-default btn-access btn-xs btn-block btn-link-dataset"
action="#{DatasetPage.setShowUnLinkingPopup(true)}"
oncomplete="PF('unlinkDatasetForm').show();"
update="@form">
#{bundle['dataset.unlinkBtn']}
</p:commandLink>
</div>
<!-- END: UNLINK -->

<!-- Contact/Share Button Group -->
<div class="btn-group btn-group-justified">
Expand Down Expand Up @@ -1697,6 +1707,72 @@
</div>
</p:dialog>
<p:remoteCommand name="linkDatasetCommand" oncomplete="PF('linkDatasetForm').hide();" update=":messagePanel @([id$=Messages])" actionListener="#{DatasetPage.saveLinkingDataverses}"/>
<p:dialog id="unlinkDatasetForm" styleClass="largePopUp" header="#{bundle['dataset.unlink.title']}" widgetVar="unlinkDatasetForm" modal="true" rendered="#{DatasetPage.showUnLinkingPopup}">
<p:focus for="dataverseUnLinkName"/>
<div class="form-horizontal">
<p class="help-block">
<h:outputFormat value="#{bundle['dataverse.unlink.dataset.choose']}" escape="false">
<o:param>
<p:commandLink value="#{settingsWrapper.supportTeamName}" oncomplete="PF('unlinkDatasetForm').hide();PF('contactForm').show()" update=":contactDialog" actionListener="#{sendFeedbackDialog.initUserInput}">
<f:setPropertyActionListener target="#{sendFeedbackDialog.messageSubject}" value=""/>
<f:setPropertyActionListener target="#{sendFeedbackDialog.recipient}" value="#{null}"/>
<f:setPropertyActionListener target="#{sendFeedbackDialog.userMessage}" value=""/>
<f:setPropertyActionListener target="#{sendFeedbackDialog.userEmail}" value=""/>
</p:commandLink>
</o:param>
</h:outputFormat>
</p>
<div class="form-group">
<label class="col-xs-3 control-label">
<h:outputText value="#{bundle['dataverse.link.yourDataverses']}"/>
</label>
<div class="col-xs-8">
<p:fragment id="unlinkNameContent">
<p:autoComplete id="dataverseUnLinkName"
placeholder="#{bundle['dataverse.link.yourDataverses.inputPlaceholder']}"
emptyMessage="#{bundle['dataverse.unlink.dataset.none']}"
scrollHeight="180" forceSelection="true"
minQueryLength="1" queryDelay="1000"
value="#{DatasetPage.selectedDataverseForLinking}"
multiple="false"
completeMethod="#{DatasetPage.completeUnLinkingDataverse}"
required="#{param['DO_DS_LINK_VALIDATION']}" requiredMessage="#{bundle['dataverse.link.select']}"
styleClass="DropdownPopup" panelStyleClass="DropdownPopupPanel"
var="dataverseLk" itemLabel="#{dataverseLk.displayName}" itemValue="#{dataverseLk}" converter="dataverseConverter">
<p:column>
<h:outputText value="#{dataverseLk.displayName}"/>
</p:column>
<p:column>
<h:outputText value="#{dataverseLk.alias}"/>
</p:column>
<p:ajax process="@this" event="itemSelect" />
<p:ajax process="@this" event="itemUnselect" />
</p:autoComplete>
<p:message for="dataverseUnLinkName"/>
</p:fragment>
</div>
</div>
</div>
<div>
<p:fragment rendered="#{empty DatasetPage.alreadyLinkedDataverses}">
<h:outputLabel value="#{bundle['dataset.linking.popup.not.linked.note']}"/>&#160;
<h:outputText value=""/>
</p:fragment>
</div>
<div class="button-block">
<p:commandButton id="deleteLinkButton" styleClass="btn btn-default"
update="linkNameContent @([id$=Messages])"
oncomplete="if (args &amp;&amp; !args.validationFailed) unlinkDatasetCommand();"
value="#{bundle['dataset.unlink.delete']}">
<f:param name="DO_DS_LINK_VALIDATION" value="true"/>
</p:commandButton>
<button class="btn btn-link" onclick="PF('unlinkDatasetForm').hide();
PF('blockDatasetForm').hide();" type="button">
#{bundle.cancel}
</button>
</div>
</p:dialog>
<p:remoteCommand name="unlinkDatasetCommand" oncomplete="PF('unlinkDatasetForm').hide();" update=":messagePanel @([id$=Messages])" actionListener="#{DatasetPage.deleteLinkingDataverses}"/>
<p:dialog id="computeBatchListPopup" header="#{bundle['dataset.compute.computeBatchListHeader']}" widgetVar="computeBatchListPopup" modal="true">
<div class="text-right">
<!-- Clear link -->
Expand Down
Loading
Loading