Skip to content

Commit

Permalink
Merge pull request #5599 from Sage-Bionetworks/develop
Browse files Browse the repository at this point in the history
Merge develop into release 523 to patch staging (SRC 3.3.30)
  • Loading branch information
jay-hodgson authored Dec 4, 2024
2 parents 3a0e7f4 + 2f5eec9 commit 7b2415f
Show file tree
Hide file tree
Showing 598 changed files with 141,031 additions and 2,064 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"react-transition-group": "2.6.0",
"sass": "^1.63.6",
"spark-md5": "^3.0.2",
"synapse-react-client": "3.3.28",
"synapse-react-client": "3.3.30",
"universal-cookie": "^4.0.4",
"xss": "^1.0.15"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ public enum FeatureFlagKey {
// If enabled, uses the v2 uploader (react implementation) for file entity uploads.
UPLOADER_V2("UPLOADER_V2"),

// If enabled, uses the file browser react implementation
REACT_FILE_BROWSER("REACT_FILE_BROWSER"),

// Last flag is used only for tests
TEST_FLAG_ONLY("TEST_FLAG_ONLY");

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.sagebionetworks.web.client.jsinterop;

import jsinterop.annotations.JsFunction;
import jsinterop.annotations.JsOverlay;
import jsinterop.annotations.JsPackage;
import jsinterop.annotations.JsType;
import org.sagebionetworks.web.client.jsni.ReferenceJSNIObject;

@JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object")
public class EntityFileBrowserProps extends ReactComponentProps {

@FunctionalInterface
@JsFunction
public interface OnSelectCallback {
void run(ReferenceJSNIObject selected);
}

OnSelectCallback onSelect;
String parentContainerId;

@JsOverlay
public static EntityFileBrowserProps create(
String parentContainerId,
OnSelectCallback onSelect
) {
EntityFileBrowserProps props = new EntityFileBrowserProps();
props.parentContainerId = parentContainerId;
props.onSelect = onSelect;
return props;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public static class SynapseComponents {
public static ReactComponentType<EntityBadgeIconsProps> EntityBadgeIcons;
public static ReactComponentType<DatasetEditorProps> DatasetItemsEditor;
public static ReactComponentType<EntityFinderProps> EntityFinder;
public static ReactComponentType<EntityFileBrowserProps> EntityFileBrowser;
public static ReactComponentType<EvaluationCardProps> EvaluationCard;
public static ReactComponentType<
EvaluationEditorPageProps
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -352,10 +352,7 @@ public void onError(Throwable caught) {
headerWidget.configure();
if (caught instanceof NotFoundException) {
show404();
} else if (
caught instanceof ForbiddenException &&
authenticationController.isLoggedIn()
) {
} else if (caught instanceof ForbiddenException) {
show403();
} else {
view.clear();
Expand All @@ -364,35 +361,35 @@ public void onError(Throwable caught) {
}

public void show403() {
if (entityId != null) {
synAlert.show403(entityId, versionNumber);
}
synAlert.show403(entityId, versionNumber);
view.setLoadingVisible(false);
view.setEntityPageTopVisible(false);
// also add the open team invitations widget (accepting may gain access to this project)
openTeamInvitesWidget.configure(
new Callback() {
@Override
public void invoke() {
// when team is updated, refresh to see if we can now access
refresh();
}
},
new CallbackP<List<OpenUserInvitationBundle>>() {
@Override
public void invoke(List<OpenUserInvitationBundle> invites) {
// if there are any, then also add the title text to the panel
if (invites != null && invites.size() > 0) {
view.setAccessDependentMessageVisible(true);
if (authenticationController.isLoggedIn()) {
// also add the open team invitations widget (accepting may gain access to this project)
openTeamInvitesWidget.configure(
new Callback() {
@Override
public void invoke() {
// when team is updated, refresh to see if we can now access
refresh();
}
},
new CallbackP<List<OpenUserInvitationBundle>>() {
@Override
public void invoke(List<OpenUserInvitationBundle> invites) {
// if there are any, then also add the title text to the panel
if (invites != null && invites.size() > 0) {
view.setAccessDependentMessageVisible(true);
}
}
}
}
);
view.setOpenTeamInvitesVisible(true);
);
view.setOpenTeamInvitesVisible(true);
}
}

public void show404() {
synAlert.show404();
synAlert.show404(entityId, versionNumber);
view.setLoadingVisible(false);
view.setEntityPageTopVisible(false);
view.setOpenTeamInvitesVisible(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ public void loadMore() {
>() {
@Override
public void onSuccess(UserGroupHeaderResponsePage result) {
boolean hasNoResults = offset == 0 && result.getChildren().isEmpty();
view.setShowNoResults(hasNoResults);

for (UserGroupHeader header : result.getChildren()) {
if (header.getIsIndividual()) {
UserBadge badge = ginInjector.getUserBadgeWidget();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ private SearchQuery checkForJson(String queryString) {
String fixedQueryString = queryString;
// check for url encoded
if (queryString.startsWith("%7B")) {
fixedQueryString = URL.decode(queryString);
fixedQueryString = URL.decodePathSegment(queryString);
}
if (fixedQueryString.startsWith("{")) {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ public void loadMore() {
>() {
@Override
public void onSuccess(PaginatedResults<Team> result) {
boolean hasNoResults = offset == 0 && result.getResults().isEmpty();
view.setShowNoResults(hasNoResults);

for (Team team : result.getResults()) {
BigTeamBadge teamBadge = ginInjector.getBigTeamBadgeWidget();
teamBadge.configure(team, "");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,6 @@ public interface Presenter {
public void setSynAlertWidget(Widget asWidget);

public void setSynAlertWidgetVisible(boolean b);

public void setShowNoResults(boolean show);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.inject.Inject;
Expand Down Expand Up @@ -39,6 +40,9 @@ public interface PeopleSearchViewImplUiBinder
@UiField
TextBox searchField;

@UiField
HTMLPanel noSearchResultsContainer;

private Header headerWidget;
private Presenter presenter;

Expand Down Expand Up @@ -103,4 +107,9 @@ public void setSynAlertWidget(Widget synAlert) {
public void setSynAlertWidgetVisible(boolean isVisible) {
synAlertPanel.setVisible(isVisible);
}

@Override
public void setShowNoResults(boolean show) {
noSearchResultsContainer.setVisible(show);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@ public Widget getResults(
searchResultsPanel =
new HTMLPanel(
new SafeHtmlBuilder()
.appendHtmlConstant(
"<img src=\"https://s3.us-east-1.amazonaws.com/static.synapse.org/images/NoSearchResults.svg\" width=\"300px\" />"
)
.appendHtmlConstant(
"<h4>" + DisplayConstants.LABEL_NO_SEARCH_RESULTS_PART1
)
Expand All @@ -211,6 +214,7 @@ public Widget getResults(
)
.toSafeHtml()
);
searchResultsPanel.addStyleName("text-align-center");
facetPanel.clear();
} else {
searchResultsPanel = new SimplePanel();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,6 @@ public interface Presenter {
public void setSynAlertWidget(Widget asWidget);

void setLoadMoreContainer(Widget w);

public void setShowNoResults(boolean show);
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.inject.Inject;
Expand Down Expand Up @@ -39,6 +40,9 @@ public interface TeamSearchViewImplUiBinder
@UiField
SimplePanel synAlertPanel;

@UiField
HTMLPanel noSearchResultsContainer;

private Header headerWidget;
private Presenter presenter;
private SynapseJSNIUtils synapseJsniUtils;
Expand Down Expand Up @@ -105,4 +109,9 @@ public void onKeyDown(KeyDownEvent event) {
public void setSynAlertWidget(Widget synAlert) {
synAlertPanel.setWidget(synAlert);
}

@Override
public void setShowNoResults(boolean show) {
noSearchResultsContainer.setVisible(show);
}
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
package org.sagebionetworks.web.client.widget.entity.browse;

import com.google.gwt.core.client.GWT;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.Widget;
import com.google.inject.Inject;
import org.gwtbootstrap3.client.ui.AnchorListItem;
import org.gwtbootstrap3.client.ui.Button;
import org.gwtbootstrap3.client.ui.Heading;
import org.gwtbootstrap3.client.ui.Tooltip;
import org.gwtbootstrap3.client.ui.html.Div;
import org.gwtbootstrap3.client.ui.html.Span;
import org.sagebionetworks.web.client.DisplayUtils;
import org.sagebionetworks.web.client.security.AuthenticationController;
import org.sagebionetworks.web.client.FeatureFlagConfig;
import org.sagebionetworks.web.client.FeatureFlagKey;
import org.sagebionetworks.web.client.context.SynapseReactClientFullContextPropsProvider;
import org.sagebionetworks.web.client.jsinterop.EntityFileBrowserProps;
import org.sagebionetworks.web.client.jsinterop.React;
import org.sagebionetworks.web.client.jsinterop.ReactElement;
import org.sagebionetworks.web.client.jsinterop.SRC;
import org.sagebionetworks.web.client.utils.CallbackP;
import org.sagebionetworks.web.client.widget.HelpWidget;
import org.sagebionetworks.web.client.widget.ReactComponent;

public class FilesBrowserViewImpl implements FilesBrowserView {

Expand All @@ -23,6 +26,8 @@ public interface FilesBrowserViewImplUiBinder

private EntityTreeBrowser entityTreeBrowser;
private Widget widget;
SynapseReactClientFullContextPropsProvider propsProvider;
private FeatureFlagConfig featureFlagConfig;

@UiField
Div files;
Expand All @@ -39,12 +44,21 @@ public interface FilesBrowserViewImplUiBinder
@UiField
Heading title;

@UiField
Div reactFileBrowserContainer;

CallbackP<String> entityClickedCallback;

@Inject
public FilesBrowserViewImpl(
FilesBrowserViewImplUiBinder binder,
EntityTreeBrowser entityTreeBrowser
EntityTreeBrowser entityTreeBrowser,
SynapseReactClientFullContextPropsProvider propsProvider,
FeatureFlagConfig featureFlagConfig
) {
widget = binder.createAndBindUi(this);
this.featureFlagConfig = featureFlagConfig;
this.propsProvider = propsProvider;
this.entityTreeBrowser = entityTreeBrowser;
Widget etbW = entityTreeBrowser.asWidget();
etbW.addStyleName("margin-top-10");
Expand All @@ -53,15 +67,46 @@ public FilesBrowserViewImpl(

@Override
public void configure(String entityId) {
boolean isReactFileBrowser = featureFlagConfig.isFeatureEnabled(
FeatureFlagKey.REACT_FILE_BROWSER
);
title.setVisible(false);
entityTreeBrowser.configure(entityId);
reactFileBrowserContainer.setVisible(isReactFileBrowser);
files.setVisible(!isReactFileBrowser);
if (isReactFileBrowser) {
rerenderFileBrowser(entityId);
} else {
entityTreeBrowser.configure(entityId);
}
}

public void rerenderFileBrowser(String parentContainerId) {
// TODO: Should not need to remount, but currently the parentContainer is not shown if the existing react component is updated
// TODO: Bug: The tree is not always auto-expanding (to the path to the parent container Id)
reactFileBrowserContainer.clear();
ReactComponent componentContainer = new ReactComponent();
EntityFileBrowserProps props = EntityFileBrowserProps.create(
parentContainerId,
ref -> {
String entityId = ref.getTargetId();
entityClickedCallback.invoke(entityId);
}
);
ReactElement component = React.createElementWithSynapseContext(
SRC.SynapseComponents.EntityFileBrowser,
props,
propsProvider.getJsInteropContextProps()
);
reactFileBrowserContainer.add(componentContainer);
componentContainer.render(component);
}

@Override
public void setEntityClickedHandler(CallbackP<String> callback) {
this.entityClickedCallback = callback;
entityTreeBrowser.setEntityClickedHandler(entityId -> {
entityTreeBrowser.setLoadingVisible(true);
callback.invoke(entityId);
entityClickedCallback.invoke(entityId);
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,6 @@ public void clear() {
entityVersion = null;
}

public void show403() {
show403(null, null);
}

public void show403(String entityId, Long entityVersion) {
clear();
this.entityId = entityId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,17 @@
visible="false"
/>
</bh:Div>
<g:HTMLPanel
ui:field="noSearchResultsContainer"
visible="false"
addStyleNames="margin-top-40 text-align-center"
>
<img
src="https://s3.us-east-1.amazonaws.com/static.synapse.org/images/NoSearchResults.svg"
width="300px"
/>
<bh:Paragraph addStyleNames="margin-top-15" text="No people found." />
</g:HTMLPanel>
<bh:Div>
<g:SimplePanel
ui:field="peopleListPanel"
Expand Down
Loading

0 comments on commit 7b2415f

Please sign in to comment.