Skip to content

Commit 9590813

Browse files
authored
MSD: Render more fields using ES data (#107537)
* MSD: Render Preview field using ES data * MSD: Render WP Version field using ES data * MSD: Render PHP Version field using ES data * MSD: Render Host field using ES data * Don't wrap website preview in link * Add dummy fields (commented out) * MSD: Render Views field using ES data * MSD: Render Backup field using ES data * MSD: Render 7-day likes field using ES data * MSD: Render Uptime field using ES data * MSD: Render Storage field using ES data * MSD: Render Last published field using ES data * Drop patch version of php * Revert some changes to keep using site returned by siteBySlugQuery to render async fields * Fix visitors * Remove span from PHPVersion__ES * Rename to formatWordPressVersion
1 parent 2251246 commit 9590813

File tree

6 files changed

+196
-47
lines changed

6 files changed

+196
-47
lines changed

client/dashboard/sites/dataviews/fields.tsx

Lines changed: 81 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import { queryClient } from '@automattic/api-queries';
1+
import { queryClient, siteBySlugQuery } from '@automattic/api-queries';
22
import { isEnabled } from '@automattic/calypso-config';
3+
import { useQuery } from '@tanstack/react-query';
34
import { __ } from '@wordpress/i18n';
45
import { useMemo } from 'react';
56
import { useAuth } from '../../app/auth';
@@ -15,7 +16,7 @@ import {
1516
isSelfHostedJetpackConnected__ES,
1617
} from '../../utils/site-types';
1718
import { getSiteDisplayUrl } from '../../utils/site-url';
18-
import { getFormattedWordPressVersion } from '../../utils/wp-version';
19+
import { getFormattedWordPressVersion, formatWordPressVersion } from '../../utils/wp-version';
1920
import {
2021
AsyncEngagementStat,
2122
EngagementStat,
@@ -24,8 +25,10 @@ import {
2425
Name,
2526
NameRenderer,
2627
PHPVersion,
28+
PHPVersion__ES,
2729
Plan,
2830
Preview,
31+
Preview__ES,
2932
Status,
3033
URL,
3134
Uptime,
@@ -203,6 +206,7 @@ function getDefaultFields( queries: AppConfig[ 'queries' ] ): Field< Site >[] {
203206
];
204207
}
205208

209+
// Use the site returned by siteBySlugQuery to render async fields (e.g. Backup) so the structure remains consistent.
206210
function getDefaultFields__ES( queries: AppConfig[ 'queries' ] ): Field< DashboardSiteListSite >[] {
207211
return [
208212
{
@@ -251,6 +255,15 @@ function getDefaultFields__ES( queries: AppConfig[ 'queries' ] ): Field< Dashboa
251255
getValue: ( { item } ) => item.total_wpcom_subscribers,
252256
label: __( 'Subscribers' ),
253257
},
258+
{
259+
id: 'backup',
260+
label: __( 'Backup' ),
261+
render: function BackupField( { item } ) {
262+
const { data: site } = useQuery( siteBySlugQuery( item.slug ) );
263+
return <LastBackup site={ site } />;
264+
},
265+
enableSorting: false,
266+
},
254267
{
255268
id: 'plan',
256269
label: __( 'Plan' ),
@@ -291,6 +304,11 @@ function getDefaultFields__ES( queries: AppConfig[ 'queries' ] ): Field< Dashboa
291304
return direction === 'asc' ? planA.localeCompare( planB ) : planB.localeCompare( planA );
292305
},
293306
},
307+
{
308+
id: 'wp_version',
309+
label: __( 'WP version' ),
310+
getValue: ( { item } ) => formatWordPressVersion( item.wordpress_version ?? '' ),
311+
},
294312
{
295313
id: 'is_a8c',
296314
type: 'boolean',
@@ -304,12 +322,73 @@ function getDefaultFields__ES( queries: AppConfig[ 'queries' ] ): Field< Dashboa
304322
},
305323
render: ( { item } ) => ( item.is_a8c ? __( 'Yes' ) : __( 'No' ) ),
306324
},
325+
{
326+
id: 'preview',
327+
label: __( 'Preview' ),
328+
render: ( { item } ) => <Preview__ES site={ item } />,
329+
enableHiding: false,
330+
enableSorting: false,
331+
},
332+
{
333+
id: 'last_published',
334+
label: __( 'Last published' ),
335+
getValue: ( { item } ) => item.last_publish ?? '',
336+
render: ( { item } ) =>
337+
item.last_publish ? <TimeSince timestamp={ item.last_publish } /> : '',
338+
},
339+
{
340+
id: 'uptime',
341+
label: __( '7-day uptime' ),
342+
render: function UptimeField( { item } ) {
343+
const { data: site } = useQuery( siteBySlugQuery( item.slug ) );
344+
return <Uptime site={ site } />;
345+
},
346+
enableSorting: false,
347+
},
307348
{
308349
id: 'visitors',
309350
label: __( '7-day visitors' ),
310351
render: ( { item, field } ) => <EngagementStat value={ field.getValue( { item } ) } />,
311352
enableSorting: false,
312353
},
354+
{
355+
id: 'views',
356+
label: __( '7-day views' ),
357+
render: ( { item, field } ) => <EngagementStat value={ field.getValue( { item } ) } />,
358+
enableSorting: false,
359+
},
360+
{
361+
id: 'likes',
362+
label: __( '7-day likes' ),
363+
render: function LikesField( { item } ) {
364+
const { data: site } = useQuery( siteBySlugQuery( item.slug ) );
365+
return <AsyncEngagementStat site={ site } type="likes" />;
366+
},
367+
enableSorting: false,
368+
},
369+
{
370+
id: 'php_version',
371+
label: __( 'PHP version' ),
372+
render: ( { item }: { item: DashboardSiteListSite } ) => <PHPVersion__ES site={ item } />,
373+
enableSorting: false,
374+
},
375+
{
376+
id: 'storage',
377+
label: __( 'Storage' ),
378+
render: function StorageField( { item } ) {
379+
const { data: site } = useQuery( siteBySlugQuery( item.slug ) );
380+
return <MediaStorage site={ site } />;
381+
},
382+
enableSorting: false,
383+
},
384+
{
385+
id: 'host',
386+
label: __( 'Host' ),
387+
getValue: ( { item } ) => {
388+
return getSiteProviderName( item ) ?? DEFAULT_PROVIDER_NAME;
389+
},
390+
render: ( { field, item } ) => field.getValue( { item } ),
391+
},
313392
];
314393
}
315394

