From e0dc4dd810a89ab7bf08fe631047b3466bef1919 Mon Sep 17 00:00:00 2001
From: Alexander Polyankin <alexander.polyankin@metabase.com>
Date: Tue, 2 Nov 2021 11:33:27 +0300
Subject: [PATCH] Add entity polling to EntityListLoader (#18786)

---
 .../entities/containers/EntityListLoader.jsx  | 30 +++++++++++++++++--
 1 file changed, 27 insertions(+), 3 deletions(-)

diff --git a/frontend/src/metabase/entities/containers/EntityListLoader.jsx b/frontend/src/metabase/entities/containers/EntityListLoader.jsx
index 8ac537d8360..6b3e5835f38 100644
--- a/frontend/src/metabase/entities/containers/EntityListLoader.jsx
+++ b/frontend/src/metabase/entities/containers/EntityListLoader.jsx
@@ -13,6 +13,7 @@ const propTypes = {
   entityType: PropTypes.string,
   entityQuery: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
   reload: PropTypes.bool,
+  reloadInterval: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),
   wrapped: PropTypes.bool,
   debounced: PropTypes.bool,
   loadingAndErrorWrapper: PropTypes.bool,
@@ -50,6 +51,7 @@ const CONSUMED_PROPS = [
   "entityType",
   "entityQuery",
   // "reload", // Masked by `reload` function. Should we rename that?
+  "reloadInterval",
   "wrapped",
   "debounced",
   "loadingAndErrorWrapper",
@@ -76,6 +78,7 @@ const getMemoizedEntityQuery = createMemoizedSelector(
   let {
     entityDef,
     entityQuery,
+    reloadInterval,
     page,
     pageSize,
     allLoading,
@@ -87,6 +90,9 @@ const getMemoizedEntityQuery = createMemoizedSelector(
   if (typeof entityQuery === "function") {
     entityQuery = entityQuery(state, props);
   }
+  if (typeof reloadInterval === "function") {
+    reloadInterval = reloadInterval(state, props);
+  }
   if (typeof pageSize === "number" && typeof page === "number") {
     entityQuery = { limit: pageSize, offset: pageSize * page, ...entityQuery };
   }
@@ -100,6 +106,7 @@ const getMemoizedEntityQuery = createMemoizedSelector(
 
   return {
     entityQuery,
+    reloadInterval,
     list: entityDef.selectors[selectorName](state, { entityQuery }),
     metadata,
     loading,
@@ -156,8 +163,13 @@ class EntityListLoader extends React.Component {
     250,
   );
 
-  UNSAFE_componentWillMount() {
-    this.fetchList(this.props, { reload: this.props.reload });
+  componentDidMount() {
+    const { loaded, reload, reloadInterval } = this.props;
+    this.fetchList(this.props, { reload });
+
+    if (loaded && reloadInterval) {
+      this.reloadTimeout = setTimeout(this.reload, reloadInterval);
+    }
   }
 
   UNSAFE_componentWillReceiveProps(nextProps) {
@@ -173,7 +185,7 @@ class EntityListLoader extends React.Component {
   }
 
   componentDidUpdate(prevProps) {
-    const { keepListWhileLoading } = this.props;
+    const { loaded, reloadInterval, keepListWhileLoading } = this.props;
     const { previousList } = this.state;
 
     const shouldUpdatePrevList =
@@ -184,6 +196,18 @@ class EntityListLoader extends React.Component {
     if (shouldUpdatePrevList) {
       this.setState({ previousList: prevProps.list });
     }
+
+    if (loaded && !prevProps.loaded) {
+      clearTimeout(this.reloadTimeout);
+
+      if (reloadInterval) {
+        this.reloadTimeout = setTimeout(this.reload, reloadInterval);
+      }
+    }
+  }
+
+  componentWillUnmount() {
+    clearTimeout(this.reloadTimeout);
   }
 
   renderChildren = () => {
-- 
GitLab