Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 40 additions & 1 deletion client/dashboard/components/site-icon/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useMemo } from 'react';
import { getSiteDisplayName } from '../../utils/site-name';
import { getSiteStatus } from '../../utils/site-status';
import SiteMigrationIcon from './site-migration-icon';
import type { Site } from '@automattic/api-core';
import type { DashboardSiteListSite, Site } from '@automattic/api-core';

import './style.scss';

Expand Down Expand Up @@ -50,3 +50,42 @@ export default function SiteIcon( { site, size = 48 }: { site: Site; size?: numb
</div>
);
}

export function SiteIconES( { site, size = 48 }: { site: DashboardSiteListSite; size?: number } ) {
const dims = { width: size, height: size };
const ico = site.icon?.img || site.icon?.ico;
const src = useMemo( () => {
if ( ! ico ) {
return;
}
const url = new URL( ico );
// wordpress.com/wp-content works with w.
url.searchParams.set( 'w', '96' );
// "blavatar" works with s.
url.searchParams.set( 's', '96' );
return url.toString();
}, [ ico ] );

const className = clsx( {
'is-small': size <= 16,
} );

if ( ico ) {
return (
<img
className={ clsx( 'site-icon', className ) }
src={ src }
alt={ site.name }
{ ...dims }
loading="lazy"
style={ { width: size, height: size, minWidth: size } }
/>
);
}

return (
<div className={ clsx( 'site-letter', className ) } style={ { ...dims, fontSize: size * 0.5 } }>
<span>{ site.name?.charAt( 0 ) }</span>
</div>
);
}
69 changes: 67 additions & 2 deletions client/dashboard/sites/dataviews/fields.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { isEnabled } from '@automattic/calypso-config';
import { __ } from '@wordpress/i18n';
import SiteIcon from '../../components/site-icon';
import SiteIcon, { SiteIconES } from '../../components/site-icon';
import TimeSince from '../../components/time-since';
import { getSiteDisplayName } from '../../utils/site-name';
import { getSitePlanDisplayName } from '../../utils/site-plan';
Expand All @@ -13,14 +13,17 @@ import {
LastBackup,
MediaStorage,
Name,
NameES,
PHPVersion,
Plan,
PlanES,
Preview,
Status,
URL,
URLES,
Uptime,
} from '../site-fields';
import type { Site } from '@automattic/api-core';
import type { DashboardSiteListSite, Site } from '@automattic/api-core';
import type { Field, Operator } from '@wordpress/dataviews';

function getDefaultFields(): Field< Site >[] {
Expand Down Expand Up @@ -153,6 +156,43 @@ function getDefaultFields(): Field< Site >[] {
];
}

function getDefaultFieldsES(): Field< DashboardSiteListSite >[] {
return [
{
id: 'name',
label: __( 'Site' ),
enableHiding: false,
enableGlobalSearch: false, // TODO
getValue: ( { item } ) => item.name ?? '',
render: ( { field, item } ) => (
<NameES siteSlug={ item.slug } value={ field.getValue( { item } ) } />
),
enableSorting: false, // TODO
},
{
id: 'url',
label: __( 'URL' ),
enableGlobalSearch: true,
getValue: ( { item } ) => item.url?.value ?? '',
render: ( { field, item } ) => <URLES site={ item } value={ field.getValue( { item } ) } />,
},
{
id: 'icon.ico',
label: __( 'Site icon' ),
render: ( { item } ) => <SiteIconES site={ item } />,
enableSorting: false,
},
{
id: 'plan',
label: __( 'Plan' ),
getValue: ( { item } ) => item.plan?.product_name_short ?? '',
render: ( { item, field } ) => (
<PlanES siteSlug={ item.slug } value={ field.getValue( { item } ) } />
),
},
];
}

