mirror of
https://github.com/apache/superset.git
synced 2026-04-19 08:04:53 +00:00
feat: add sticky state to tables and loadingcards state. (#16102)
* initial feat commit * fix chart and dash rendering onload * Update superset-frontend/src/views/CRUD/welcome/Welcome.tsx Co-authored-by: Michael S. Molina <70410625+michael-s-molina@users.noreply.github.com> * fix jumpyness and add const Co-authored-by: Michael S. Molina <70410625+michael-s-molina@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
273ab3d257
commit
a70248736f
@@ -17,7 +17,8 @@
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
// storage keys for welcome page sticky tabs..
|
||||
// storage keys for welcome page sticky tabs and tables
|
||||
export const HOMEPAGE_CHART_FILTER = 'homepage_chart_filter';
|
||||
export const HOMEPAGE_ACTIVITY_FILTER = 'homepage_activity_filter';
|
||||
export const HOMEPAGE_DASHBOARD_FILTER = 'homepage_dashboard_filter';
|
||||
export const HOMEPAGE_COLLAPSE_STATE = 'homepage_collapse_state';
|
||||
|
||||
@@ -269,6 +269,9 @@ export function shortenSQL(sql: string, maxLines: number) {
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
// loading card count for homepage
|
||||
export const loadingCardCount = 5;
|
||||
|
||||
const breakpoints = [576, 768, 992, 1200];
|
||||
export const mq = breakpoints.map(bp => `@media (max-width: ${bp}px)`);
|
||||
|
||||
@@ -286,7 +289,7 @@ export const CardContainer = styled.div<{
|
||||
display: grid;
|
||||
grid-gap: ${theme.gridUnit * 12}px ${theme.gridUnit * 4}px;
|
||||
grid-template-columns: repeat(auto-fit, 300px);
|
||||
max-height: ${showThumbnails ? '314' : '140'}px;
|
||||
max-height: ${showThumbnails ? '314' : '148'}px;
|
||||
margin-top: ${theme.gridUnit * -6}px;
|
||||
padding: ${
|
||||
showThumbnails
|
||||
|
||||
@@ -21,9 +21,9 @@ import moment from 'moment';
|
||||
import { styled, t } from '@superset-ui/core';
|
||||
import { setInLocalStorage } from 'src/utils/localStorageHelpers';
|
||||
|
||||
import Loading from 'src/components/Loading';
|
||||
import ListViewCard from 'src/components/ListViewCard';
|
||||
import SubMenu from 'src/components/Menu/SubMenu';
|
||||
import { LoadingCards, ActivityData } from 'src/views/CRUD/welcome/Welcome';
|
||||
import {
|
||||
CardStyles,
|
||||
getEditedObjects,
|
||||
@@ -34,7 +34,7 @@ import { Chart } from 'src/types/Chart';
|
||||
import { Dashboard, SavedQueryObject } from 'src/views/CRUD/types';
|
||||
|
||||
import Icons from 'src/components/Icons';
|
||||
import { ActivityData } from './Welcome';
|
||||
|
||||
import EmptyState from './EmptyState';
|
||||
|
||||
/**
|
||||
@@ -230,7 +230,7 @@ export default function ActivityTable({
|
||||
const doneFetching = loadedCount < 3;
|
||||
|
||||
if ((loadingState && !editedObjs) || doneFetching) {
|
||||
return <Loading position="inline" />;
|
||||
return <LoadingCards />;
|
||||
}
|
||||
return (
|
||||
<Styles>
|
||||
|
||||
@@ -35,6 +35,7 @@ import PropertiesModal from 'src/explore/components/PropertiesModal';
|
||||
import { User } from 'src/types/bootstrapTypes';
|
||||
import { CardContainer, PAGE_SIZE } from 'src/views/CRUD/utils';
|
||||
import { HOMEPAGE_CHART_FILTER } from 'src/views/CRUD/storageKeys';
|
||||
import { LoadingCards } from 'src/views/CRUD/welcome/Welcome';
|
||||
import ChartCard from 'src/views/CRUD/chart/ChartCard';
|
||||
import Chart from 'src/types/Chart';
|
||||
import handleResourceExport from 'src/utils/export';
|
||||
@@ -177,7 +178,7 @@ function ChartTable({
|
||||
});
|
||||
}
|
||||
|
||||
if (loading) return <Loading position="inline" />;
|
||||
if (loading) return <LoadingCards cover={showThumbnails} />;
|
||||
return (
|
||||
<ErrorBoundary>
|
||||
{sliceCurrentlyEditing && (
|
||||
|
||||
@@ -31,6 +31,7 @@ import {
|
||||
setInLocalStorage,
|
||||
getFromLocalStorage,
|
||||
} from 'src/utils/localStorageHelpers';
|
||||
import { LoadingCards } from 'src/views/CRUD/welcome/Welcome';
|
||||
import {
|
||||
createErrorHandler,
|
||||
CardContainer,
|
||||
@@ -189,7 +190,7 @@ function DashboardTable({
|
||||
filters: getFilters(filter),
|
||||
});
|
||||
|
||||
if (loading) return <Loading position="inline" />;
|
||||
if (loading) return <LoadingCards cover={showThumbnails} />;
|
||||
return (
|
||||
<>
|
||||
<SubMenu
|
||||
|
||||
@@ -22,7 +22,7 @@ import SyntaxHighlighter from 'react-syntax-highlighter/dist/cjs/light';
|
||||
import sql from 'react-syntax-highlighter/dist/cjs/languages/hljs/sql';
|
||||
import github from 'react-syntax-highlighter/dist/cjs/styles/hljs/github';
|
||||
import withToasts from 'src/messageToasts/enhancers/withToasts';
|
||||
import Loading from 'src/components/Loading';
|
||||
import { LoadingCards } from 'src/views/CRUD/welcome/Welcome';
|
||||
import { Dropdown, Menu } from 'src/common/components';
|
||||
import { useListViewResource, copyQueryLink } from 'src/views/CRUD/hooks';
|
||||
import ListViewCard from 'src/components/ListViewCard';
|
||||
@@ -240,7 +240,7 @@ const SavedQueries = ({
|
||||
</Menu>
|
||||
);
|
||||
|
||||
if (loading) return <Loading position="inline" />;
|
||||
if (loading) return <LoadingCards cover={showThumbnails} />;
|
||||
return (
|
||||
<>
|
||||
{queryDeleteModal && (
|
||||
|
||||
@@ -25,15 +25,20 @@ import {
|
||||
getFromLocalStorage,
|
||||
setInLocalStorage,
|
||||
} from 'src/utils/localStorageHelpers';
|
||||
import ListViewCard from 'src/components/ListViewCard';
|
||||
import withToasts from 'src/messageToasts/enhancers/withToasts';
|
||||
import Loading from 'src/components/Loading';
|
||||
import {
|
||||
createErrorHandler,
|
||||
getRecentAcitivtyObjs,
|
||||
mq,
|
||||
CardContainer,
|
||||
getUserOwnedObjects,
|
||||
loadingCardCount,
|
||||
} from 'src/views/CRUD/utils';
|
||||
import { HOMEPAGE_ACTIVITY_FILTER } from 'src/views/CRUD/storageKeys';
|
||||
import {
|
||||
HOMEPAGE_ACTIVITY_FILTER,
|
||||
HOMEPAGE_COLLAPSE_STATE,
|
||||
} from 'src/views/CRUD/storageKeys';
|
||||
import { FeatureFlag, isFeatureEnabled } from 'src/featureFlags';
|
||||
import { Switch } from 'src/common/components';
|
||||
|
||||
@@ -54,6 +59,10 @@ export interface ActivityData {
|
||||
Examples?: Array<object>;
|
||||
}
|
||||
|
||||
interface LoadingProps {
|
||||
cover?: boolean;
|
||||
}
|
||||
|
||||
const DEFAULT_TAB_ARR = ['2', '3'];
|
||||
|
||||
const WelcomeContainer = styled.div`
|
||||
@@ -96,6 +105,12 @@ const WelcomeContainer = styled.div`
|
||||
div.ant-collapse-item:last-child .ant-collapse-header {
|
||||
padding-bottom: ${({ theme }) => theme.gridUnit * 9}px;
|
||||
}
|
||||
.loading-cards {
|
||||
margin-top: ${({ theme }) => theme.gridUnit * 8}px;
|
||||
.ant-card-cover > div {
|
||||
height: 168px;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const WelcomeNav = styled.div`
|
||||
@@ -118,6 +133,14 @@ const WelcomeNav = styled.div`
|
||||
}
|
||||
`;
|
||||
|
||||
export const LoadingCards = ({ cover }: LoadingProps) => (
|
||||
<CardContainer showThumbnails={cover} className="loading-cards">
|
||||
{[...new Array(loadingCardCount)].map(() => (
|
||||
<ListViewCard cover={cover ? false : <></>} description="" loading />
|
||||
))}
|
||||
</CardContainer>
|
||||
);
|
||||
|
||||
function Welcome({ user, addDangerToast }: WelcomeProps) {
|
||||
const userid = user.userId;
|
||||
const id = userid.toString();
|
||||
@@ -137,16 +160,18 @@ function Welcome({ user, addDangerToast }: WelcomeProps) {
|
||||
null,
|
||||
);
|
||||
const [loadedCount, setLoadedCount] = useState(0);
|
||||
const [activeState, setActiveState] = useState<Array<string>>(
|
||||
DEFAULT_TAB_ARR,
|
||||
);
|
||||
|
||||
const collapseState = getFromLocalStorage(HOMEPAGE_COLLAPSE_STATE, null);
|
||||
const [activeState, setActiveState] = useState<Array<string>>(collapseState);
|
||||
|
||||
const handleCollapse = (state: Array<string>) => {
|
||||
setActiveState(state);
|
||||
setInLocalStorage(HOMEPAGE_COLLAPSE_STATE, state);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const activeTab = getFromLocalStorage(HOMEPAGE_ACTIVITY_FILTER, null);
|
||||
setActiveState(collapseState || DEFAULT_TAB_ARR);
|
||||
getRecentAcitivtyObjs(user.userId, recent, addDangerToast)
|
||||
.then(res => {
|
||||
const data: ActivityData | null = {};
|
||||
@@ -216,7 +241,7 @@ function Welcome({ user, addDangerToast }: WelcomeProps) {
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (queryData?.length) {
|
||||
if (!collapseState && queryData?.length) {
|
||||
setActiveState(activeState => [...activeState, '4']);
|
||||
}
|
||||
setActivityData(activityData => ({
|
||||
@@ -230,7 +255,7 @@ function Welcome({ user, addDangerToast }: WelcomeProps) {
|
||||
}, [chartData, queryData, dashboardData]);
|
||||
|
||||
useEffect(() => {
|
||||
if (activityData?.Viewed?.length) {
|
||||
if (!collapseState && activityData?.Viewed?.length) {
|
||||
setActiveState(activeState => ['1', ...activeState]);
|
||||
}
|
||||
}, [activityData]);
|
||||
@@ -263,12 +288,12 @@ function Welcome({ user, addDangerToast }: WelcomeProps) {
|
||||
loadedCount={loadedCount}
|
||||
/>
|
||||
) : (
|
||||
<Loading position="inline" />
|
||||
<LoadingCards />
|
||||
)}
|
||||
</Collapse.Panel>
|
||||
<Collapse.Panel header={t('Dashboards')} key="2">
|
||||
{!dashboardData || isRecentActivityLoading ? (
|
||||
<Loading position="inline" />
|
||||
<LoadingCards cover={checked} />
|
||||
) : (
|
||||
<DashboardTable
|
||||
user={user}
|
||||
@@ -280,7 +305,7 @@ function Welcome({ user, addDangerToast }: WelcomeProps) {
|
||||
</Collapse.Panel>
|
||||
<Collapse.Panel header={t('Charts')} key="3">
|
||||
{!chartData || isRecentActivityLoading ? (
|
||||
<Loading position="inline" />
|
||||
<LoadingCards cover={checked} />
|
||||
) : (
|
||||
<ChartTable
|
||||
showThumbnails={checked}
|
||||
@@ -292,7 +317,7 @@ function Welcome({ user, addDangerToast }: WelcomeProps) {
|
||||
</Collapse.Panel>
|
||||
<Collapse.Panel header={t('Saved queries')} key="4">
|
||||
{!queryData ? (
|
||||
<Loading position="inline" />
|
||||
<LoadingCards cover={checked} />
|
||||
) : (
|
||||
<SavedQueries
|
||||
showThumbnails={checked}
|
||||
|
||||
Reference in New Issue
Block a user