You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by ru...@apache.org on 2020/04/28 04:37:39 UTC

[incubator-superset] branch master updated: [fix] Push browser history on pagination in react listviews (#9624)

This is an automated email from the ASF dual-hosted git repository.

rusackas pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git


The following commit(s) were added to refs/heads/master by this push:
     new c474ea8  [fix] Push browser history on pagination in react listviews (#9624)
c474ea8 is described below

commit c474ea848a1c5e611d1b30301686aa83eb2cda06
Author: Lily Kuang <li...@preset.io>
AuthorDate: Mon Apr 27 21:37:22 2020 -0700

    [fix] Push browser history on pagination in react listviews (#9624)
    
    * improve history for query params
    
    * fix: push browser history on pagination in react listviews
    
    * fix spec
    
    Co-authored-by: Tai Dupree <td...@gmail.com>
---
 .../components/ListView/ListView_spec.jsx          | 32 +++++++++++++++-----
 superset-frontend/src/components/ListView/utils.ts | 19 ++++++++++--
 superset-frontend/src/welcome/App.jsx              | 35 ++++++++++++----------
 3 files changed, 60 insertions(+), 26 deletions(-)

diff --git a/superset-frontend/spec/javascripts/components/ListView/ListView_spec.jsx b/superset-frontend/spec/javascripts/components/ListView/ListView_spec.jsx
index 3630f93..637667b 100644
--- a/superset-frontend/spec/javascripts/components/ListView/ListView_spec.jsx
+++ b/superset-frontend/spec/javascripts/components/ListView/ListView_spec.jsx
@@ -21,6 +21,7 @@ import { mount, shallow } from 'enzyme';
 import { act } from 'react-dom/test-utils';
 import { MenuItem, Pagination } from 'react-bootstrap';
 import Select from 'react-select';
+import { QueryParamProvider } from 'use-query-params';
 
 import ListView from 'src/components/ListView/ListView';
 import ListViewFilters from 'src/components/ListView/Filters';
@@ -29,6 +30,16 @@ import { areArraysShallowEqual } from 'src/reduxUtils';
 import { ThemeProvider } from 'emotion-theming';
 import { supersetTheme } from '@superset-ui/style';
 
+export function makeMockLocation(query) {
+  const queryStr = encodeURIComponent(query);
+  return {
+    protocol: 'http:',
+    host: 'localhost',
+    pathname: '/',
+    search: queryStr.length ? `?${queryStr}` : '',
+  };
+}
+
 const mockedProps = {
   title: 'Data Table',
   columns: [
@@ -64,11 +75,19 @@ const mockedProps = {
   bulkActions: [{ name: 'do something', onSelect: jest.fn() }],
 };
 
+const factory = (props = mockedProps) =>
+  mount(
+    <QueryParamProvider location={makeMockLocation()}>
+      <ListView {...props} />
+    </QueryParamProvider>,
+    {
+      wrappingComponent: ThemeProvider,
+      wrappingComponentProps: { theme: supersetTheme },
+    },
+  );
+
 describe('ListView', () => {
-  const wrapper = mount(<ListView {...mockedProps} />, {
-    wrappingComponent: ThemeProvider,
-    wrappingComponentProps: { theme: supersetTheme },
-  });
+  const wrapper = factory();
 
   afterEach(() => {
     mockedProps.fetchData.mockClear();
@@ -327,10 +346,7 @@ describe('ListView with new UI filters', () => {
     ],
   };
 
-  const wrapper = mount(<ListView {...newFiltersProps} />, {
-    wrappingComponent: ThemeProvider,
-    wrappingComponentProps: { theme: supersetTheme },
-  });
+  const wrapper = factory(newFiltersProps);
 
   afterEach(() => {
     mockedProps.fetchData.mockClear();
diff --git a/superset-frontend/src/components/ListView/utils.ts b/superset-frontend/src/components/ListView/utils.ts
index 6bc643a..6ce2665 100644
--- a/superset-frontend/src/components/ListView/utils.ts
+++ b/superset-frontend/src/components/ListView/utils.ts
@@ -33,6 +33,8 @@ import {
   useQueryParams,
 } from 'use-query-params';
 
+import { isEqual } from 'lodash';
+
 import {
   FetchDataConfig,
   Filter,
@@ -191,7 +193,7 @@ export function useListViewState({
   useEffect(() => {
     if (initialFilters.length) {
       setInternalFilters(
-        mergeCreateFilterValues(initialFilters, query.filters),
+        mergeCreateFilterValues(initialFilters, query.filters || []),
       );
     }
   }, [initialFilters]);
@@ -205,10 +207,23 @@ export function useListViewState({
       queryParams.sortColumn = sortBy[0].id;
       queryParams.sortOrder = sortBy[0].desc ? 'desc' : 'asc';
     }
-    setQuery(queryParams);
+
+    const method =
+      typeof query.pageIndex !== 'undefined' &&
+      queryParams.pageIndex !== query.pageIndex
+        ? 'push'
+        : 'replace';
+
+    setQuery(queryParams, method);
     fetchData({ pageIndex, pageSize, sortBy, filters });
   }, [fetchData, pageIndex, pageSize, sortBy, filters]);
 
+  useEffect(() => {
+    if (!isEqual(initialState.pageIndex, pageIndex)) {
+      gotoPage(initialState.pageIndex);
+    }
+  }, [query]);
+
   const filtersApplied = internalFilters.every(
     ({ id, value, operator }, index) =>
       id &&
diff --git a/superset-frontend/src/welcome/App.jsx b/superset-frontend/src/welcome/App.jsx
index fcdfd79..c97dea1 100644
--- a/superset-frontend/src/welcome/App.jsx
+++ b/superset-frontend/src/welcome/App.jsx
@@ -22,6 +22,7 @@ import thunk from 'redux-thunk';
 import { createStore, applyMiddleware, compose, combineReducers } from 'redux';
 import { Provider } from 'react-redux';
 import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
+import { QueryParamProvider } from 'use-query-params';
 import { ThemeProvider } from 'emotion-theming';
 
 import { initFeatureFlags } from 'src/featureFlags';
@@ -60,22 +61,24 @@ const App = () => (
   <Provider store={store}>
     <ThemeProvider theme={supersetTheme}>
       <Router>
-        <Menu data={menu} />
-        <Switch>
-          <Route path="/superset/welcome/">
-            <Welcome user={user} />
-          </Route>
-          <Route path="/dashboard/list/">
-            <DashboardList user={user} />
-          </Route>
-          <Route path="/chart/list/">
-            <ChartList user={user} />
-          </Route>
-          <Route path="/tablemodelview/list/">
-            <DatasetList user={user} />
-          </Route>
-        </Switch>
-        <ToastPresenter />
+        <QueryParamProvider ReactRouterRoute={Route}>
+          <Menu data={menu} />
+          <Switch>
+            <Route path="/superset/welcome/">
+              <Welcome user={user} />
+            </Route>
+            <Route path="/dashboard/list/">
+              <DashboardList user={user} />
+            </Route>
+            <Route path="/chart/list/">
+              <ChartList user={user} />
+            </Route>
+            <Route path="/tablemodelview/list/">
+              <DatasetList user={user} />
+            </Route>
+          </Switch>
+          <ToastPresenter />
+        </QueryParamProvider>
       </Router>
     </ThemeProvider>
   </Provider>