From a9481be9521340c5d4334e6e13facc9bbc665228 Mon Sep 17 00:00:00 2001
From: Paul Rosenzweig <paulrosenzweig@users.noreply.github.com>
Date: Fri, 23 Aug 2019 13:37:14 -0400
Subject: [PATCH] keep refreshElapsed state in refresh widget (#10505)

---
 .../dashboard/components/Dashboard.jsx        |  2 +-
 .../dashboard/components/DashboardActions.jsx |  4 +-
 .../dashboard/components/DashboardHeader.jsx  |  4 +-
 .../dashboard/components/RefreshWidget.jsx    | 22 +++++++++-
 .../dashboard/hoc/DashboardControls.jsx       | 40 +++++++++++--------
 5 files changed, 50 insertions(+), 22 deletions(-)

diff --git a/frontend/src/metabase/dashboard/components/Dashboard.jsx b/frontend/src/metabase/dashboard/components/Dashboard.jsx
index ccf06356e7e..d120e64aba7 100644
--- a/frontend/src/metabase/dashboard/components/Dashboard.jsx
+++ b/frontend/src/metabase/dashboard/components/Dashboard.jsx
@@ -90,7 +90,7 @@ type Props = {
   editingParameter: ?Parameter,
 
   refreshPeriod: number,
-  refreshElapsed: number,
+  setRefreshElapsedHook: Function,
   isFullscreen: boolean,
   isNightMode: boolean,
   hideParameters: ?string,
diff --git a/frontend/src/metabase/dashboard/components/DashboardActions.jsx b/frontend/src/metabase/dashboard/components/DashboardActions.jsx
index 4f26a710a8d..deec3e45668 100644
--- a/frontend/src/metabase/dashboard/components/DashboardActions.jsx
+++ b/frontend/src/metabase/dashboard/components/DashboardActions.jsx
@@ -13,7 +13,7 @@ export const getDashboardActions = ({
   onNightModeChange,
   onFullscreenChange,
   refreshPeriod,
-  refreshElapsed,
+  setRefreshElapsedHook,
   onRefreshPeriodChange,
 }) => {
   const buttons = [];
@@ -25,7 +25,7 @@ export const getDashboardActions = ({
         data-metabase-event="Dashboard;Refresh Menu Open"
         className="text-brand-hover"
         period={refreshPeriod}
-        elapsed={refreshElapsed}
+        setRefreshElapsedHook={setRefreshElapsedHook}
         onChangePeriod={onRefreshPeriodChange}
       />,
     );
diff --git a/frontend/src/metabase/dashboard/components/DashboardHeader.jsx b/frontend/src/metabase/dashboard/components/DashboardHeader.jsx
index 22cd653067d..ccf69ddc83c 100644
--- a/frontend/src/metabase/dashboard/components/DashboardHeader.jsx
+++ b/frontend/src/metabase/dashboard/components/DashboardHeader.jsx
@@ -49,7 +49,7 @@ type Props = {
   isNightMode: boolean,
 
   refreshPeriod: ?number,
-  refreshElapsed: ?number,
+  setRefreshElapsedHook: Function,
 
   parametersWidget: React$Element<*>,
 
@@ -90,7 +90,7 @@ export default class DashboardHeader extends Component {
     isNightMode: PropTypes.bool.isRequired,
 
     refreshPeriod: PropTypes.number,
-    refreshElapsed: PropTypes.number,
+    setRefreshElapsedHook: PropTypes.func.isRequired,
 
     addCardToDashboard: PropTypes.func.isRequired,
     addTextDashCardToDashboard: PropTypes.func.isRequired,
diff --git a/frontend/src/metabase/dashboard/components/RefreshWidget.jsx b/frontend/src/metabase/dashboard/components/RefreshWidget.jsx
index 875ac2e66f8..3c131e4afc6 100644
--- a/frontend/src/metabase/dashboard/components/RefreshWidget.jsx
+++ b/frontend/src/metabase/dashboard/components/RefreshWidget.jsx
@@ -20,8 +20,28 @@ const OPTIONS = [
 ];
 
 export default class RefreshWidget extends Component {
+  state = { elapsed: null };
+
+  componentWillMount() {
+    const { setRefreshElapsedHook } = this.props;
+    if (setRefreshElapsedHook) {
+      setRefreshElapsedHook(elapsed => this.setState({ elapsed }));
+    }
+  }
+
+  componentDidUpdate(prevProps) {
+    const { setRefreshElapsedHook } = this.props;
+    if (
+      setRefreshElapsedHook &&
+      prevProps.setRefreshElapsedHook !== setRefreshElapsedHook
+    ) {
+      setRefreshElapsedHook(elapsed => this.setState({ elapsed }));
+    }
+  }
+
   render() {
-    const { period, elapsed, onChangePeriod, className } = this.props;
+    const { period, onChangePeriod, className } = this.props;
+    const { elapsed } = this.state;
     const remaining = period - elapsed;
     return (
       <PopoverWithTrigger
diff --git a/frontend/src/metabase/dashboard/hoc/DashboardControls.jsx b/frontend/src/metabase/dashboard/hoc/DashboardControls.jsx
index bb10825f7dd..d8a325991c8 100644
--- a/frontend/src/metabase/dashboard/hoc/DashboardControls.jsx
+++ b/frontend/src/metabase/dashboard/hoc/DashboardControls.jsx
@@ -25,11 +25,10 @@ type State = {
   isFullscreen: boolean,
   isNightMode: boolean,
   refreshPeriod: ?number,
-  refreshElapsed: ?number,
   hideParameters: ?string,
 };
 
-const TICK_PERIOD = 0.25; // seconds
+const TICK_PERIOD = 1; // seconds
 
 /* This contains some state for dashboard controls on both private and embedded dashboards.
  * It should probably be in Redux?
@@ -51,13 +50,15 @@ export default (ComposedComponent: ReactClass<any>) =>
         isNightMode: false,
 
         refreshPeriod: null,
-        refreshElapsed: null,
 
         hideParameters: null,
       };
 
       _interval: ?number;
 
+      _refreshElapsed: ?number;
+      _refreshElapsedHook: ?Function;
+
       componentWillMount() {
         if (screenfull.enabled) {
           document.addEventListener(
@@ -139,17 +140,16 @@ export default (ComposedComponent: ReactClass<any>) =>
             this._tickRefreshClock,
             TICK_PERIOD * 1000,
           );
-          this.setState({ refreshPeriod, refreshElapsed: 0 });
+          this.setState({ refreshPeriod });
+          this.setRefreshElapsed(0);
           MetabaseAnalytics.trackEvent(
             "Dashboard",
             "Set Refresh",
             refreshPeriod,
           );
         } else {
-          this.setState({
-            refreshPeriod: null,
-            refreshElapsed: null,
-          });
+          this.setState({ refreshPeriod: null });
+          this.setRefreshElapsed(null);
         }
       };
 
@@ -177,12 +177,10 @@ export default (ComposedComponent: ReactClass<any>) =>
       };
 
       _tickRefreshClock = async () => {
-        const refreshElapsed = (this.state.refreshElapsed || 0) + TICK_PERIOD;
-        if (
-          this.state.refreshPeriod &&
-          refreshElapsed >= this.state.refreshPeriod
-        ) {
-          this.setState({ refreshElapsed: 0 });
+        this._refreshElapsed = (this._refreshElapsed || 0) + TICK_PERIOD;
+        const { refreshPeriod } = this.state;
+        if (refreshPeriod && this._refreshElapsed >= refreshPeriod) {
+          this._refreshElapsed = 0;
           await this.props.fetchDashboard(
             this.props.dashboardId,
             this.props.location.query,
@@ -191,9 +189,8 @@ export default (ComposedComponent: ReactClass<any>) =>
             reload: true,
             clear: false,
           });
-        } else {
-          this.setState({ refreshElapsed });
         }
+        this.setRefreshElapsed(this._refreshElapsed);
       };
 
       _clearRefreshInterval() {
@@ -219,11 +216,22 @@ export default (ComposedComponent: ReactClass<any>) =>
         this.setState({ isFullscreen: !!screenfull.isFullscreen });
       };
 
+      setRefreshElapsedHook = hook => {
+        this._refreshElapsedHook = hook;
+      };
+
+      setRefreshElapsed = elapsed => {
+        if (this._refreshElapsedHook) {
+          this._refreshElapsedHook(elapsed);
+        }
+      };
+
       render() {
         return (
           <ComposedComponent
             {...this.props}
             {...this.state}
+            setRefreshElapsedHook={this.setRefreshElapsedHook}
             loadDashboardParams={this.loadDashboardParams}
             updateDashboardParams={this.updateDashboardParams}
             onNightModeChange={this.setNightMode}
-- 
GitLab