client/dashboard/sites/index.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,23 +76,26 @@ function getFetchSiteListParams(
7676
backup: 'has_backup',
7777
// views: 'stats_views',
7878
plan: 'plan',
79-
// wp_version
79+
wp_version: 'wordpress_version',
8080
is_a8c: 'is_a8c',
8181
// preview
82-
// last_published
82+
last_published: 'last_publish',
8383
// uptime
84+
views: 'views',
8485
visitors: 'visitors',
8586
subscribers_count: 'total_wpcom_subscribers',
8687
// links
87-
// php_version
88+
php_version: 'php_version',
8889
// storage
89-
// host
90+
host: 'hosting_provider_guess',
9091
};
9192

9293
const additionalMappedFields: Record< string, ( keyof DashboardSiteListSite )[] > = {
94+
likes: [ 'enabled_modules' ],
9395
name: [ 'badge' ],
9496
status: [ 'wpcom_status', 'private', 'deleted' ],
9597
plan: [ 'owner_id' ],
98+
preview: [ 'name', 'icon', 'url', 'private', 'deleted' ],
9699
};
97100

98101
// Always include ID and slug (for navigation), deleted (for styling), is_a8c (for included a8c owned) and other (for vip & self hosted jetpack)

client/dashboard/sites/site-fields/index.tsx

Lines changed: 94 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import { __, sprintf } from '@wordpress/i18n';
2020
import { useInView } from 'react-intersection-observer';
2121
import { useAnalytics } from '../../app/analytics';
2222
import ComponentViewTracker from '../../components/component-view-tracker';
23-
import SiteIcon from '../../components/site-icon';
23+
import SiteIcon, { SiteIconRenderer } from '../../components/site-icon';
2424
import { Text } from '../../components/text';
2525
import { TextBlur } from '../../components/text-blur';
2626
import TimeSince from '../../components/time-since';
@@ -236,31 +236,73 @@ export function Preview( { site }: { site: Site } ) {
236236
);
237237
}
238238

