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

Make it possible for users to view their data on Panorama Public #387

Merged
merged 7 commits into from
Jan 21, 2024
Merged
Show file tree
Hide file tree
Changes from 6 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
Expand Up @@ -178,6 +178,7 @@
import org.labkey.panoramapublic.query.ExperimentAnnotationsManager;
import org.labkey.panoramapublic.query.JournalManager;
import org.labkey.panoramapublic.query.ModificationInfoManager;
import org.labkey.panoramapublic.query.MyDataTableInfo;
import org.labkey.panoramapublic.query.PxXmlManager;
import org.labkey.panoramapublic.query.SpecLibInfoManager;
import org.labkey.panoramapublic.query.SubmissionManager;
Expand Down Expand Up @@ -9183,6 +9184,68 @@ public ModelAndView getView(Object o, BindException errors)
}
}

@RequiresPermission(ReadPermission.class)
@RequiresLogin
public class MyDataViewAction extends SimpleViewAction<MyDataForm>
{
@Override
public void addNavTrail(NavTree root)
{
root.addChild("My Panorama Public Data");
}

@Override
public ModelAndView getView(MyDataForm form, BindException errors) throws Exception
{
if (form.getUserId() == null)
{
errors.addError(new LabKeyError("Did not find a user id in the request"));
return new SimpleErrorView(errors);
}
User user = UserManager.getUser(form.getUserId());
if (user == null)
{
errors.addError(new LabKeyError("Could not find a user for id: " + form.getUserId()));
}
else if (!user.equals(getUser()))
{
errors.addError(new LabKeyError("User did not match. You cannot view datasets for other users"));
}
if (errors.hasErrors())
{
return new SimpleErrorView(errors);
}

QuerySettings settings = new QuerySettings(getViewContext(), MyDataTableInfo.NAME, MyDataTableInfo.NAME);
settings.setContainerFilterName(ContainerFilter.Type.CurrentAndSubfolders.name());
QueryView view = new QueryView(new PanoramaPublicSchema(getUser(), getContainer()), settings, errors);
view.setTitle("Panorama Public Experiments");
view.setShowRecordSelectors(false);
view.setShowExportButtons(false);
view.setShowDetailsColumn(false);
view.setShowDeleteButton(false);
view.setShowUpdateColumn(false);
view.setShowInsertNewButton(false);
view.disableContainerFilterSelection();
return view;
}
}

public static class MyDataForm
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need this form at all? It seems like we only support viewing data for the current user.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

No, we don't need a userId since we are only displaying the data for the currently logged in user! I removed the form.

{
private Integer _userId;

public Integer getUserId()
{
return _userId;
}

public void setUserId(Integer userId)
{
_userId = userId;
}
}

// ------------------------------------------------------------------------
// BEGIN Assign PanoramaPublicSubmitterRole to data submitters and lab heads
// ------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
import org.labkey.panoramapublic.query.DataValidationTableInfo;
import org.labkey.panoramapublic.query.ExperimentAnnotationsTableInfo;
import org.labkey.panoramapublic.query.JournalExperimentTableInfo;
import org.labkey.panoramapublic.query.MyDataTableInfo;
import org.labkey.panoramapublic.query.PanoramaPublicTable;
import org.labkey.panoramapublic.query.SubmissionTableInfo;
import org.labkey.panoramapublic.query.modification.ExperimentIsotopeModInfoTableInfo;
Expand Down Expand Up @@ -129,6 +130,10 @@ public TableInfo createTable(String name, ContainerFilter cf)
{
return new ExperimentAnnotationsTableInfo(this, cf);
}
if (MyDataTableInfo.NAME.equalsIgnoreCase(name))
{
return new MyDataTableInfo(this, cf, getUser());
}
if (TABLE_JOURNAL_EXPERIMENT.equalsIgnoreCase(name))
{
return new JournalExperimentTableInfo(this, cf);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
import org.labkey.api.security.roles.ProjectAdminRole;
import org.labkey.api.security.roles.Role;
import org.labkey.api.security.roles.RoleManager;
import org.labkey.api.settings.AppProps;
import org.labkey.api.util.DOM;
import org.labkey.api.util.HtmlString;
import org.labkey.api.util.PageFlowUtil;
Expand All @@ -65,8 +66,10 @@
import org.labkey.panoramapublic.PanoramaPublicController;
import org.labkey.panoramapublic.PanoramaPublicManager;
import org.labkey.panoramapublic.PanoramaPublicSchema;
import org.labkey.panoramapublic.model.CatalogEntry;
import org.labkey.panoramapublic.model.DataLicense;
import org.labkey.panoramapublic.model.ExperimentAnnotations;
import org.labkey.panoramapublic.view.publish.CatalogEntryWebPart;
import org.labkey.panoramapublic.view.publish.ShortUrlDisplayColumnFactory;

import java.io.IOException;
Expand All @@ -75,8 +78,12 @@
import java.util.List;
import java.util.Set;

import static org.labkey.api.util.DOM.Attribute.height;
import static org.labkey.api.util.DOM.Attribute.href;
import static org.labkey.api.util.DOM.Attribute.onclick;
import static org.labkey.api.util.DOM.Attribute.src;
import static org.labkey.api.util.DOM.Attribute.title;
import static org.labkey.api.util.DOM.Attribute.width;
import static org.labkey.api.util.DOM.IMG;
import static org.labkey.api.util.DOM.at;

Expand Down Expand Up @@ -337,6 +344,10 @@ public Class getDisplayValueClass()
getMutableColumn("CreatedBy").setFk(new UserIdQueryForeignKey(schema));
getMutableColumn("ModifiedBy").setFk(new UserIdQueryForeignKey(schema));

ExprColumn catalogEntryCol = getCatalogEntryCol();
catalogEntryCol.setDisplayColumnFactory(colInfo -> new CatalogEntryIconColumn(colInfo));
addColumn(catalogEntryCol);

List<FieldKey> visibleColumns = new ArrayList<>();
visibleColumns.add(FieldKey.fromParts("Share"));
visibleColumns.add(FieldKey.fromParts("Title"));
Expand Down Expand Up @@ -407,6 +418,18 @@ private ExprColumn getVersionCountCol()
return versionCountCol;
}

