Skip to content

Commit

Permalink
Merge pull request #9030 from google/enhancement/8145-audience-tile-l…
Browse files Browse the repository at this point in the history
…oading

Implement the loading state for the Audience Tile.
  • Loading branch information
techanvil authored Jul 23, 2024
2 parents 9306906 + 2b21f2d commit ef49540
Show file tree
Hide file tree
Showing 19 changed files with 896 additions and 91 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ describe( 'ErrorNotice', () => {
const syncAvailableAudiencesEndpoint = new RegExp(
'^/google-site-kit/v1/modules/analytics-4/data/sync-audiences'
);
const audienceSettingsEndpoint = new RegExp(
'^/google-site-kit/v1/modules/analytics-4/data/audience-settings'
);

const reportOptions = {
endDate: '2024-03-27',
Expand Down Expand Up @@ -265,6 +268,14 @@ describe( 'ErrorNotice', () => {
status: 200,
} );

fetchMock.getOnce( audienceSettingsEndpoint, {
body: {
data: {
configuredAudiences: [],
},
},
} );

expect(
registry
.select( MODULES_ANALYTICS_4 )
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* AudienceTileLoading component.
*
* Site Kit by Google, Copyright 2024 Google LLC
*
* Licensed 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
*
* https://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.
*/

/**
* Internal dependencies
*/
import PreviewBlock from '../../../../../../../components/PreviewBlock';

export default function AudienceTileLoading() {
return (
<div className="googlesitekit-audience-segmentation-tile-loading">
{ /* The first preview block is only visible on desktop to preview the header which is hidden on other screens. */ }
<PreviewBlock width="100%" height="20px" />
<PreviewBlock width="100%" height="52px" />
<PreviewBlock width="100%" height="52px" />
<PreviewBlock width="100%" height="52px" />
<PreviewBlock width="100%" height="52px" />
<PreviewBlock width="100%" height="52px" />
<PreviewBlock width="100%" height="52px" />
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,14 @@ import AudienceMetricIconTopContent from '../../../../../../../../svg/icons/audi
import AudienceTileMetric from './AudienceTileMetric';
import AudienceTileCitiesMetric from './AudienceTileCitiesMetric';
import AudienceTilePagesMetric from './AudienceTilePagesMetric';
import PreviewBlock from '../../../../../../../components/PreviewBlock';
import ChangeBadge from '../../../../../../../components/ChangeBadge';
import InfoTooltip from '../../../../../../../components/InfoTooltip';
import PartialDataBadge from './PartialDataBadge';
import PartialDataNotice from './PartialDataNotice';
import { numFmt } from '../../../../../../../util';
import AudienceTileCollectingData from './AudienceTileCollectingData';
import AudienceTileCollectingDataHideable from './AudienceTileCollectingDataHideable';
import AudienceTileLoading from './AudienceTileLoading';

// TODO: as part of #8484 the report props should be updated to expect
// the full report rows for the current tile to reduce data manipulation
Expand All @@ -72,6 +72,7 @@ export default function AudienceTile( {
topContentTitles,
Widget,
audienceResourceName,
isLoading,
isZeroData,
isPartialData,
isTileHideable,
Expand Down Expand Up @@ -107,9 +108,17 @@ export default function AudienceTile( {
breakpoint
);

// TODO: Loading states will be implemented as part of https://github.com/google/site-kit-wp/issues/8145.
if ( ! loaded || isZeroData === undefined || isPartialData === undefined ) {
return <PreviewBlock width="100%" height="600px" />;
if (
! loaded ||
isLoading ||
isZeroData === undefined ||
isPartialData === undefined
) {
return (
<Widget noPadding>
<AudienceTileLoading />
</Widget>
);
}

if ( isPartialData && isZeroData ) {
Expand Down Expand Up @@ -283,6 +292,7 @@ AudienceTile.propTypes = {
topContentTitles: PropTypes.object,
Widget: PropTypes.elementType.isRequired,
audienceResourceName: PropTypes.string.isRequired,
isLoading: PropTypes.bool,
isZeroData: PropTypes.bool,
isPartialData: PropTypes.bool,
isTileHideable: PropTypes.bool,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,26 @@ ReadyLongCityNames.scenario = {
label: 'Modules/Analytics4/Components/AudienceSegmentation/Dashboard/AudienceTile/ReadyLongCityNames',
};

export const Loading = Template.bind( {} );
Loading.storyName = 'Loading';
Loading.args = {
...readyProps,
isLoading: true,
};
Loading.decorators = [
( Story ) => {
// Ensure the animation is paused for VRT tests to correctly capture the loading state.
return (
<div className="googlesitekit-vrt-animation-paused">
<Story />
</div>
);
},
];
Loading.scenario = {
label: 'Modules/Analytics4/Components/AudienceSegmentation/Dashboard/AudienceTile/Loading',
};

export const NoData = Template.bind( {} );
NoData.storyName = 'NoData';
NoData.args = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ const hasZeroDataForAudience = ( report, audienceResourceName ) => {
return totalUsers === 0;
};

export default function AudienceTiles( { Widget } ) {
export default function AudienceTiles( { Widget, widgetLoading } ) {
const [ activeTile, setActiveTile ] = useState( 0 );
const breakpoint = useBreakpoint();
const isTabbedBreakpoint =
Expand Down Expand Up @@ -248,7 +248,7 @@ export default function AudienceTiles( { Widget } ) {
const visible = [];
const tempAudiences = configuredAudiences.slice();

while ( reportLoaded && tempAudiences.length > 0 ) {
while ( tempAudiences.length > 0 ) {
const audienceResourceName = tempAudiences.shift();

const isDismissed = dismissedItems?.includes(
Expand Down Expand Up @@ -278,7 +278,7 @@ export default function AudienceTiles( { Widget } ) {
}

return [ toClear, visible ];
}, [ configuredAudiences, dismissedItems, reportLoaded, report ] );
}, [ configuredAudiences, dismissedItems, report ] );

// Re-dismiss with a short expiry time to clear any previously dismissed tiles.
// This ensures that the tile will reappear when it is populated with data again.
Expand All @@ -300,6 +300,7 @@ export default function AudienceTiles( { Widget } ) {
}, [ audiencesToClearDismissal, dismissItem, isDismissingItem ] );

const loading =
widgetLoading ||
! reportLoaded ||
! totalPageviewsReportLoaded ||
! topCitiesReportLoaded ||
Expand Down Expand Up @@ -515,4 +516,5 @@ export default function AudienceTiles( { Widget } ) {

AudienceTiles.propTypes = {
Widget: PropTypes.elementType.isRequired,
widgetLoading: PropTypes.bool.isRequired,
};
Loading

0 comments on commit ef49540

Please sign in to comment.