diff --git a/superset-frontend/src/views/CRUD/types.ts b/superset-frontend/src/views/CRUD/types.ts index 659686e8c23e..c7e47ddeca9a 100644 --- a/superset-frontend/src/views/CRUD/types.ts +++ b/superset-frontend/src/views/CRUD/types.ts @@ -26,6 +26,7 @@ export type FavoriteStatus = { export enum TableTabTypes { FAVORITE = 'Favorite', MINE = 'Mine', + EXAMPLES = 'Examples', } export type Filters = { @@ -42,6 +43,7 @@ export interface DashboardTableProps { mine: Array; showThumbnails?: boolean; featureFlag?: boolean; + examples: Array; } export interface Dashboard { diff --git a/superset-frontend/src/views/CRUD/welcome/ActivityTable.tsx b/superset-frontend/src/views/CRUD/welcome/ActivityTable.tsx index 82d97aa956ca..1bacc30db615 100644 --- a/superset-frontend/src/views/CRUD/welcome/ActivityTable.tsx +++ b/superset-frontend/src/views/CRUD/welcome/ActivityTable.tsx @@ -219,17 +219,7 @@ export default function ActivityTable({ setInLocalStorage(HOMEPAGE_ACTIVITY_FILTER, SetTabType.VIEWED); }, }); - } else { - tabs.unshift({ - name: 'Examples', - label: t('Examples'), - onClick: () => { - setActiveChild('Examples'); - setInLocalStorage(HOMEPAGE_ACTIVITY_FILTER, SetTabType.EXAMPLE); - }, - }); } - const renderActivity = () => (activeChild !== 'Edited' ? activityData[activeChild] : editedObjs).map( (entity: ActivityObject) => { diff --git a/superset-frontend/src/views/CRUD/welcome/ChartTable.test.tsx b/superset-frontend/src/views/CRUD/welcome/ChartTable.test.tsx index 986a5bf94e55..c61cb1b33e1b 100644 --- a/superset-frontend/src/views/CRUD/welcome/ChartTable.test.tsx +++ b/superset-frontend/src/views/CRUD/welcome/ChartTable.test.tsx @@ -85,7 +85,7 @@ describe('ChartTable', () => { } }); await waitForComponentToPaint(wrapper); - expect(fetchMock.calls(chartsEndpoint)).toHaveLength(3); + expect(fetchMock.calls(chartsEndpoint)).toHaveLength(1); expect(wrapper.find('ChartCard')).toExist(); }); diff --git a/superset-frontend/src/views/CRUD/welcome/ChartTable.tsx b/superset-frontend/src/views/CRUD/welcome/ChartTable.tsx index 3fa7caad1978..e0a4ad904524 100644 --- a/superset-frontend/src/views/CRUD/welcome/ChartTable.tsx +++ b/superset-frontend/src/views/CRUD/welcome/ChartTable.tsx @@ -18,6 +18,7 @@ */ import React, { useState, useMemo, useEffect } from 'react'; import { t } from '@superset-ui/core'; +import { filter } from 'lodash'; import { useListViewResource, useChartEditModal, @@ -52,6 +53,7 @@ interface ChartTableProps { user?: User; mine: Array; showThumbnails: boolean; + examples?: Array; } function ChartTable({ @@ -60,10 +62,17 @@ function ChartTable({ addSuccessToast, mine, showThumbnails, + examples, }: ChartTableProps) { const history = useHistory(); const filterStore = getFromLocalStorage(HOMEPAGE_CHART_FILTER, null); - const initialFilter = filterStore || TableTabTypes.MINE; + let initialFilter = filterStore || TableTabTypes.EXAMPLES; + + if (!examples && filterStore === TableTabTypes.EXAMPLES) { + initialFilter = TableTabTypes.MINE; + } + + const filteredExamples = filter(examples, obj => 'viz_type' in obj); const { state: { loading, resourceCollection: charts, bulkSelectEnabled }, @@ -76,7 +85,7 @@ function ChartTable({ t('chart'), addDangerToast, true, - initialFilter === 'Favorite' ? [] : mine, + initialFilter === 'Mine' ? mine : filteredExamples, [], false, ); @@ -96,9 +105,13 @@ function ChartTable({ const [chartFilter, setChartFilter] = useState(initialFilter); const [preparingExport, setPreparingExport] = useState(false); + const [loaded, setLoaded] = useState(false); useEffect(() => { - getData(chartFilter); + if (loaded || chartFilter === 'Favorite') { + getData(chartFilter); + } + setLoaded(true); }, [chartFilter]); const handleBulkChartExport = (chartsToExport: Chart[]) => { @@ -118,7 +131,7 @@ function ChartTable({ operator: 'rel_o_m', value: `${user?.userId}`, }); - } else { + } else if (filterName === 'Favorite') { filters.push({ id: 'id', operator: 'chart_is_favorite', @@ -128,6 +141,36 @@ function ChartTable({ return filters; }; + const menuTabs = [ + { + name: 'Favorite', + label: t('Favorite'), + onClick: () => { + setChartFilter(TableTabTypes.FAVORITE); + setInLocalStorage(HOMEPAGE_CHART_FILTER, TableTabTypes.FAVORITE); + }, + }, + { + name: 'Mine', + label: t('Mine'), + onClick: () => { + setChartFilter(TableTabTypes.MINE); + setInLocalStorage(HOMEPAGE_CHART_FILTER, TableTabTypes.MINE); + }, + }, + ]; + + if (examples) { + menuTabs.push({ + name: 'Examples', + label: t('Examples'), + onClick: () => { + setChartFilter(TableTabTypes.EXAMPLES); + setInLocalStorage(HOMEPAGE_CHART_FILTER, TableTabTypes.EXAMPLES); + }, + }); + } + const getData = (filter: string) => fetchData({ pageIndex: 0, @@ -156,24 +199,7 @@ function ChartTable({ { - setChartFilter('Favorite'); - setInLocalStorage(HOMEPAGE_CHART_FILTER, TableTabTypes.FAVORITE); - }, - }, - { - name: 'Mine', - label: t('Mine'), - onClick: () => { - setChartFilter('Mine'); - setInLocalStorage(HOMEPAGE_CHART_FILTER, TableTabTypes.MINE); - }, - }, - ]} + tabs={menuTabs} buttons={[ { name: ( diff --git a/superset-frontend/src/views/CRUD/welcome/DashboardTable.test.tsx b/superset-frontend/src/views/CRUD/welcome/DashboardTable.test.tsx index 078b14d0e213..26fd3a13d32d 100644 --- a/superset-frontend/src/views/CRUD/welcome/DashboardTable.test.tsx +++ b/superset-frontend/src/views/CRUD/welcome/DashboardTable.test.tsx @@ -72,9 +72,9 @@ describe('DashboardTable', () => { it('render a submenu with clickable tabs and buttons', async () => { expect(wrapper.find('SubMenu')).toExist(); expect(wrapper.find('li.no-router')).toHaveLength(2); - expect(wrapper.find('Button')).toHaveLength(4); + expect(wrapper.find('Button')).toHaveLength(6); act(() => { - const handler = wrapper.find('li.no-router a').at(1).prop('onClick'); + const handler = wrapper.find('li.no-router a').at(0).prop('onClick'); if (handler) { handler({} as any); } diff --git a/superset-frontend/src/views/CRUD/welcome/DashboardTable.tsx b/superset-frontend/src/views/CRUD/welcome/DashboardTable.tsx index 8db07c98a35c..9e9cf6fc2ae4 100644 --- a/superset-frontend/src/views/CRUD/welcome/DashboardTable.tsx +++ b/superset-frontend/src/views/CRUD/welcome/DashboardTable.tsx @@ -18,6 +18,7 @@ */ import React, { useState, useMemo, useEffect } from 'react'; import { SupersetClient, t } from '@superset-ui/core'; +import { filter } from 'lodash'; import { useListViewResource, useFavoriteStatus } from 'src/views/CRUD/hooks'; import { Dashboard, @@ -54,10 +55,17 @@ function DashboardTable({ addSuccessToast, mine, showThumbnails, + examples, }: DashboardTableProps) { const history = useHistory(); const filterStore = getFromLocalStorage(HOMEPAGE_DASHBOARD_FILTER, null); - const defaultFilter = filterStore || TableTabTypes.MINE; + let defaultFilter = filterStore || TableTabTypes.EXAMPLES; + + if (!examples && filterStore === TableTabTypes.EXAMPLES) { + defaultFilter = TableTabTypes.MINE; + } + + const filteredExamples = filter(examples, obj => !('viz_type' in obj)); const { state: { loading, resourceCollection: dashboards }, @@ -70,7 +78,7 @@ function DashboardTable({ t('dashboard'), addDangerToast, true, - defaultFilter === 'Favorite' ? [] : mine, + defaultFilter === 'Mine' ? mine : filteredExamples, [], false, ); @@ -84,9 +92,13 @@ function DashboardTable({ const [editModal, setEditModal] = useState(); const [dashboardFilter, setDashboardFilter] = useState(defaultFilter); const [preparingExport, setPreparingExport] = useState(false); + const [loaded, setLoaded] = useState(false); useEffect(() => { - getData(dashboardFilter); + if (loaded || dashboardFilter === 'Favorite') { + getData(dashboardFilter); + } + setLoaded(true); }, [dashboardFilter]); const handleBulkDashboardExport = (dashboardsToExport: Dashboard[]) => { @@ -126,7 +138,7 @@ function DashboardTable({ operator: 'rel_m_m', value: `${user?.userId}`, }); - } else { + } else if (filterName === 'Favorite') { filters.push({ id: 'id', operator: 'dashboard_is_favorite', @@ -136,6 +148,36 @@ function DashboardTable({ return filters; }; + const menuTabs = [ + { + name: 'Favorite', + label: t('Favorite'), + onClick: () => { + setDashboardFilter(TableTabTypes.FAVORITE); + setInLocalStorage(HOMEPAGE_DASHBOARD_FILTER, TableTabTypes.FAVORITE); + }, + }, + { + name: 'Mine', + label: t('Mine'), + onClick: () => { + setDashboardFilter(TableTabTypes.MINE); + setInLocalStorage(HOMEPAGE_DASHBOARD_FILTER, TableTabTypes.MINE); + }, + }, + ]; + + if (examples) { + menuTabs.push({ + name: 'Examples', + label: t('Examples'), + onClick: () => { + setDashboardFilter(TableTabTypes.EXAMPLES); + setInLocalStorage(HOMEPAGE_DASHBOARD_FILTER, TableTabTypes.EXAMPLES); + }, + }); + } + const getData = (filter: string) => fetchData({ pageIndex: 0, @@ -154,27 +196,7 @@ function DashboardTable({ <> { - setDashboardFilter(TableTabTypes.FAVORITE); - setInLocalStorage( - HOMEPAGE_DASHBOARD_FILTER, - TableTabTypes.FAVORITE, - ); - }, - }, - { - name: 'Mine', - label: t('Mine'), - onClick: () => { - setDashboardFilter(TableTabTypes.MINE); - setInLocalStorage(HOMEPAGE_DASHBOARD_FILTER, TableTabTypes.MINE); - }, - }, - ]} + tabs={menuTabs} buttons={[ { name: ( diff --git a/superset-frontend/src/views/CRUD/welcome/Welcome.test.tsx b/superset-frontend/src/views/CRUD/welcome/Welcome.test.tsx index 85c953017ba1..d71864e6393b 100644 --- a/superset-frontend/src/views/CRUD/welcome/Welcome.test.tsx +++ b/superset-frontend/src/views/CRUD/welcome/Welcome.test.tsx @@ -132,10 +132,10 @@ describe('Welcome', () => { const savedQueryCall = fetchMock.calls(/saved_query\/\?q/); const recentCall = fetchMock.calls(/superset\/recent_activity\/*/); const dashboardCall = fetchMock.calls(/dashboard\/\?q/); - expect(chartCall).toHaveLength(2); + expect(chartCall).toHaveLength(1); expect(recentCall).toHaveLength(1); expect(savedQueryCall).toHaveLength(1); - expect(dashboardCall).toHaveLength(2); + expect(dashboardCall).toHaveLength(1); }); }); diff --git a/superset-frontend/src/views/CRUD/welcome/Welcome.tsx b/superset-frontend/src/views/CRUD/welcome/Welcome.tsx index 36a0e4459649..df446712a29c 100644 --- a/superset-frontend/src/views/CRUD/welcome/Welcome.tsx +++ b/superset-frontend/src/views/CRUD/welcome/Welcome.tsx @@ -54,6 +54,8 @@ export interface ActivityData { Examples?: Array; } +const DEFAULT_TAB_ARR = ['2', '3']; + const WelcomeContainer = styled.div` background-color: ${({ theme }) => theme.colors.grayscale.light4}; .ant-row.menu { @@ -114,11 +116,9 @@ function Welcome({ user, addDangerToast }: WelcomeProps) { null, ); const [loadedCount, setLoadedCount] = useState(0); - const [activeState, setActiveState] = useState>([ - '1', - '2', - '3', - ]); + const [activeState, setActiveState] = useState>( + DEFAULT_TAB_ARR, + ); const userid = user.userId; const id = userid.toString(); @@ -136,14 +136,15 @@ function Welcome({ user, addDangerToast }: WelcomeProps) { if (res.viewed) { const filtered = reject(res.viewed, ['item_url', null]).map(r => r); data.Viewed = filtered; - if (!activeTab) { + if (!activeTab && data.Viewed) { setActiveChild('Viewed'); + } else if (!activeTab && !data.Viewed) { + setActiveChild('Created'); } else setActiveChild(activeTab); } else { + if (!activeTab) setActiveChild('Created'); + else setActiveChild(activeTab); data.Examples = res.examples; - if (activeTab === 'Viewed' || !activeTab) { - setActiveChild('Examples'); - } else setActiveChild(activeTab); } setActivityData(activityData => ({ ...activityData, ...data })); }) @@ -200,9 +201,14 @@ function Welcome({ user, addDangerToast }: WelcomeProps) { }; useEffect(() => { + const defaultArr = DEFAULT_TAB_ARR; + if (activityData?.Viewed) { + defaultArr.push('1'); + } if (queryData?.length) { - setActiveState(['1', '2', '3', '4']); + defaultArr.push('4'); } + setActiveState(defaultArr); setActivityData(activityData => ({ ...activityData, Created: [ @@ -213,6 +219,8 @@ function Welcome({ user, addDangerToast }: WelcomeProps) { })); }, [chartData, queryData, dashboardData]); + const isRecentActivityLoading = + !activityData?.Examples && !activityData?.Viewed; return ( @@ -243,21 +251,27 @@ function Welcome({ user, addDangerToast }: WelcomeProps) { )} - {!dashboardData ? ( + {!dashboardData || isRecentActivityLoading ? ( ) : ( )} - {!chartData ? ( + {!chartData || isRecentActivityLoading ? ( ) : ( - + )}