private ExprColumn getCatalogEntryCol()
{
SQLFragment catalogEntrySql = new SQLFragment(" (SELECT entry.id AS CatalogEntry ")
.append(" FROM ").append(PanoramaPublicManager.getTableInfoCatalogEntry(), "entry")
.append(" WHERE ")
.append(" entry.shortUrl = ").append(ExprColumn.STR_TABLE_ALIAS).append(".shortUrl")
.append(") ");
ExprColumn col = new ExprColumn(this, "CatalogEntry", catalogEntrySql, JdbcType.INTEGER);
col.setDescription("Add or view the catalog entry for the experiment");
return col;
}

@Override
public String getName()
{
Expand Down Expand Up @@ -724,4 +747,47 @@ String getRenderId()
return "input-picker-div-instrument";
}
}

public static class CatalogEntryIconColumn extends DataColumn
{
public CatalogEntryIconColumn(ColumnInfo col)
{
super(col);
super.setCaption("Catalog Entry");
}

@Override
public void renderGridCellContents(RenderContext ctx, Writer out) throws IOException
{
User user = ctx.getViewContext().getUser();
if (user == null || user.isGuest())
{
HtmlString.NBSP.appendTo(out);
return;
}
Integer catalogEntryId = ctx.get(getColumnInfo().getFieldKey(), Integer.class);

// Get the experiment connected with this catalog entry.
Integer experimentId = ctx.get(FieldKey.fromParts("id"), Integer.class);
if (experimentId != null)
{
ExperimentAnnotations expAnnot = ExperimentAnnotationsManager.get(experimentId);
// Display the catalog entry link only if the user has the required permissions (Admin or PanoramaPublicSubmitter) in the the experiment folder.
if (expAnnot != null && CatalogEntryWebPart.canBeDisplayed(expAnnot, user))
{
CatalogEntry entry = catalogEntryId == null ? null : CatalogEntryManager.get(catalogEntryId);
String imageUrl = entry != null ? AppProps.getInstance().getContextPath() + "/PanoramaPublic/images/slideshow-icon-green.png"
: AppProps.getInstance().getContextPath() + "/PanoramaPublic/images/slideshow-icon.png";
String imageTitle = entry != null ? "View catalog entry" : "Add catalog entry";
ActionURL catalogEntryLink = entry != null ? PanoramaPublicController.getViewCatalogEntryUrl(expAnnot, entry)
: PanoramaPublicController.getAddCatalogEntryUrl(expAnnot).addReturnURL(ctx.getViewContext().getActionURL().clone());
DOM.A(at(href, catalogEntryLink.getLocalURIString(), title, PageFlowUtil.filter(imageTitle)),
DOM.IMG(at(src, imageUrl, height, 22, width, 22)))
.appendTo(out);
return;
}
}
HtmlString.EMPTY_STRING.appendTo(out);
Copy link
Contributor

Choose a reason for hiding this comment

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

This codepath uses EMPTY_STRING and the one above uses NBSP. I imagine they should probably use the same placeholder, though maybe it doesn't make a difference.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done.

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package org.labkey.panoramapublic.query;

import org.labkey.api.data.CompareType;
import org.labkey.api.data.ContainerFilter;
import org.labkey.api.data.SimpleFilter;
import org.labkey.api.query.FieldKey;
import org.labkey.api.security.User;
import org.labkey.panoramapublic.PanoramaPublicSchema;

import java.util.ArrayList;
import java.util.List;

public class MyDataTableInfo extends ExperimentAnnotationsTableInfo
{
public static final String NAME = "MyPanoramaPublicData";

public MyDataTableInfo(PanoramaPublicSchema schema, ContainerFilter cf, User user)
{
super(schema, cf);

if (user != null)
{
// Filter to rows where the given user is either the submitter or the lab head.
SimpleFilter.OrClause or = new SimpleFilter.OrClause();
or.addClause(new CompareType.EqualsCompareClause(FieldKey.fromParts("submitter"), CompareType.EQUAL, user.getUserId()));
or.addClause(new CompareType.EqualsCompareClause(FieldKey.fromParts("labhead"), CompareType.EQUAL, user.getUserId()));
SimpleFilter filter = new SimpleFilter();
filter.addClause(or);
addCondition(filter);
}

List<FieldKey> visibleColumns = new ArrayList<>();
visibleColumns.add(FieldKey.fromParts("Share"));
visibleColumns.add(FieldKey.fromParts("Title"));
visibleColumns.add(FieldKey.fromParts("Organism"));
visibleColumns.add(FieldKey.fromParts("Instrument"));
visibleColumns.add(FieldKey.fromParts("Runs"));
visibleColumns.add(FieldKey.fromParts("Keywords"));
visibleColumns.add(FieldKey.fromParts("Citation"));
visibleColumns.add(FieldKey.fromParts("pxid"));
visibleColumns.add(FieldKey.fromParts("Public"));
visibleColumns.add(FieldKey.fromParts("CatalogEntry"));
setDefaultVisibleColumns(visibleColumns);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,5 +77,13 @@ protected void populateButtonBar(DataView view, ButtonBar bb)
deleteExperimentAnnotation.setDisplayPermission(DeletePermission.class);
deleteExperimentAnnotation.setRequiresSelection(true);
bb.add(deleteExperimentAnnotation);

if (!view.getViewContext().getUser().isGuest())
{
ActionURL viewMyDataUrl = new ActionURL(PanoramaPublicController.MyDataViewAction.class, getContainer());
viewMyDataUrl.addParameter("userId", view.getViewContext().getUser().getUserId());
ActionButton viewMyDataButton = new ActionButton(viewMyDataUrl, "My Data");
bb.add(viewMyDataButton);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
int imgWidth = settings.getImgWidth();
int imgHeight = settings.getImgHeight();

ActionURL cancelUrl = PanoramaPublicController.getViewExperimentDetailsURL(form.getId(), form.getContainer());
ActionURL cancelUrl = bean.getForm().getReturnActionURL(PanoramaPublicController.getViewExperimentDetailsURL(form.getId(), form.getContainer()));

%>
<labkey:errors/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,16 @@
success: function (wp) {
let expWebpart = wp.body.filter(webpart => webpart.name === "Targeted MS Experiment List");
if (expWebpart.length === 1) {

let buttonBarItems = [];
if (!LABKEY.user.isGuest)
{
buttonBarItems = [
{text: 'My Data', url: LABKEY.ActionURL.buildURL('panoramapublic', 'myDataView', null, {userId: LABKEY.user.id})},
LABKEY.QueryWebPart.standardButtons.views
];
}

let wp = new LABKEY.QueryWebPart({
renderTo: 'webpart_'+ expWebpart[0].webPartId,
title: 'Panorama Public Experiments',
Expand All @@ -491,6 +501,10 @@
showExportButtons: false,//this needs to be set to false otherwise setting selectRecordSelector to false still shows the checkbox column
showDetailsColumn: false,
dataRegionName: "Targeted MS Experiment List",
buttonBar: {
includeStandardButtons: true,
items: buttonBarItems,
},
success: function () {
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public TargetedMsExperimentInsertPage startInsert()

public void clickSubmit()
{
getWrapper().clickAndWait(Locator.linkContainingText("Submit"));
getWrapper().clickAndWait(Locator.linkWithText("Submit"));
}

public void clickResubmit()
Expand Down
Loading