diff --git a/src/main/java/org/sagebionetworks/web/client/jsinterop/ErrorPageProps.java b/src/main/java/org/sagebionetworks/web/client/jsinterop/ErrorPageProps.java index 1e419aa2c1..2550633e56 100644 --- a/src/main/java/org/sagebionetworks/web/client/jsinterop/ErrorPageProps.java +++ b/src/main/java/org/sagebionetworks/web/client/jsinterop/ErrorPageProps.java @@ -1,5 +1,6 @@ package org.sagebionetworks.web.client.jsinterop; +import jsinterop.annotations.JsFunction; import jsinterop.annotations.JsOverlay; import jsinterop.annotations.JsPackage; import jsinterop.annotations.JsType; @@ -7,20 +8,33 @@ @JsType(isNative = true, namespace = JsPackage.GLOBAL, name = "Object") public class ErrorPageProps extends ReactComponentProps { - String image; - String title; + String type; String message; + String entityId; + Double entityVersionNumber; + + @JsFunction + public interface Callback { + void run(String targetHref); + } + + public Callback gotoPlace; @JsOverlay public static ErrorPageProps create( - String image, - String title, - String message + String type, + String message, + String entityId, + Long entityVersion, + Callback gotoPlace ) { ErrorPageProps props = new ErrorPageProps(); - props.image = image; - props.title = title; + props.type = type; props.message = message; + props.entityId = entityId; + props.entityVersionNumber = + entityVersion != null ? entityVersion.doubleValue() : null; + props.gotoPlace = gotoPlace; return props; } } diff --git a/src/main/java/org/sagebionetworks/web/client/presenter/EntityPresenter.java b/src/main/java/org/sagebionetworks/web/client/presenter/EntityPresenter.java index a1c0dc7505..6cdd65f7ba 100644 --- a/src/main/java/org/sagebionetworks/web/client/presenter/EntityPresenter.java +++ b/src/main/java/org/sagebionetworks/web/client/presenter/EntityPresenter.java @@ -365,7 +365,7 @@ public void onError(Throwable caught) { public void show403() { if (entityId != null) { - synAlert.show403(entityId); + synAlert.show403(entityId, versionNumber); } view.setLoadingVisible(false); view.setEntityPageTopVisible(false); diff --git a/src/main/java/org/sagebionetworks/web/client/view/DownViewImpl.java b/src/main/java/org/sagebionetworks/web/client/view/DownViewImpl.java index 470ac36566..b1e2f772c9 100644 --- a/src/main/java/org/sagebionetworks/web/client/view/DownViewImpl.java +++ b/src/main/java/org/sagebionetworks/web/client/view/DownViewImpl.java @@ -4,6 +4,8 @@ import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Widget; import com.google.inject.Inject; +import org.sagebionetworks.web.client.GlobalApplicationState; +import org.sagebionetworks.web.client.PlaceChanger; import org.sagebionetworks.web.client.context.SynapseReactClientFullContextPropsProvider; import org.sagebionetworks.web.client.jsinterop.ErrorPageProps; import org.sagebionetworks.web.client.jsinterop.React; @@ -25,20 +27,22 @@ public class DownViewImpl implements DownView { String message; public static enum ErrorPageType { - maintenance, - noAccess, - unavailable, + DOWN, + ACCESS_DENIED, + NOT_FOUND, } public interface Binder extends UiBinder {} + GlobalApplicationState globalAppState; Widget widget; @Inject public DownViewImpl( Binder uiBinder, Header headerWidget, - final SynapseReactClientFullContextPropsProvider propsProvider + final SynapseReactClientFullContextPropsProvider propsProvider, + GlobalApplicationState globalAppState ) { widget = uiBinder.createAndBindUi(this); this.headerWidget = headerWidget; @@ -49,6 +53,7 @@ public DownViewImpl( renderMaintenancePage(); } }); + this.globalAppState = globalAppState; } @Override @@ -77,9 +82,13 @@ public boolean isAttached() { public void renderMaintenancePage() { ErrorPageProps props = ErrorPageProps.create( - ErrorPageType.maintenance.name(), - SYNAPSE_DOWN_MAINTENANCE_TITLE, - message + ErrorPageType.DOWN.name(), + message, + null, //entity ID + null, //entity version + href -> { + globalAppState.handleRelativePathClick(href); + } ); ReactNode component = React.createElementWithSynapseContext( SRC.SynapseComponents.ErrorPage, diff --git a/src/main/java/org/sagebionetworks/web/client/widget/entity/controller/StuAlert.java b/src/main/java/org/sagebionetworks/web/client/widget/entity/controller/StuAlert.java index 1e4a8781c8..421e704ebf 100644 --- a/src/main/java/org/sagebionetworks/web/client/widget/entity/controller/StuAlert.java +++ b/src/main/java/org/sagebionetworks/web/client/widget/entity/controller/StuAlert.java @@ -11,6 +11,7 @@ public class StuAlert { StuAlertView view; String entityId; + Long entityVersion; SynapseAlert synAlert; GWTWrapper gwt; AuthenticationController authController; @@ -37,24 +38,29 @@ public void clear() { synAlert.clear(); view.clearState(); entityId = null; + entityVersion = null; } public void show403() { - clear(); - view.show403(); + show403(null, null); } - public void show403(String entityId) { - show403(); + public void show403(String entityId, Long entityVersion) { + clear(); this.entityId = entityId; - if (!authController.isLoggedIn()) { - synAlert.showLogin(); - } + this.entityVersion = entityVersion; + view.show403(entityId, entityVersion, authController.isLoggedIn()); } public void show404() { + show404(null, null); + } + + public void show404(String entityId, Long entityVersion) { clear(); - view.show404(); + this.entityId = entityId; + this.entityVersion = entityVersion; + view.show404(entityId, entityVersion, authController.isLoggedIn()); } public String getEntityId() { @@ -65,13 +71,9 @@ public void handleException(Throwable ex) { clear(); // if it's something that Stu recognizes, then he should handle it. if (ex instanceof ForbiddenException) { - if (!authController.isLoggedIn()) { - synAlert.showLogin(); - } else { - view.show403(); - } + view.show403(null, null, authController.isLoggedIn()); } else if (ex instanceof NotFoundException) { - view.show404(); + view.show404(null, null, authController.isLoggedIn()); } else { synAlert.handleException(ex); } diff --git a/src/main/java/org/sagebionetworks/web/client/widget/entity/controller/StuAlertView.java b/src/main/java/org/sagebionetworks/web/client/widget/entity/controller/StuAlertView.java index 4caab5d779..7c39cfdcd1 100644 --- a/src/main/java/org/sagebionetworks/web/client/widget/entity/controller/StuAlertView.java +++ b/src/main/java/org/sagebionetworks/web/client/widget/entity/controller/StuAlertView.java @@ -20,9 +20,9 @@ public interface StuAlertView extends IsWidget { */ void clearState(); - void show403(); + void show403(String entityId, Long entityVersion, boolean isLoggedIn); - void show404(); + void show404(String entityId, Long entityVersion, boolean isLoggedIn); void setSynAlert(Widget w); diff --git a/src/main/java/org/sagebionetworks/web/client/widget/entity/controller/StuAlertViewImpl.java b/src/main/java/org/sagebionetworks/web/client/widget/entity/controller/StuAlertViewImpl.java index d01007e5b3..f1b3284320 100644 --- a/src/main/java/org/sagebionetworks/web/client/widget/entity/controller/StuAlertViewImpl.java +++ b/src/main/java/org/sagebionetworks/web/client/widget/entity/controller/StuAlertViewImpl.java @@ -7,6 +7,7 @@ import com.google.inject.Inject; import org.gwtbootstrap3.client.ui.html.Div; import org.sagebionetworks.web.client.DisplayUtils; +import org.sagebionetworks.web.client.GlobalApplicationState; import org.sagebionetworks.web.client.context.SynapseReactClientFullContextPropsProvider; import org.sagebionetworks.web.client.jsinterop.ErrorPageProps; import org.sagebionetworks.web.client.jsinterop.React; @@ -31,12 +32,18 @@ public interface Binder extends UiBinder {} Widget synAlertWidget; Div container = new Div(); boolean is404, is403; + String entityId; + Long entityVersion; + boolean isLoggedIn; + GlobalApplicationState globalAppState; @Inject public StuAlertViewImpl( - SynapseReactClientFullContextPropsProvider propsProvider + SynapseReactClientFullContextPropsProvider propsProvider, + GlobalApplicationState globalAppState ) { this.propsProvider = propsProvider; + this.globalAppState = globalAppState; } @Override @@ -53,6 +60,8 @@ public Widget asWidget() { public void clearState() { container.setVisible(false); if (widget != null) { + entityId = null; + entityVersion = null; is404 = false; is403 = false; errorPageContainer.setVisible(false); @@ -73,12 +82,16 @@ private void lazyConstruct() { } } - private void renderErrorPage( - ErrorPageType type, - String title, - String message - ) { - ErrorPageProps props = ErrorPageProps.create(type.name(), title, message); + private void renderErrorPage(ErrorPageType type) { + ErrorPageProps props = ErrorPageProps.create( + type.name(), + null, //custom message + entityId, + entityVersion, + href -> { + globalAppState.handleRelativePathClick(href); + } + ); ReactNode component = React.createElementWithSynapseContext( SRC.SynapseComponents.ErrorPage, props, @@ -90,32 +103,30 @@ private void renderErrorPage( private void updateErrorPage() { if (is404) { - renderErrorPage( - ErrorPageType.unavailable, - "Sorry, this page isn’t available.", - "The link you followed may be broken, or the page may have been removed." - ); + renderErrorPage(ErrorPageType.NOT_FOUND); } if (is403) { - renderErrorPage( - ErrorPageType.noAccess, - "Sorry, no access to this page.", - "You are not authorized to access the page requested." - ); + renderErrorPage(ErrorPageType.ACCESS_DENIED); } } @Override - public void show403() { + public void show403(String entityId, Long entityVersion, boolean isLoggedIn) { is403 = true; + this.isLoggedIn = isLoggedIn; + this.entityId = entityId; + this.entityVersion = entityVersion; lazyConstruct(); container.setVisible(true); updateErrorPage(); } @Override - public void show404() { + public void show404(String entityId, Long entityVersion, boolean isLoggedIn) { is404 = true; + this.isLoggedIn = isLoggedIn; + this.entityId = entityId; + this.entityVersion = entityVersion; lazyConstruct(); container.setVisible(true); updateErrorPage(); diff --git a/src/main/resources/org/sagebionetworks/web/client/widget/entity/renderer/EntityListWidgetViewImpl.ui.xml b/src/main/resources/org/sagebionetworks/web/client/widget/entity/renderer/EntityListWidgetViewImpl.ui.xml index 5ae3b528b7..499e37bc8f 100644 --- a/src/main/resources/org/sagebionetworks/web/client/widget/entity/renderer/EntityListWidgetViewImpl.ui.xml +++ b/src/main/resources/org/sagebionetworks/web/client/widget/entity/renderer/EntityListWidgetViewImpl.ui.xml @@ -4,7 +4,6 @@ xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui" xmlns:b="urn:import:org.gwtbootstrap3.client.ui" - xmlns:a="urn:import:org.sagebionetworks.web.client.widget.entity.menu.v2" xmlns:bg="urn:import:org.gwtbootstrap3.client.ui.gwt" xmlns:bh="urn:import:org.gwtbootstrap3.client.ui.html" xmlns:t="urn:import:org.sagebionetworks.web.client.view.bootstrap.table" diff --git a/src/main/resources/org/sagebionetworks/web/client/widget/entity/renderer/HtmlPreviewViewImpl.ui.xml b/src/main/resources/org/sagebionetworks/web/client/widget/entity/renderer/HtmlPreviewViewImpl.ui.xml index 87d4056394..441e0560e0 100644 --- a/src/main/resources/org/sagebionetworks/web/client/widget/entity/renderer/HtmlPreviewViewImpl.ui.xml +++ b/src/main/resources/org/sagebionetworks/web/client/widget/entity/renderer/HtmlPreviewViewImpl.ui.xml @@ -2,7 +2,6 @@