export function getFields( {
isAutomattician,
viewType,
Expand All @@ -177,3 +217,28 @@ export function getFields( {
return true;
} );
}

export function getFieldsES( {
isAutomattician,
viewType,
}: {
isAutomattician?: boolean;
viewType?: string;
} ) {
const defaultFields = getDefaultFieldsES();
return defaultFields.filter( ( field ) => {
if ( field.id === 'is_a8c' && ! isAutomattician ) {
return false;
}

if ( field.id === 'icon.ico' && viewType === 'grid' ) {
return false;
}

if ( field.id === 'preview' && viewType === 'table' ) {
return false;
}

return true;
} );
}
72 changes: 49 additions & 23 deletions client/dashboard/sites/dataviews/sites-dataviews.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@ import { __ } from '@wordpress/i18n';
import { DataViews } from '../../app/dataviews';
import { DataViewsCard } from '../../components/dataviews-card';
import { GuidedTourContextProvider, GuidedTourStep } from '../../components/guided-tour';
import { SiteLink } from '../site-fields';
import { SiteLink, SiteLinkES } from '../site-fields';
import { DEFAULT_LAYOUTS, DEFAULT_CONFIG } from './views';
import type { Site } from '@automattic/api-core';
import type { DashboardSiteListSite, Site } from '@automattic/api-core';
import type { Action, Field, View } from '@wordpress/dataviews';
import type { ReactNode } from 'react';

/**
* Meant to stand in for the dataview's filterSortAndPaginate function when
* the filtering has already been done on the backend by elasticsearch.
*/
function esFilterSortAndPaginate( sites: Site[], view: View, totalItems: number ) {
function esFilterSortAndPaginate( sites: DashboardSiteListSite[], view: View, totalItems: number ) {
return {
data: sites,
paginationInfo: {
Expand All @@ -27,8 +27,10 @@ function esFilterSortAndPaginate( sites: Site[], view: View, totalItems: number
export const SitesDataViews = ( {
view,
sites,
sitesES,
totalItems,
fields,
fieldsES,
actions,
isLoading,
empty,
Expand All @@ -37,37 +39,61 @@ export const SitesDataViews = ( {
}: {
view: View;
sites: Site[];
sitesES: DashboardSiteListSite[];
totalItems: number;
fields: Field< Site >[];
fieldsES: Field< DashboardSiteListSite >[];
actions: Action< Site >[];
isLoading: boolean;
empty: ReactNode;
onChangeView: ( view: View ) => void;
onResetView?: () => void;
} ) => {
const { data: filteredData, paginationInfo } = isEnabled( 'dashboard/v2/es-site-list' )
? esFilterSortAndPaginate( sites, view, totalItems )
: filterSortAndPaginate( sites, view, fields );
const { data: filteredData, paginationInfo } = filterSortAndPaginate( sites, view, fields );

const { data: filteredDataES, paginationInfo: paginationInfoES } = esFilterSortAndPaginate(
sitesES,
view,
totalItems
);

const dv = isEnabled( 'dashboard/v2/es-site-list' ) ? (
<DataViews< DashboardSiteListSite >
getItemId={ ( item ) => '' + item.blog_id?.toString() + item.url }
data={ filteredDataES }
fields={ fieldsES }
// TODO: actions={ actions }
view={ view }
isLoading={ isLoading }
onChangeView={ onChangeView }
onResetView={ onResetView }
defaultLayouts={ DEFAULT_LAYOUTS }
paginationInfo={ paginationInfoES }
config={ DEFAULT_CONFIG }
empty={ empty }
renderItemLink={ ( { item, ...props } ) => <SiteLinkES { ...props } site={ item } /> }
/>
) : (
<DataViews< Site >
getItemId={ ( item ) => item.ID.toString() }
data={ filteredData }
fields={ fields }
actions={ actions }
view={ view }
isLoading={ isLoading }
onChangeView={ onChangeView }
onResetView={ onResetView }
defaultLayouts={ DEFAULT_LAYOUTS }
paginationInfo={ paginationInfo }
config={ DEFAULT_CONFIG }
empty={ empty }
renderItemLink={ ( { item, ...props } ) => <SiteLink { ...props } site={ item } /> }
/>
);

return (
<>
<DataViewsCard>
<DataViews< Site >
getItemId={ ( item ) => item.ID.toString() + item.URL }
data={ filteredData }
fields={ fields }
actions={ actions }
view={ view }
isLoading={ isLoading }
onChangeView={ onChangeView }
onResetView={ onResetView }
defaultLayouts={ DEFAULT_LAYOUTS }
paginationInfo={ paginationInfo }
config={ DEFAULT_CONFIG }
empty={ empty }
renderItemLink={ ( { item, ...props } ) => <SiteLink { ...props } site={ item } /> }
/>
</DataViewsCard>
<DataViewsCard>{ dv }</DataViewsCard>
<GuidedTourContextProvider
tourId="hosting-dashboard-tours-sites"
isSkippable
Expand Down
18 changes: 14 additions & 4 deletions client/dashboard/sites/dataviews/views.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { isEnabled } from '@automattic/calypso-config';
import type { AnalyticsClient } from '../../app/analytics';
import type { User } from '@automattic/api-core';
import type { Operator, SortDirection, SupportedLayouts, View } from '@wordpress/dataviews';
Expand All @@ -9,19 +10,23 @@ export const DEFAULT_LAYOUTS: SupportedLayouts = {
},
showLevels: false,
showMedia: true,
showTitle: true,
showDescription: true,
mediaField: 'icon.ico',
titleField: 'name',
descriptionField: 'URL',
descriptionField: isEnabled( 'dashboard/v2/es-site-list' ) ? 'url' : 'URL',
},
grid: {
layout: {
previewSize: 230,
},
showLevels: false,
showMedia: true,
showTitle: true,
showDescription: true,
mediaField: 'preview',
titleField: 'name',
descriptionField: 'URL',
descriptionField: isEnabled( 'dashboard/v2/es-site-list' ) ? 'url' : 'URL',
},
};

Expand All @@ -33,8 +38,13 @@ export const DEFAULT_PER_PAGE = 12;

const DEFAULT_VIEW: Partial< View > = {
perPage: DEFAULT_PER_PAGE,
fields: [ 'status', 'visitors', 'subscribers_count', 'plan' ],
sort: { field: 'name', direction: 'asc' as SortDirection },
fields: isEnabled( 'dashboard/v2/es-site-list' )
? [ 'plan' ]
: [ 'status', 'visitors', 'subscribers_count', 'plan' ],
sort: {
field: isEnabled( 'dashboard/v2/es-site-list' ) ? 'url' : 'name',
direction: 'asc' as SortDirection,
},
};

export function getDefaultView( {
Expand Down
Loading