From cd56edd5379429074066ba9e1da57bd3f37e2f65 Mon Sep 17 00:00:00 2001 From: Serge Rider Date: Mon, 30 Nov 2020 18:43:44 +0300 Subject: [PATCH 1/2] CB-572 Static servlet: add cache control field --- .../io.cloudbeaver.server/META-INF/MANIFEST.MF | 1 + .../server/jetty/CBImageServlet.java | 8 ++++---- .../server/jetty/CBStaticServlet.java | 17 +++++++++++++++-- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/server/bundles/io.cloudbeaver.server/META-INF/MANIFEST.MF b/server/bundles/io.cloudbeaver.server/META-INF/MANIFEST.MF index 9b302e25ca..fbbb303c4d 100644 --- a/server/bundles/io.cloudbeaver.server/META-INF/MANIFEST.MF +++ b/server/bundles/io.cloudbeaver.server/META-INF/MANIFEST.MF @@ -21,6 +21,7 @@ Require-Bundle: org.eclipse.core.runtime;visibility:=reexport, javax.servlet;visibility:=reexport, org.eclipse.jetty.server;visibility:=reexport, org.eclipse.jetty.servlet;visibility:=reexport, + org.eclipse.jetty.http, org.eclipse.jetty.util;visibility:=reexport, com.google.gson;visibility:=reexport, org.jkiss.bundle.graphql.java;visibility:=reexport, diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jetty/CBImageServlet.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jetty/CBImageServlet.java index 7eff6294e5..1a0707637e 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jetty/CBImageServlet.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jetty/CBImageServlet.java @@ -56,7 +56,7 @@ public class CBImageServlet extends HttpServlet { } response.setContentType("image/" + iconExt); - setExpireTime(response, 60 * 60 * 24 * 3); // 3 days + setExpireTime(response); // 3 days ByteArrayOutputStream buffer = new ByteArrayOutputStream(); try (InputStream is = new BufferedInputStream(iconURL.openStream())) { IOUtils.copyStream(is, buffer); @@ -70,11 +70,11 @@ public class CBImageServlet extends HttpServlet { } } - private void setExpireTime(HttpServletResponse response, long expiresSeconds) { + private void setExpireTime(HttpServletResponse response) { // Http 1.0 header, set a fix expires date. - response.setDateHeader("Expires", System.currentTimeMillis() + expiresSeconds * 1000); + response.setDateHeader("Expires", System.currentTimeMillis() + CBStaticServlet.STATIC_CACHE_SECONDS * 1000); // Http 1.1 header, set a time after now. - response.setHeader("Cache-Control", "public, max-age=" + expiresSeconds); + response.setHeader("Cache-Control", "public, max-age=" + CBStaticServlet.STATIC_CACHE_SECONDS); } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jetty/CBStaticServlet.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jetty/CBStaticServlet.java index 0c0a82a7ba..4d212c4d52 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jetty/CBStaticServlet.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/jetty/CBStaticServlet.java @@ -1,20 +1,33 @@ package io.cloudbeaver.server.jetty; +import org.eclipse.jetty.http.HttpField; +import org.eclipse.jetty.http.HttpHeader; import org.eclipse.jetty.server.ResourceService; import org.eclipse.jetty.servlet.DefaultServlet; +import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; @WebServlet(urlPatterns = "/") public class CBStaticServlet extends DefaultServlet { + public static final int STATIC_CACHE_SECONDS = 60 * 60 * 24 * 3; + public CBStaticServlet() { -// super(makeResourceService()); - super(); + super(makeResourceService()); + } + + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + super.doGet(request, response); } private static ResourceService makeResourceService() { ResourceService resourceService = new ResourceService(); + resourceService.setCacheControl(new HttpField(HttpHeader.CACHE_CONTROL, "public, max-age=" + STATIC_CACHE_SECONDS)); return resourceService; } From fa0b2c89fc75ae088560d4927205cd68bd7c7ae9 Mon Sep 17 00:00:00 2001 From: Wroud Date: Mon, 30 Nov 2020 21:02:51 +0300 Subject: [PATCH 2/2] fix(core-blocks): CB-560 tab selection on first render --- .../src/Administration/Administration.tsx | 8 +++++++- webapp/packages/core-blocks/src/Tabs/TabsState.tsx | 11 ++--------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/webapp/packages/core-administration/src/Administration/Administration.tsx b/webapp/packages/core-administration/src/Administration/Administration.tsx index e516b184ae..e3de8247ed 100644 --- a/webapp/packages/core-administration/src/Administration/Administration.tsx +++ b/webapp/packages/core-administration/src/Administration/Administration.tsx @@ -7,6 +7,7 @@ */ import { observer } from 'mobx-react'; +import { useLayoutEffect, useRef } from 'react'; import styled, { css } from 'reshadow'; import { TabsState, TabList, verticalTabStyles } from '@cloudbeaver/core-blocks'; @@ -75,9 +76,14 @@ type Props = React.PropsWithChildren<{ export const Administration: React.FC = observer(function Administration({ configurationWizard, activeScreen, onItemSelect, children, }) { + const contentRef = useRef(null); const controller = useController(AdministrationController); const items = controller.getItems(configurationWizard); + useLayoutEffect(() => { + contentRef.current?.scrollTo({ top: 0, left: 0 }); + }, [activeScreen?.item]); + return styled(useStyles(verticalTabStyles, administrationStyles, tabsStyles))( @@ -94,7 +100,7 @@ export const Administration: React.FC = observer(function Administration( ))} - + {children} >({ open: onOpen, close: onClose, props: rest as T, - selectedId: null as string | null | undefined, + selectedId: selectedId || currentTabId, state, }); @@ -76,21 +76,14 @@ export function TabsState>({ state.selectedId = currentTabId; } - useEffect(() => { - if (!currentTabId) { - return; - } - state.select(currentTabId); - }, [currentTabId]); // hack currentId and selectedId not works - useEffect(() => { const openHandler: IExecutorHandler> = data => { + dynamic.current.open?.(data); if (dynamic.current.selectedId === data.tabId) { return false; } dynamic.current.selectedId = data.tabId; dynamic.current.state.select(data.tabId); - dynamic.current.open?.(data); return undefined; }; const closeHandler: IExecutorHandler> = data => dynamic.current.close?.(data);