239+
export function Preview__ES( { site }: { site: DashboardSiteListSite } ) {
240+
const [ resizeListener, { width } ] = useResizeObserver();
241+
242+
// If the site is a private A8C site, X-Frame-Options is set to same
243+
// origin.
244+
const iframeDisabled = site.deleted || ( site.is_a8c && site.private );
245+
return (
246+
<div
247+
style={ {
248+
display: 'block',
249+
height: '100%',
250+
width: '100%',
251+
borderRadius: 'inherit',
252+
overflow: 'hidden',
253+
} }
254+
>
255+
{ resizeListener }
256+
{ iframeDisabled && (
257+
<div
258+
style={ {
259+
fontSize: '24px',
260+
display: 'flex',
261+
alignItems: 'center',
262+
justifyContent: 'center',
263+
height: '100%',
264+
} }
265+
>
266+
<SiteIconRenderer
267+
alt={ site.name ?? '' }
268+
fallbackInitial={ site.name?.charAt( 0 ) ?? '' }
269+
icon={ site.icon ?? undefined }
270+
isMigration={ false }
271+
/>
272+
</div>
273+
) }
274+
{ width && ! iframeDisabled && (
275+
<SitePreview url={ site.url?.with_scheme ?? '' } scale={ width / 1200 } height={ 1200 } />
276+
) }
277+
</div>
278+
);
279+
}
280+
239281
export function AsyncEngagementStat( {
240282
site,
241283
type,
242284
}: {
243-
site: Site;
285+
site?: Site;
244286
type: 'visitors' | 'views' | 'likes';
245287
} ) {
246288
const { ref, inView } = useInView( { triggerOnce: true, fallbackInView: true } );
247289
const isEligible =
248-
! site.is_deleted && ( ! site.jetpack || hasJetpackModule( site, JetpackModules.STATS ) );
290+
! site?.is_deleted && ( ! site?.jetpack || hasJetpackModule( site, JetpackModules.STATS ) );
249291

250292
const { data: stats, isLoading } = useQuery( {
251-
...siteEngagementStatsQuery( site.ID ),
252-
enabled: isEligible && inView,
293+
...siteEngagementStatsQuery( site?.ID ?? 0 ),
294+
enabled: !! site?.ID && isEligible && inView,
253295
} );
254296

255-
if ( ! isEligible ) {
256-
return <IneligibleIndicator />;
257-
}
258-
259297
const renderContent = () => {
260-
if ( isLoading ) {
298+
if ( ! site || isLoading ) {
261299
return <LoadingIndicator label="100" />;
262300
}
263301

302+
if ( ! isEligible ) {
303+
return <IneligibleIndicator />;
304+
}
305+
264306
return stats?.currentData[ type ];
265307
};
266308

@@ -271,28 +313,28 @@ export function EngagementStat( { value }: { value: number | null } ) {
271313
return typeof value !== 'number' ? <IneligibleIndicator /> : value;
272314
}
273315

274-
export function LastBackup( { site }: { site: Site } ) {
316+
export function LastBackup( { site }: { site?: Site } ) {
275317
const { ref, inView } = useInView( { triggerOnce: true, fallbackInView: true } );
276-
const isEligible = hasHostingFeature( site, HostingFeatures.BACKUPS );
318+
const isEligible = site && hasHostingFeature( site, HostingFeatures.BACKUPS );
277319

278320
const {
279321
data: lastBackup,
280322
isLoading,
281323
isError,
282324
} = useQuery( {
283-
...siteLastBackupQuery( site.ID ),
284-
enabled: isEligible && inView,
325+
...siteLastBackupQuery( site?.ID ?? 0 ),
326+
enabled: !! site?.ID && isEligible && inView,
285327
} );
286328

287-
if ( ! isEligible ) {
288-
return <IneligibleIndicator />;
289-
}
290-
291329
const renderContent = () => {
292-
if ( isLoading ) {
330+
if ( ! site || isLoading ) {
293331
return <LoadingIndicator label="Unknown" />;
294332
}
295333

334+
if ( ! isEligible ) {
335+
return <IneligibleIndicator />;
336+
}
337+
296338
if ( ! lastBackup || isError ) {
297339
return <IneligibleIndicator />;
298340
}
@@ -303,24 +345,24 @@ export function LastBackup( { site }: { site: Site } ) {
303345
return <span ref={ ref }>{ renderContent() }</span>;
304346
}
305347

306-
export function Uptime( { site }: { site: Site } ) {
348+
export function Uptime( { site }: { site?: Site } ) {
307349
const { ref, inView } = useInView( { triggerOnce: true, fallbackInView: true } );
308-
const isEligible = hasJetpackModule( site, JetpackModules.MONITOR );
350+
const isEligible = site && hasJetpackModule( site, JetpackModules.MONITOR );
309351

310352
const { data: uptime, isLoading } = useQuery( {
311-
...siteUptimeQuery( site.ID, 'week' ),
312-
enabled: isEligible && inView,
353+
...siteUptimeQuery( site?.ID ?? 0, 'week' ),
354+
enabled: !! site?.ID && isEligible && inView,
313355
} );
314356

315-
if ( ! isEligible ) {
316-
return <IneligibleIndicator />;
317-
}
318-
319357
const renderContent = () => {
320-
if ( isLoading ) {
358+
if ( ! site || isLoading ) {
321359
return <LoadingIndicator label="100%" />;
322360
}
323361

362+
if ( ! isEligible ) {
363+
return <IneligibleIndicator />;
364+
}
365+
324366
return uptime ? `${ uptime }%` : <IneligibleIndicator />;
325367
};
326368

@@ -346,26 +388,39 @@ export function PHPVersion( { site }: { site: Site } ) {
346388
return <span ref={ ref }>{ ! isLoading ? data : <LoadingIndicator label="X.Y" /> }</span>;
347389
}
348390

349-
export function MediaStorage( { site }: { site: Site } ) {
391+
export function PHPVersion__ES( { site }: { site: DashboardSiteListSite } ) {
392+
return site.php_version ? (
393+
site.php_version.split( '.' ).slice( 0, 2 ).join( '.' ) // Drop patch version.
394+
) : (
395+
<IneligibleIndicator />
396+
);
397+
}
398+
399+
export function MediaStorage( { site }: { site?: Site } ) {
350400
const { ref, inView } = useInView( {
351401
triggerOnce: true,
352402
fallbackInView: true,
353403
} );
354404

355405
const { data: mediaStorage, isLoading } = useQuery( {
356-
...siteMediaStorageQuery( site.ID ),
357-
enabled: inView,
406+
...siteMediaStorageQuery( site?.ID ?? 0 ),
407+
enabled: !! site?.ID && inView,
358408
} );
359409

360-
const value = mediaStorage ? (
361-
`${
362-
Math.round( ( mediaStorage.storage_used_bytes / mediaStorage.max_storage_bytes ) * 1000 ) / 10
363-
}%`
364-
) : (
365-
<IneligibleIndicator />
366-
);
410+
const renderContent = () => {
411+
if ( ! site || isLoading ) {
412+
return <LoadingIndicator label="100%" />;
413+
}
367414

368-
return <span ref={ ref }>{ ! isLoading ? value : <LoadingIndicator label="100%" /> }</span>;
415+
if ( ! mediaStorage ) {
416+
return <IneligibleIndicator />;
417+
}
418+
419+
const { storage_used_bytes, max_storage_bytes } = mediaStorage;
420+
return `${ Math.round( ( storage_used_bytes / max_storage_bytes ) * 1000 ) / 10 }%`;
421+
};
422+
423+
return <span ref={ ref }>{ renderContent() }</span>;
369424
}
370425

371426
function SiteLaunchNag( { site }: { site: Site } ) {

client/dashboard/utils/site-provider.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { Site } from '@automattic/api-core';
22

33
export const DEFAULT_PROVIDER_NAME = 'WordPress.com';
44

5-
export function getSiteProviderName( site: Site ) {
5+
export function getSiteProviderName( site: Pick< Site, 'hosting_provider_guess' > ) {
66
const provider = site.hosting_provider_guess;
77
let providerName;
88
if ( provider === 'jurassic_ninja' ) {

0 commit comments

Comments
 (0)