You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by yj...@apache.org on 2020/10/29 05:44:55 UTC

[incubator-superset] 12/33: remove lock file

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

yjc pushed a commit to branch home-screen-mvp
in repository https://gitbox.apache.org/repos/asf/incubator-superset.git

commit bf28bb6ec56f9e13afe8b26cb625afd9d60575a2
Author: Phillip Kelley-Dotson <pk...@yahoo.com>
AuthorDate: Thu Oct 8 14:27:51 2020 -0700

    remove lock file
---
 .../views/CRUD/welcome/ChartTable_spec.tsx         |  79 +++++
 .../views/CRUD/welcome/DashboardTable_spec.tsx     |   6 +-
 .../views/CRUD/welcome/SavedQueries_spec.tsx       |  32 ++
 .../views/CRUD/welcome/Welcome_spec.tsx            |   1 +
 .../src/components/ListViewCard/index.tsx          |   4 +-
 .../src/views/CRUD/chart/ChartCard.tsx             |   1 -
 .../src/views/CRUD/dashboard/DashboardList.tsx     |   4 +-
 superset-frontend/src/views/CRUD/utils.tsx         |  26 +-
 .../src/views/CRUD/welcome/ActivityTable.tsx       |  72 ++--
 .../src/views/CRUD/welcome/SavedQueries.tsx        |  19 +-
 .../src/views/CRUD/welcome/Welcome.tsx             | 365 ++++++++++-----------
 11 files changed, 360 insertions(+), 249 deletions(-)

diff --git a/superset-frontend/spec/javascripts/views/CRUD/welcome/ChartTable_spec.tsx b/superset-frontend/spec/javascripts/views/CRUD/welcome/ChartTable_spec.tsx
new file mode 100644
index 0000000..ed0666e
--- /dev/null
+++ b/superset-frontend/spec/javascripts/views/CRUD/welcome/ChartTable_spec.tsx
@@ -0,0 +1,79 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import React from 'react';
+import { mount } from 'enzyme';
+import thunk from 'redux-thunk';
+import fetchMock from 'fetch-mock';
+
+import waitForComponentToPaint from 'spec/helpers/waitForComponentToPaint';
+import configureStore from 'redux-mock-store';
+import ChartTable from 'src/views/CRUD/welcome/ChartTable';
+import ChartCard from 'src/views/CRUD/chart/ChartCard';
+
+// store needed for withToasts(DashboardTable)
+const mockStore = configureStore([thunk]);
+const store = mockStore({});
+
+const chartsEndpoint = 'glob:*/api/v1/chart/?*';
+// fetchMock.get(chartsEndpoint, { result: mockDashboards });
+
+const mockCharts = [...new Array(3)].map((_, i) => ({
+  changed_on_utc: new Date().toISOString(),
+  created_by: 'super user',
+  id: i,
+  slice_name: `cool chart ${i}`,
+  url: 'url',
+  viz_type: 'bar',
+  datasource_title: `ds${i}`,
+  thumbnail_url: '/thumbnail',
+}));
+
+/* fetchMock.get(chartsEndpoint, {
+  result: [],
+});
+*/
+fetchMock.get(chartsEndpoint, {
+  result: mockCharts,
+});
+
+describe('DashboardTable', () => {
+  beforeEach(fetchMock.resetHistory);
+
+  const mockedProps = {};
+  const wrapper = mount(<ChartTable {...mockedProps} />, {
+    context: { store },
+  });
+
+  /*beforeAll(async () => {
+    await waitForComponentToPaint(wrapper);
+  });*/
+
+  it('it renders', () => {
+    expect(wrapper.find(ChartTable)).toExist();
+  });
+  it('fetches chart favorites and renders chart cards ', () => {
+      console.log('mock call', fetchMock.calls(/chart\/\?q/))
+    expect(fetchMock.calls(chartsEndpoint)).toHaveLength(1);
+    console.log('wrapper', wrapper.dive());
+    // there's a delay between response and updating state, so manually set it
+    // rather than adding a timeout which could introduce flakiness
+    // wrapper.setState({ dashboards: mockDashboards });
+    expect(wrapper.find(ChartCard)).toExist();
+  });
+});
diff --git a/superset-frontend/spec/javascripts/views/CRUD/welcome/DashboardTable_spec.tsx b/superset-frontend/spec/javascripts/views/CRUD/welcome/DashboardTable_spec.tsx
index e09b5fe..4d2eb9e 100644
--- a/superset-frontend/spec/javascripts/views/CRUD/welcome/DashboardTable_spec.tsx
+++ b/superset-frontend/spec/javascripts/views/CRUD/welcome/DashboardTable_spec.tsx
@@ -23,8 +23,8 @@ import configureStore from 'redux-mock-store';
 import fetchMock from 'fetch-mock';
 import { supersetTheme, ThemeProvider } from '@superset-ui/core';
 
