Skip to content

Commit

Permalink
Template parts in patterns page: add author field and primary filter (#…
Browse files Browse the repository at this point in the history
…60372)

Co-authored-by: oandregal <[email protected]>
Co-authored-by: draganescu <[email protected]>
  • Loading branch information
3 people authored Apr 10, 2024
1 parent e4623e1 commit e5e2bd2
Showing 1 changed file with 84 additions and 5 deletions.
89 changes: 84 additions & 5 deletions packages/edit-site/src/components/page-patterns/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/**
* External dependencies
*/
import classnames from 'classnames';

/**
* WordPress dependencies
*/
Expand Down Expand Up @@ -30,6 +35,7 @@ import {
lockSmall,
} from '@wordpress/icons';
import { usePrevious } from '@wordpress/compose';
import { useEntityRecords } from '@wordpress/core-data';

/**
* Internal dependencies
Expand All @@ -39,6 +45,7 @@ import Page from '../page';
import {
LAYOUT_GRID,
LAYOUT_TABLE,
LAYOUT_LIST,
PATTERN_TYPES,
TEMPLATE_PART_POST_TYPE,
PATTERN_SYNC_TYPES,
Expand All @@ -59,6 +66,7 @@ import { unlock } from '../../lock-unlock';
import usePatterns from './use-patterns';
import PatternsHeader from './header';
import { useLink } from '../routes/link';
import { useAddedBy } from '../page-templates-template-parts/hooks';

const { ExperimentalBlockEditorProvider, useGlobalStyle } = unlock(
blockEditorPrivateApis
Expand Down Expand Up @@ -201,6 +209,39 @@ function Preview( { item, categoryId, viewType } ) {
);
}

function Author( { item, viewType } ) {
const [ isImageLoaded, setIsImageLoaded ] = useState( false );
const { text, icon, imageUrl } = useAddedBy( item.type, item.id );
const withIcon = viewType !== LAYOUT_LIST;

return (
<HStack alignment="left" spacing={ 1 }>
{ withIcon && imageUrl && (
<div
className={ classnames(
'page-templates-author-field__avatar',
{
'is-loaded': isImageLoaded,
}
) }
>
<img
onLoad={ () => setIsImageLoaded( true ) }
alt=""
src={ imageUrl }
/>
</div>
) }
{ withIcon && ! imageUrl && (
<div className="page-templates-author-field__icon">
<Icon icon={ icon } />
</div>
) }
<span className="page-templates-author-field__name">{ text }</span>
</HStack>
);
}

function Title( { item, categoryId } ) {
const isUserPattern = item.type === PATTERN_TYPES.user;
const isNonUserPattern = item.type === PATTERN_TYPES.theme;
Expand Down Expand Up @@ -289,6 +330,24 @@ export default function DataviewsPatterns() {
syncStatus: viewSyncStatus,
}
);

const { records } = useEntityRecords( 'postType', TEMPLATE_PART_POST_TYPE, {
per_page: -1,
} );
const authors = useMemo( () => {
if ( ! records ) {
return EMPTY_ARRAY;
}
const authorsSet = new Set();
records.forEach( ( template ) => {
authorsSet.add( template.author_text );
} );
return Array.from( authorsSet ).map( ( author ) => ( {
value: author,
label: author,
} ) );
}, [ records ] );

const fields = useMemo( () => {
const _fields = [
{
Expand All @@ -313,6 +372,7 @@ export default function DataviewsPatterns() {
enableHiding: false,
},
];

if ( type === PATTERN_TYPES.theme ) {
_fields.push( {
header: __( 'Sync status' ),
Expand Down Expand Up @@ -342,23 +402,42 @@ export default function DataviewsPatterns() {
},
enableSorting: false,
} );
} else if ( type === TEMPLATE_PART_POST_TYPE ) {
_fields.push( {
header: __( 'Author' ),
id: 'author',
getValue: ( { item } ) => item.templatePart.author_text,
render: ( { item } ) => {
return <Author viewType={ view.type } item={ item } />;
},
type: ENUMERATION_TYPE,
elements: authors,
filterBy: {
isPrimary: true,
},
width: '1%',
} );
}

return _fields;
}, [ view.type, categoryId, type ] );
}, [ view.type, categoryId, type, authors ] );

// Reset the page number when the category changes.
useEffect( () => {
if ( previousCategoryId !== categoryId ) {
setView( DEFAULT_VIEW );
}
}, [ categoryId, previousCategoryId ] );
const { data, paginationInfo } = useMemo( () => {
// Since filters are applied server-side,
// we need to remove them from the view
// Search is managed server-side as well as filters for patterns.
// However, the author filter in template parts is done client-side.
const viewWithoutFilters = { ...view };
delete viewWithoutFilters.search;
viewWithoutFilters.filters = [];
if ( type !== TEMPLATE_PART_POST_TYPE ) {
viewWithoutFilters.filters = [];
}
return filterSortAndPaginate( patterns, viewWithoutFilters, fields );
}, [ patterns, view, fields ] );
}, [ patterns, view, fields, type ] );

const actions = useMemo(
() => [
Expand Down

0 comments on commit e5e2bd2

Please sign in to comment.