Skip to content

Commit

Permalink
Show widget skeleton only once (#811)
Browse files Browse the repository at this point in the history
  • Loading branch information
padawannn authored Dec 4, 2023
1 parent 868d99c commit fedeec7
Show file tree
Hide file tree
Showing 11 changed files with 83 additions and 39 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Not released

- Show widget skeleton only once [#811](https://github.com/CartoDB/carto-react/pull/811)
- Added filterable prop to TimeSeriesWidget [#808](https://github.com/CartoDB/carto-react/pull/808)
- Fix dataSources store type [#807](https://github.com/CartoDB/carto-react/pull/807)

Expand Down
4 changes: 3 additions & 1 deletion packages/react-ui/src/widgets/BarWidgetUI/BarWidgetUI.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { processFormatterRes } from '../utils/formatterUtils';
import Typography from '../../components/atoms/Typography';
import BarSkeleton from './BarSkeleton';
import useImperativeIntl from '../../hooks/useImperativeIntl';
import useSkeleton from '../useSkeleton';

const IS_TOUCH_SCREEN = detectTouchScreen();

Expand Down Expand Up @@ -55,6 +56,7 @@ function BarWidgetUI(props) {

const intl = useIntl();
const intlConfig = useImperativeIntl(intl);
const { showSkeleton } = useSkeleton(isLoading);

// Tooltip
const tooltipOptions = useMemo(
Expand Down Expand Up @@ -294,7 +296,7 @@ function BarWidgetUI(props) {
[filterable, clickEvent]
);

if (isLoading) return <BarSkeleton height={height} />;
if (showSkeleton) return <BarSkeleton height={height} />;

return (
<div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
import SearchIcon from '../../assets/icons/SearchIcon';
import useImperativeIntl from '../../hooks/useImperativeIntl';
import { ORDER_TYPES } from '../utils/chartConstants';
import useSkeleton from '../useSkeleton';

function usePrevious(value) {
const ref = useRef();
Expand Down Expand Up @@ -60,6 +61,7 @@ function CategoryWidgetUI(props) {
const requestRef = useRef();
const prevAnimValues = usePrevious(animValues);
const referencedPrevAnimValues = useRef();
const { showSkeleton } = useSkeleton(isLoading);

const intl = useIntl();
const intlConfig = useImperativeIntl(intl);
Expand Down Expand Up @@ -354,7 +356,7 @@ function CategoryWidgetUI(props) {
);
};

if (data?.length === 0 || isLoading) return <CategorySkeleton />;
if (data?.length === 0 || showSkeleton) return <CategorySkeleton />;

return (
<CategoriesRoot>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { styled } from '@mui/material';
import { animateValue } from '../utils/animations';
import Typography from '../../components/atoms/Typography';
import FormulaSkeleton from './FormulaSkeleton';
import useSkeleton from '../useSkeleton';

const Prefix = styled('span')(() => ({
marginRight: '2px'
Expand All @@ -27,6 +28,7 @@ function FormulaWidgetUI(props) {
const requestRef = useRef();
const prevValue = usePrevious(value);
const referencedPrevValue = useRef(prevValue);
const { showSkeleton } = useSkeleton(isLoading);

useEffect(() => {
if (typeof data === 'number' && animation) {
Expand Down Expand Up @@ -65,7 +67,7 @@ function FormulaWidgetUI(props) {
const isComplexFormat = typeof formattedValue === 'object' && formattedValue !== null;
const isDisabled = formattedValue === '-';

if (isLoading) return <FormulaSkeleton />;
if (showSkeleton) return <FormulaSkeleton />;

return isComplexFormat ? (
<Typography variant='h5' component='div' weight='medium'>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import useHistogramInteractivity from './useHistogramInteractivity';
import Typography from '../../components/atoms/Typography';
import HistogramSkeleton from './HistogramSkeleton';
import useImperativeIntl from '../../hooks/useImperativeIntl';
import useSkeleton from '../useSkeleton';

const IS_TOUCH_SCREEN = detectTouchscreen();

Expand Down Expand Up @@ -48,6 +49,7 @@ function HistogramWidgetUI({

const intl = useIntl();
const intlConfig = useImperativeIntl(intl);
const { showSkeleton } = useSkeleton(isLoading);

const filterable = _filterable && !!onSelectedBarsChange;

Expand Down Expand Up @@ -268,7 +270,7 @@ function HistogramWidgetUI({
0
);

if (isLoading) return <HistogramSkeleton height={height} />;
if (showSkeleton) return <HistogramSkeleton height={height} />;

return (
<div>
Expand Down
4 changes: 3 additions & 1 deletion packages/react-ui/src/widgets/PieWidgetUI/PieWidgetUI.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import usePieCategories from './hooks/usePieCategories';
import ChartLegend from '../ChartLegend';
import Typography from '../../components/atoms/Typography';
import useImperativeIntl from '../../hooks/useImperativeIntl';
import useSkeleton from '../useSkeleton';

const CHART_SIZE = '232px';

Expand Down Expand Up @@ -63,6 +64,7 @@ function PieWidgetUI({
const theme = useTheme();
const processedData = usePieCategories(data, order, maxItems, colors);

const { showSkeleton } = useSkeleton(isLoading);
const intl = useIntl();
const intlConfig = useImperativeIntl(intl);

Expand Down Expand Up @@ -198,7 +200,7 @@ function PieWidgetUI({
onSelectedCategoriesChange([]);
};

if (isLoading) return <PieSkeleton height={height} />;
if (showSkeleton) return <PieSkeleton height={height} />;

return (
<>
Expand Down
4 changes: 3 additions & 1 deletion packages/react-ui/src/widgets/RangeWidgetUI/RangeWidgetUI.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { debounce } from '@carto/react-core';
import Typography from '../../components/atoms/Typography';
import RangeSkeleton from './RangeSkeleton';
import useImperativeIntl from '../../hooks/useImperativeIntl';
import useSkeleton from '../useSkeleton';

const Root = styled(Box)(() => ({
position: 'relative'
Expand Down Expand Up @@ -92,6 +93,7 @@ function RangeWidgetUI({ data, min, max, limits, onSelectedRangeChange, isLoadin

const intl = useIntl();
const intlConfig = useImperativeIntl(intl);
const { showSkeleton } = useSkeleton(isLoading);

const limitsMarks = useMemo(() => {
if (!limits || limits.length !== 2) {
Expand Down Expand Up @@ -162,7 +164,7 @@ function RangeWidgetUI({ data, min, max, limits, onSelectedRangeChange, isLoadin
changeSliderValues([min, max]);
};

if (isLoading) {
if (showSkeleton) {
return <RangeSkeleton />;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import React, { useRef, useState, useEffect } from 'react';
import { areChartPropsEqual } from '../utils/chartUtils';
import ReactEcharts from '../../custom-components/echarts-for-react';
import ScatterPlotSkeleton from './ScatterPlotSkeleton';
import useSkeleton from '../useSkeleton';

function __generateDefaultConfig(
{ tooltipFormatter, xAxisFormatter = (v) => v, yAxisFormatter = (v) => v },
Expand Down Expand Up @@ -86,6 +87,8 @@ function ScatterPlotWidgetUI({
series: []
});

const { showSkeleton } = useSkeleton(isLoading);

useEffect(() => {
const config = __generateDefaultConfig(
{ xAxisFormatter, yAxisFormatter, tooltipFormatter },
Expand All @@ -104,7 +107,7 @@ function ScatterPlotWidgetUI({

const HEIGHT = 225;

if (isLoading) return <ScatterPlotSkeleton height={HEIGHT} />;
if (showSkeleton) return <ScatterPlotSkeleton height={HEIGHT} />;

return (
<EchartsWrapper
Expand Down
4 changes: 3 additions & 1 deletion packages/react-ui/src/widgets/TableWidgetUI/TableWidgetUI.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
import TableSkeleton from './Skeleton/TableSkeleton';
import TablePaginationActions from '../../components/molecules/Table/TablePaginationActions';
import useImperativeIntl from '../../hooks/useImperativeIntl';
import useSkeleton from '../useSkeleton';

const TableHeadCellLabel = styled(TableSortLabel)(({ theme }) => ({
...theme.typography.caption,
Expand Down Expand Up @@ -73,6 +74,7 @@ function TableWidgetUI({

const intl = useIntl();
const intlConfig = useImperativeIntl(intl);
const { showSkeleton } = useSkeleton(isLoading);

const defaultLabelDisplayedRows = ({ from, to, count }) => {
return intlConfig.formatMessage({ id: 'c4r.widgets.table.of' }, { from, to, count });
Expand Down Expand Up @@ -103,7 +105,7 @@ function TableWidgetUI({
fixedHeightStyle.height = `calc(${height} - ${paginationHeight}px)`;
}

if (isLoading)
if (showSkeleton)
return (
<TableSkeleton
rowsPerPage={rowsPerPage}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { TimeSeriesControls } from './components/TimeSeriesControls';
import TimeSeriesLayout from './components/TimeSeriesLayout';
import ChartLegend from '../ChartLegend';
import { findItemIndexByTime, getDate } from './utils/utilities';
import useSkeleton from '../useSkeleton';
function TimeSeriesWidgetUI({
data,
categories,
Expand Down Expand Up @@ -49,6 +50,8 @@ function TimeSeriesWidgetUI({
}) {
let prevEmittedTimeWindow = useRef();
const intl = useIntl();
const { showSkeleton } = useSkeleton(isLoading);

const handleTimeWindowUpdate = useCallback(
(timeWindow) => {
if (timeWindow.length === 2) {
Expand Down Expand Up @@ -77,36 +80,16 @@ function TimeSeriesWidgetUI({
[onTimeWindowUpdate, onTimelineUpdate, data]
);

const content = isLoading ? (
<TimeSeriesSkeleton
fitHeight={fitHeight}
height={height}
showControls={showControls}
showLegend={showLegend}
/>
) : (
<TimeSeriesWidgetUIContent
data={data}
categories={categories}
stepSize={stepSize}
stepMultiplier={stepMultiplier}
chartType={chartType}
timeAxisSplitNumber={timeAxisSplitNumber}
tooltip={tooltip}
tooltipFormatter={tooltipFormatter}
formatter={formatter}
height={height}
fitHeight={fitHeight}
showControls={showControls}
animation={animation}
filterable={filterable}
palette={palette}
showLegend={showLegend}
selectedCategories={selectedCategories}
timelinePosition={timelinePosition}
onSelectedCategoriesChange={onSelectedCategoriesChange}
/>
);
if (showSkeleton) {
return (
<TimeSeriesSkeleton
fitHeight={fitHeight}
height={height}
showControls={showControls}
showLegend={showLegend}
/>
);
}

return (
<TimeSeriesProvider
Expand All @@ -119,7 +102,27 @@ function TimeSeriesWidgetUI({
onTimeWindowUpdate={handleTimeWindowUpdate}
intl={intl}
>
{content}
<TimeSeriesWidgetUIContent
data={data}
categories={categories}
stepSize={stepSize}
stepMultiplier={stepMultiplier}
chartType={chartType}
timeAxisSplitNumber={timeAxisSplitNumber}
tooltip={tooltip}
tooltipFormatter={tooltipFormatter}
formatter={formatter}
height={height}
fitHeight={fitHeight}
showControls={showControls}
animation={animation}
filterable={filterable}
palette={palette}
showLegend={showLegend}
selectedCategories={selectedCategories}
timelinePosition={timelinePosition}
onSelectedCategoriesChange={onSelectedCategoriesChange}
/>
</TimeSeriesProvider>
);
}
Expand Down Expand Up @@ -218,6 +221,8 @@ function TimeSeriesWidgetUIContent({
}, [timelinePosition, data]);

useEffect(() => {
if (!data.length) return;

const start = data[0].name;
const end = data[data.length - 1].name;
if (
Expand Down
21 changes: 21 additions & 0 deletions packages/react-ui/src/widgets/useSkeleton.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { useEffect, useState } from 'react';

function useSkeleton(isDataLoading) {
const [showSkeleton, setShowSkeleton] = useState(false);
const [skeletonEverBeenShown, setSkeletonEverBeenShown] = useState(false);

useEffect(() => {
if (isDataLoading && !skeletonEverBeenShown) {
setShowSkeleton(true);
setSkeletonEverBeenShown(true);
}

if (!isDataLoading) {
setShowSkeleton(false);
}
}, [isDataLoading, skeletonEverBeenShown]);

return { showSkeleton };
}

export default useSkeleton;

0 comments on commit fedeec7

Please sign in to comment.