-import ListView from 'src/components/ListView';
 import DashboardTable from 'src/views/CRUD/welcome/DashboardTable';
+import DashboardCard from 'src/views/CRUD/welcome/DashboardCard';
 
 // store needed for withToasts(DashboardTable)
 const mockStore = configureStore([thunk]);
@@ -47,7 +47,7 @@ function setup() {
 describe('DashboardTable', () => {
   beforeEach(fetchMock.resetHistory);
 
-  it('fetches dashboards and renders a ListView', () => {
+  it('fetches dashboards and renders a ', () => {
     return new Promise(done => {
       const wrapper = setup();
 
@@ -56,7 +56,7 @@ describe('DashboardTable', () => {
         // there's a delay between response and updating state, so manually set it
         // rather than adding a timeout which could introduce flakiness
         wrapper.setState({ dashboards: mockDashboards });
-        expect(wrapper.find(ListView)).toExist();
+        expect(wrapper.find(DashboardCard)).toExist();
         done();
       });
     });
diff --git a/superset-frontend/spec/javascripts/views/CRUD/welcome/SavedQueries_spec.tsx b/superset-frontend/spec/javascripts/views/CRUD/welcome/SavedQueries_spec.tsx
index e69de29..d5c61b5 100644
--- a/superset-frontend/spec/javascripts/views/CRUD/welcome/SavedQueries_spec.tsx
+++ b/superset-frontend/spec/javascripts/views/CRUD/welcome/SavedQueries_spec.tsx
@@ -0,0 +1,32 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+import React from 'react';
+import { SavedQueries } from 'src/views/CRUD/welcome/SavedQueries'
+import { shallow } from 'enzyme';
+
+describe('SavedQueries', () => {
+  const 
+  it('is valid', () => {
+    expect(React.isValidElement(<SavedQueries />)).toBe(true);
+  });
+  it('SaveQueries renders up to three saved queries', ()=>{
+    //expect() 
+  })
+  
+});
\ No newline at end of file
diff --git a/superset-frontend/spec/javascripts/views/CRUD/welcome/Welcome_spec.tsx b/superset-frontend/spec/javascripts/views/CRUD/welcome/Welcome_spec.tsx
index 5db15b9..13c27b7 100644
--- a/superset-frontend/spec/javascripts/views/CRUD/welcome/Welcome_spec.tsx
+++ b/superset-frontend/spec/javascripts/views/CRUD/welcome/Welcome_spec.tsx
@@ -40,4 +40,5 @@ describe('Welcome', () => {
     const wrapper = shallow(<Welcome {...mockedProps} />);
     expect(wrapper.find('SubMenu')).toHaveLength(4);
   });
+  console.log('wrapper', )
 });
diff --git a/superset-frontend/src/components/ListViewCard/index.tsx b/superset-frontend/src/components/ListViewCard/index.tsx
index 7fb69c0..427beba 100644
--- a/superset-frontend/src/components/ListViewCard/index.tsx
+++ b/superset-frontend/src/components/ListViewCard/index.tsx
@@ -156,6 +156,7 @@ interface CardProps {
   rows?: number | string;
   avatar?: string;
   isRecent?: boolean;
+  tableName?: string;
 }
 
 function ListViewCard({
@@ -169,6 +170,7 @@ function ListViewCard({
   coverRight,
   actions,
   avatar,
+  tableName,
   loading,
   imgPosition = 'top',
   showImg = true,
@@ -213,7 +215,7 @@ function ListViewCard({
             </div>
             <div>
               <div>Datasource Name</div>
-              <div>{}</div>
+              <div>{tableName}</div>
             </div>
           </QueryData>
         ))
diff --git a/superset-frontend/src/views/CRUD/chart/ChartCard.tsx b/superset-frontend/src/views/CRUD/chart/ChartCard.tsx
index 1046f3a..e1ab61f 100644
--- a/superset-frontend/src/views/CRUD/chart/ChartCard.tsx
+++ b/superset-frontend/src/views/CRUD/chart/ChartCard.tsx
@@ -112,7 +112,6 @@ export default function ChartCard({
       )}
     </Menu>
   );
-  console.log('favorite status', favoriteStatusRef)
   return (
     <ListViewCard
       loading={loading}
diff --git a/superset-frontend/src/views/CRUD/dashboard/DashboardList.tsx b/superset-frontend/src/views/CRUD/dashboard/DashboardList.tsx
index 1fe8427..770122e 100644
--- a/superset-frontend/src/views/CRUD/dashboard/DashboardList.tsx
+++ b/superset-frontend/src/views/CRUD/dashboard/DashboardList.tsx
@@ -32,6 +32,8 @@ import Icon from 'src/components/Icon';
 import FaveStar from 'src/components/FaveStar';
 import PropertiesModal from 'src/dashboard/components/PropertiesModal';
 import TooltipWrapper from 'src/components/TooltipWrapper';
+
+import Dashboard from 'src/dashboard/containers/Dashboard';
 import DashboardCard from './DashboardCard';
 
 const PAGE_SIZE = 25;
@@ -415,7 +417,7 @@ function DashboardList(props: DashboardListProps) {
     },
   ];
 
-  function renderCard(dashboard: Dashboard & { loading: boolean }) {
+  function renderCard(dashboard: Dashboard) {
     return (
       <DashboardCard
         {...{
diff --git a/superset-frontend/src/views/CRUD/utils.tsx b/superset-frontend/src/views/CRUD/utils.tsx
index 0d5550e..bd6e9f0 100644
--- a/superset-frontend/src/views/CRUD/utils.tsx
+++ b/superset-frontend/src/views/CRUD/utils.tsx
@@ -53,18 +53,34 @@ const createFetchResourceMethod = (method: string) => (
   return [];
 };
 
-export const createBatchMethod = (queryParams: string) => {
-  return Promise.all([
+export const createBatchMethod = (queryParams: string, created?: string) => {
+  const baseBatch = [
     SupersetClient.get({ endpoint: `/api/v1/dashboard/?q=${queryParams}` }),
     SupersetClient.get({ endpoint: `/api/v1/chart/?q=${queryParams}` }),
-  ]).then(([dashboardRes, chartRes]) => {
+  ];
+  if (created)
+    baseBatch.push(
+      SupersetClient.get({ endpoint: `/api/v1/saved_query/?q=${queryParams}` }),
+    );
+  return Promise.all(baseBatch).then(([dashboardRes, chartRes, savedQuery]) => {
+    console.log('dashboard', dashboardRes);
+    console.log('chartRes', chartRes);
+    console.log('savedQuery', savedQuery);
     const results = [];
+    const ifQuery = savedQuery ? savedQuery.json?.result.slice(0, 3) : [];
+    console.log('-----slices--------');
+    console.log(dashboardRes?.json?.result.slice(0, 3));
+    console.log(chartRes?.json?.result.slice(0, 3));
+    console.log(ifQuery);
+    console.log('-----END Slices--------');
     results.push(
       ...[
-        ...dashboardRes.json.result.slice(0, 3),
-        ...chartRes.json.result.slice(0, 3),
+        ...dashboardRes.json?.result.slice(0, 3),
+        ...chartRes.json?.result.slice(0, 3),
+        ...ifQuery,
       ],
     );
+    console.log('result', results);
     return results;
   });
 };
diff --git a/superset-frontend/src/views/CRUD/welcome/ActivityTable.tsx b/superset-frontend/src/views/CRUD/welcome/ActivityTable.tsx
index de237b4..669838d 100644
--- a/superset-frontend/src/views/CRUD/welcome/ActivityTable.tsx
+++ b/superset-frontend/src/views/CRUD/welcome/ActivityTable.tsx
@@ -17,7 +17,6 @@
  * under the License.
  */
 import React, { useEffect, useState } from 'react';
-import { SupersetClient, t } from '@superset-ui/core';
 import rison from 'rison';
 import moment from 'moment';
 import ListViewCard from 'src/components/ListViewCard';
@@ -30,7 +29,12 @@ interface MapProps {
   slice_name: string;
   time: string;
   changed_on_utc: string;
-  item_url: string;
+  url: string;
+  sql: string;
+  dashboard_title: string;
+  label: string;
+  id: string;
+  table: object;
 }
 
 interface ActivityProps {
@@ -43,7 +47,8 @@ interface ActivityProps {
 export default function ActivityTable({ user, activityFilter }: ActivityProps) {
   const [active, setActiveState] = useState([]);
   const [loading, setLoading] = useState(false);
-  const recent = `/superset/recent_activity/${user.userId}/?limit=5`;
+  // this API uses Log for data which in some cases is can be empty
+  // const recent = `/superset/recent_activity/${user.userId}/?limit=5`;
   const filters = {
     // Chart and dashbaord uses same filters
     // for edited and created
@@ -63,31 +68,30 @@ export default function ActivityTable({ user, activityFilter }: ActivityProps) {
     ],
   };
 
-  const setData = (endpoint: string) => {
-    setLoading(true);
-    SupersetClient.get({ endpoint })
-      .then(({ json }) => {
-        setLoading(false);
+  const setBatchData = (q: string, created?: string) => {
+    createBatchMethod(q, created)
+      .then((res: Array<object>) =>
         // @ts-ignore
-        setActiveState(json);
-      })
-      .catch(() => {
-        setLoading(false);
-        createErrorHandler(() =>
-          addDangerToast(t('There was an issue fetching your resource')),
-        );
-      });
+        setActiveState(res),
+      )
+      .catch(() => addDangerToast('Oops something went wrong'));
   };
 
-  const setBatchData = (q: string) => {
-    // @ts-ignore
-    createBatchMethod(q).then((res: Array<object>) => setActiveState(res));
+  const getFilterTitle = (e: MapProps) => {
+    if (e.dashboard_title) return e.dashboard_title;
+    if (e.label) return e.label;
+    if (e.url && !e.table) return e.item_title;
+    return e.slice_name;
   };
 
-  const getIconName = (name: string | undefined) => {
-    if (name === 'explore_json') return 'sql';
-    if (name === 'dashboard') return 'nav-dashboard';
-    if (name === 'log' || name === 'explore') return 'nav-charts';
+  const getIconName = (e: MapProps) => {
+    if (e.sql) return 'sql';
+    if (e.url.indexOf('dashboard') !== -1) {
+      return 'nav-dashboard';
+    }
+    if (e.url.indexOf('explore') !== -1) {
+      return 'nav-charts';
+    }
     return '';
   };
 
@@ -99,14 +103,11 @@ export default function ActivityTable({ user, activityFilter }: ActivityProps) {
       page_size: 0,
       filters: activityFilter !== 'Created' ? filters.edited : filters.created,
     });
-    if (activityFilter === 'Viewed') {
-      setData(recent);
-    }
     if (activityFilter === 'Edited') {
       setBatchData(queryParams);
     }
     if (activityFilter === 'Created') {
-      setBatchData(queryParams);
+      setBatchData(queryParams, 'createdBy');
     }
   };
 
@@ -115,18 +116,17 @@ export default function ActivityTable({ user, activityFilter }: ActivityProps) {
   }, [activityFilter]);
 
   const renderActivity = () => {
-    return active.map((e: MapProps) => (
+    return active.map((e: MapProps, i) => (
       <ListViewCard
+        key={`${i}`}
         isRecent
         loading={loading}
-        imgURL={null}
-        imgFallbackURL={null}
-        url={e.item_url}
-        title={activityFilter === 'Viewed' ? e.item_title : e.slice_name}
-        description={moment
-          .utc(activityFilter === 'Viewd' ? e.time : e.changed_on_utc)
-          .fromNow()}
-        avatar={getIconName(e.action)}
+        imgURL=""
+        imgFallbackURL=""
+        url={e.sql ? `/supserset/sqllab?queryId=${e.id}` : e.url}
+        title={getFilterTitle(e)}
+        description={moment.utc(e.changed_on_utc).fromNow()}
+        avatar={getIconName(e)}
         actions={null}
       />
     ));
diff --git a/superset-frontend/src/views/CRUD/welcome/SavedQueries.tsx b/superset-frontend/src/views/CRUD/welcome/SavedQueries.tsx
index d30db0b..c60d4fb 100644
--- a/superset-frontend/src/views/CRUD/welcome/SavedQueries.tsx
+++ b/superset-frontend/src/views/CRUD/welcome/SavedQueries.tsx
@@ -17,7 +17,7 @@
  * under the License.
  */
 import React, { useEffect, useState } from 'react';
-import { t, SupersetClient } from '@superset-ui/core';
+import { t } from '@superset-ui/core';
 import withToasts from 'src/messageToasts/enhancers/withToasts';
 import { Dropdown, Menu } from 'src/common/components';
 import { useListViewResource } from 'src/views/CRUD/hooks';
@@ -28,6 +28,7 @@ import { addDangerToast } from 'src/messageToasts/actions';
 const PAGE_SIZE = 3;
 
 interface Query {
+  sql_tables: array;
   database: {
     database_name: string;
   };
@@ -37,15 +38,18 @@ interface Query {
   addDangerToast: () => void;
 }
 
-interface StateProps {
-  queries: Array<Query>;
+interface SavedQueriesProps {
+  user: {
+    userId: string | number;
+  };
+  queryFilter: string;
 }
 
-const SavedQueries = ({ user, queryFilter }) => {
+const SavedQueries = ({ user, queryFilter }: SavedQueriesProps) => {
   const {
     state: { loading, resourceCollection: queries },
     fetchData,
-  } = useListViewResource<Query>('query', t('query'), addDangerToast);
+  } = useListViewResource<Query>('saved_query', t('query'), addDangerToast);
   const getFilters = () => {
     const filters = [];
 
@@ -90,10 +94,11 @@ const SavedQueries = ({ user, queryFilter }) => {
       {queries ? (
         queries.map(q => (
           <ListViewCard
-            imgFallbackURL={null}
-            imgURL={null}
+            imgFallbackURL="/static/assets/images/dashboard-card-fallback.png"
+            imgURL=""
             title={q.database.database_name}
             rows={q.rows}
+            tableName={q.sql_tables[0].table}
             loading={loading}
             description={t('Last run ', q.end_time)}
             showImg={false}
diff --git a/superset-frontend/src/views/CRUD/welcome/Welcome.tsx b/superset-frontend/src/views/CRUD/welcome/Welcome.tsx
index b4326fc..f6015b7 100644
--- a/superset-frontend/src/views/CRUD/welcome/Welcome.tsx
+++ b/superset-frontend/src/views/CRUD/welcome/Welcome.tsx
@@ -17,11 +17,9 @@
  * under the License.
  */
 import React, { useState } from 'react';
-import { FormControl } from 'react-bootstrap';
 import SubMenu from 'src/components/Menu/SubMenu';
 import { styled, t } from '@superset-ui/core';
 import { Collapse } from 'src/common/components';
-import { useQueryParam, StringParam, QueryParamConfig } from 'use-query-params';
 import { User } from 'src/types/bootstrapTypes';
 import Icon from 'src/components/Icon';
 
@@ -36,9 +34,24 @@ interface WelcomeProps {
   user: User;
 }
 
+const WelcomeContainer = styled.div`
+  nav {
+    background-color: ${({ theme }) => theme.colors.grayscale.light4};
+    &:after {
+      content: '';
+      display: block;
+      border: 1px solid ${({ theme }) => theme.colors.grayscale.light2};
+      margin: 0px 26px;
+    }
+  }
+  .ant-card.ant-card-bordered {
+    border: 1px solid ${({ theme }) => theme.colors.grayscale.light2};
+  }
+`;
+
 const ActivityContainer = styled.div`
   display: grid;
-  grid-template-columns: repeat(auto-fit, minmax(300px, max-content));
+  grid-template-columns: repeat(auto-fit, minmax(31%, max-content));
   grid-gap: ${({ theme }) => theme.gridUnit * 8}px;
   justify-content: center;
   padding: ${({ theme }) => theme.gridUnit * 2}px
@@ -48,6 +61,7 @@ const ActivityContainer = styled.div`
 const IconContainer = styled.div`
   svg {
     vertical-align: -7px;
+    color: ${({ theme }) => theme.colors.primary.dark1};
   }
 `;
 export const CardContainer = styled.div`
@@ -56,219 +70,180 @@ export const CardContainer = styled.div`
   grid-gap: ${({ theme }) => theme.gridUnit * 8}px;
   justify-content: left;
   padding: ${({ theme }) => theme.gridUnit * 2}px
-    ${({ theme }) => theme.gridUnit * 4}px;
+    ${({ theme }) => theme.gridUnit * 6}px;
 `;
 
-function useSyncQueryState(
-  queryParam: string,
-  queryParamType: QueryParamConfig<
-    string | null | undefined,
-    string | undefined
-  >,
-  defaultState: string,
-): [string, (val: string) => void] {
-  const [queryState, setQueryState] = useQueryParam(queryParam, queryParamType);
-  const [state, setState] = useState(queryState || defaultState);
-
-  const setQueryStateAndState = (val: string) => {
-    setQueryState(val);
-    setState(val);
-  };
-
-  return [state, setQueryStateAndState];
-}
-
 export default function Welcome({ user }: WelcomeProps) {
   const [queryFilter, setQueryFilter] = useState('Favorite');
-  const [activityFilter, setActivityFilter] = useState('Viewed');
+  const [activityFilter, setActivityFilter] = useState('Edited');
   const [dashboardFilter, setDashboardFilter] = useState('Favorite');
   const [chartFilter, setChartFilter] = useState('Favorite');
-  const [searchQuery, setSearchQuery] = useSyncQueryState(
-    'search',
-    StringParam,
-    '',
-  );
 
   function ExpandIcon(): React.ReactNode {
     return <Icon name="caret-right" />;
   }
 
   return (
-    <Collapse defaultActiveKey={['1']} expandIcon={ExpandIcon} ghost>
-      <Panel header={t('Recents')} key="1">
-        <SubMenu
-          activeChild={activityFilter}
-          name=""
-          // eslint-disable-next-line react/no-children-prop
-          children={[
-            {
-              name: 'Viewed',
-              label: t('Viewed'),
-              onClick: () => setActivityFilter('Viewed'),
-            },
-            {
-              name: 'Edited',
-              label: t('Edited'),
-              onClick: () => setActivityFilter('Edited'),
-            },
-            {
-              name: 'Created',
-              label: t('Created'),
-              onClick: () => setActivityFilter('Created'),
-            },
-          ]}
-        />
-        <ActivityContainer>
-          <ActivityTable user={user} activityFilter={activityFilter} />
-        </ActivityContainer>
-      </Panel>
+    <WelcomeContainer>
+      <Collapse defaultActiveKey={['1']} ghost>
+        <Panel header={t('Recents')} key="1">
+          <SubMenu
+            activeChild={activityFilter}
+            name=""
+            // eslint-disable-next-line react/no-children-prop
+            children={[
+              {
+                name: 'Edited',
+                label: t('Edited'),
+                onClick: () => setActivityFilter('Edited'),
+              },
+              {
+                name: 'Created',
+                label: t('Created'),
+                onClick: () => setActivityFilter('Created'),
+              },
+            ]}
+          />
+          <ActivityContainer>
+            <ActivityTable user={user} activityFilter={activityFilter} />
+          </ActivityContainer>
+        </Panel>
 
-      <Panel header={t('Dashboards')} key="2">
-        <SubMenu
-          activeChild={dashboardFilter}
-          name=""
-          // eslint-disable-next-line react/no-children-prop
-          children={[
-            {
-              name: 'Favorite',
-              label: t('Favorite'),
-              onClick: () => setDashboardFilter('Favorite'),
-            },
-            {
-              name: 'Mine',
-              label: t('Mine'),
-              onClick: () => setDashboardFilter('Mine'),
-            },
-          ]}
-          buttons={[
-            {
-              name: (
-                <IconContainer>
-                  <Icon name="plus-small" /> DashBoard{' '}
-                </IconContainer>
-              ),
-              buttonStyle: 'tertiary',
-              onClick: () => {
-                // @ts-ignore
-                window.location = '/dashboard/new';
+        <Panel header={t('Dashboards')} key="2">
+          <SubMenu
+            activeChild={dashboardFilter}
+            name=""
+            // eslint-disable-next-line react/no-children-prop
+            children={[
+              {
+                name: 'Favorite',
+                label: t('Favorite'),
+                onClick: () => setDashboardFilter('Favorite'),
+              },
+              {
+                name: 'Mine',
+                label: t('Mine'),
+                onClick: () => setDashboardFilter('Mine'),
               },
-            },
-            {
-              name: 'View All',
-              buttonStyle: 'link',
-              onClick: () => {
-                // @ts-ignore
-                window.location = '/dashboard/list/';
+            ]}
+            buttons={[
+              {
+                name: (
+                  <IconContainer>
+                    <Icon name="plus-small" /> Dashboard{' '}
+                  </IconContainer>
+                ),
+                buttonStyle: 'tertiary',
+                onClick: () => {
+                  // @ts-ignore
+                  window.location = '/dashboard/new';
+                },
               },
-            },
-          ]}
-        />
-        <FormControl
-          type="text"
-          bsSize="sm"
-          placeholder="Search"
-          value={searchQuery}
-          // @ts-ignore React bootstrap types aren't quite right here
-          onChange={e => setSearchQuery(e.currentTarget.value)}
-        />
-        <CardContainer>
-          <DashboardTable
-            search={searchQuery}
-            dashboardFilter={dashboardFilter}
-            user={user}
+              {
+                name: 'View All',
+                buttonStyle: 'link',
+                onClick: () => {
+                  // @ts-ignore
+                  window.location = '/dashboard/list/';
+                },
+              },
+            ]}
           />
-        </CardContainer>
-      </Panel>
+          <CardContainer>
+            <DashboardTable dashboardFilter={dashboardFilter} user={user} />
+          </CardContainer>
+        </Panel>
 
-      <Panel header={t('Saved Queries')} key="3">
-        <SubMenu
-          activeChild={queryFilter}
-          name=""
-          // eslint-disable-next-line react/no-children-prop
-          children={[
-            {
-              name: 'Favorite',
-              label: t('Favorite'),
-              onClick: () => setQueryFilter('Favorite'),
-            },
-            {
-              name: 'Mine',
-              label: t('Mine'),
-              onClick: () => setQueryFilter('Mine'),
-            },
-          ]}
-          buttons={[
-            {
-              name: (
-                <IconContainer>
-                  <Icon name="plus-small" /> SQL Query{' '}
-                </IconContainer>
-              ),
-              buttonStyle: 'tertiary',
-              onClick: () => {
-                // @ts-ignore
-                window.location = '/superset/sqllab';
+        <Panel header={t('Saved Queries')} key="3">
+          <SubMenu
+            activeChild={queryFilter}
+            name=""
+            // eslint-disable-next-line react/no-children-prop
+            children={[
+              {
+                name: 'Favorite',
+                label: t('Favorite'),
+                onClick: () => setQueryFilter('Favorite'),
+              },
+              {
+                name: 'Mine',
+                label: t('Mine'),
+                onClick: () => setQueryFilter('Mine'),
               },
-            },
-            {
-              name: 'View All',
-              buttonStyle: 'link',
-              onClick: () => {
-                // @ts-ignore
-                window.location = 'superset/sqllab#search';
+            ]}
+            buttons={[
+              {
+                name: (
+                  <IconContainer>
+                    <Icon name="plus-small" /> SQL Query{' '}
+                  </IconContainer>
+                ),
+                buttonStyle: 'tertiary',
+                onClick: () => {
+                  // @ts-ignore
+                  window.location = '/superset/sqllab';
+                },
               },
-            },
-          ]}
-        />
-        <CardContainer>
-          <SavedQueries user={user} queryFilter={queryFilter} />
-        </CardContainer>
-      </Panel>
-      <Panel header={t('Charts')} key="4">
-        <SubMenu
-          activeChild={chartFilter}
-          name=""
-          // eslint-disable-next-line react/no-children-prop
-          children={[
-            {
-              name: 'Favorite',
-              label: t('Favorite'),
-              onClick: () => setChartFilter('Favorite'),
-            },
-            {
-              name: 'Mine',
-              label: t('Mine'),
-              onClick: () => setChartFilter('Mine'),
-            },
-          ]}
-          buttons={[
-            {
-              name: (
-                <IconContainer>
-                  <Icon name="plus-small" /> Chart{' '}
-                </IconContainer>
-              ),
-              buttonStyle: 'tertiary',
-              onClick: () => {
-                // @ts-ignore
-                window.location = '/chart/add';
+              {
+                name: 'View All',
+                buttonStyle: 'link',
+                onClick: () => {
+                  // @ts-ignore
+                  window.location = '/savedqueryview/list';
+                },
               },
-            },
-            {
-              name: 'View All',
-              buttonStyle: 'link',
-              onClick: () => {
-                // @ts-ignore
-                window.location = '/chart/list';
+            ]}
+          />
+          <CardContainer>
+            <SavedQueries user={user} queryFilter={queryFilter} />
+          </CardContainer>
+        </Panel>
+        <Panel header={t('Charts')} key="4">
+          <SubMenu
+            activeChild={chartFilter}
+            name=""
+            // eslint-disable-next-line react/no-children-prop
+            children={[
+              {
+                name: 'Favorite',
+                label: t('Favorite'),
+                onClick: () => setChartFilter('Favorite'),
+              },
+              {
+                name: 'Mine',
+                label: t('Mine'),
+                onClick: () => setChartFilter('Mine'),
+              },
+            ]}
+            buttons={[
+              {
+                name: (
+                  <IconContainer>
+                    <Icon name="plus-small" /> Chart{' '}
+                  </IconContainer>
+                ),
+                buttonStyle: 'tertiary',
+                onClick: () => {
+                  // @ts-ignore
+                  window.location = '/chart/add';
+                },
               },
-            },
-          ]}
-        />
+              {
+                name: 'View All',
+                buttonStyle: 'link',
+                onClick: () => {
+                  // @ts-ignore
+                  window.location = '/chart/list';
+                },
+              },
+            ]}
+          />
 
-        <CardContainer>
-          <ChartTable chartFilter={chartFilter} user={user} />
-        </CardContainer>
-      </Panel>
-    </Collapse>
+          <CardContainer>
+            <ChartTable chartFilter={chartFilter} user={user} />
+          </CardContainer>
+        </Panel>
+      </Collapse>
+    </WelcomeContainer>
   );
 }