Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DataViews: add list layout to templates #57014

Merged
merged 9 commits into from
Dec 13, 2023
Merged
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
1 change: 1 addition & 0 deletions packages/dataviews/src/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@
border-radius: $grid-unit-05;
overflow: hidden;
position: relative;
margin-top: $grid-unit-05;

&::after {
content: "";
Expand Down
2 changes: 1 addition & 1 deletion packages/dataviews/src/view-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export default function ViewList( {
) }
onClick={ () => onSelectionChange( [ item ] ) }
>
<HStack spacing={ 3 }>
<HStack spacing={ 3 } alignment="flex-start">
<div className="dataviews-list-view__media-wrapper">
{ mediaField?.render( { item } ) || (
<div className="dataviews-list-view__media-placeholder"></div>
Expand Down
10 changes: 8 additions & 2 deletions packages/edit-site/src/components/layout/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -156,14 +156,20 @@
}
}

.edit-site-template-pages-list-view {
max-width: $nav-sidebar-width;
}

// This shouldn't be necessary (we should have a way to say that a skeletton is relative
.edit-site-layout__canvas .interface-interface-skeleton,
.edit-site-page-pages-preview .interface-interface-skeleton {
.edit-site-page-pages-preview .interface-interface-skeleton,
.edit-site-template-pages-preview .interface-interface-skeleton {
position: relative !important;
min-height: 100% !important;
}

.edit-site-page-pages-preview {
.edit-site-page-pages-preview,
.edit-site-template-pages-preview {
height: 100%;
}

Expand Down
4 changes: 2 additions & 2 deletions packages/edit-site/src/components/page-pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import {
viewPostAction,
useEditPostAction,
} from '../actions';
import SideEditor from './side-editor';
import PostPreview from '../post-preview';
import Media from '../media';
import { unlock } from '../../lock-unlock';
const { useLocation } = unlock( routerPrivateApis );
Expand Down Expand Up @@ -338,7 +338,7 @@ export default function PagePages() {
<Page>
<div className="edit-site-page-pages-preview">
{ pageId !== null ? (
<SideEditor
<PostPreview
postId={ pageId }
postType={ postType }
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
__experimentalVStack as VStack,
VisuallyHidden,
} from '@wordpress/components';
import { __, _x } from '@wordpress/i18n';
import { __ } from '@wordpress/i18n';
import { useState, useMemo, useCallback } from '@wordpress/element';
import { useEntityRecords } from '@wordpress/core-data';
import { decodeEntities } from '@wordpress/html-entities';
Expand All @@ -38,6 +38,7 @@ import {
OPERATOR_NOT_IN,
LAYOUT_GRID,
LAYOUT_TABLE,
LAYOUT_LIST,
} from '../../utils/constants';
import {
useResetTemplateAction,
Expand All @@ -46,6 +47,7 @@ import {
} from './template-actions';
import usePatternSettings from '../page-patterns/use-pattern-settings';
import { unlock } from '../../lock-unlock';
import PostPreview from '../post-preview';

const { ExperimentalBlockEditorProvider, useGlobalStyle } = unlock(
blockEditorPrivateApis
Expand All @@ -59,6 +61,10 @@ const defaultConfigPerViewType = {
mediaField: 'preview',
primaryField: 'title',
},
[ LAYOUT_LIST ]: {
primaryField: 'title',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think the primaryField could be different between views? I can't think of a use case like that, so maybe we should add in the fields API(ex isPrimary)? 🤔

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe it can be modified, and in this case, it just becomes a top level config, like "sort" or "visibleFields" or something like that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think the primaryField could be different between views? I can't think of a use case like that, so maybe we should add in the fields API(ex isPrimary)? 🤔

I feel the same as you: it's quite improbable that it's different across views. However, I think the meaning of "primary" is something that belongs to the view API and not the field API.

maybe it can be modified, and in this case, it just becomes a top level config, like "sort" or "visibleFields" or something like that.

By the user, you mean?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

user or the person that creates the view, in which case it's in the view object like you said

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd leave it as it is in this PR. If it requires further action, it can be done separately.

mediaField: 'preview',
},
};

const DEFAULT_VIEW = {
Expand All @@ -77,10 +83,16 @@ function normalizeSearchInput( input = '' ) {
return removeAccents( input.trim().toLowerCase() );
}

// TODO: these are going to be reused in the template part list.
// That's the reason for leaving the template parts code for now.
function TemplateTitle( { item } ) {
const { isCustomized } = useAddedBy( item.type, item.id );
function TemplateTitle( { item, view } ) {
if ( view.type === LAYOUT_LIST ) {
return (
<>
{ decodeEntities( item.title?.rendered || item.slug ) ||
__( '(no title)' ) }
</>
);
}

return (
<VStack spacing={ 1 }>
<View as="span" className="edit-site-list-title__customized-info">
Expand All @@ -95,24 +107,18 @@ function TemplateTitle( { item } ) {
__( '(no title)' ) }
</Link>
</View>
{ isCustomized && (
<span className="edit-site-list-added-by__customized-info">
{ item.type === TEMPLATE_POST_TYPE
? _x( 'Customized', 'template' )
: _x( 'Customized', 'template part' ) }
</span>
) }
</VStack>
);
}

function AuthorField( { item } ) {
function AuthorField( { item, view } ) {
const { text, icon, imageUrl } = useAddedBy( item.type, item.id );
const withIcon = view.type !== LAYOUT_LIST;

return (
<HStack alignment="left" spacing={ 1 }>
{ imageUrl ? (
<AvatarImage imageUrl={ imageUrl } />
) : (
{ withIcon && imageUrl && <AvatarImage imageUrl={ imageUrl } /> }
{ withIcon && ! imageUrl && (
<div className="edit-site-list-added-by__icon">
<Icon icon={ icon } />
</div>
Expand Down Expand Up @@ -151,12 +157,16 @@ function TemplatePreview( { content, viewType } ) {
}

export default function DataviewsTemplates() {
const [ templateId, setTemplateId ] = useState( null );
const [ view, setView ] = useState( DEFAULT_VIEW );
const { records: allTemplates, isResolving: isLoadingData } =
useEntityRecords( 'postType', TEMPLATE_POST_TYPE, {
per_page: -1,
} );

const onSelectionChange = ( items ) =>
setTemplateId( items?.length === 1 ? items[ 0 ].id : null );

const authors = useMemo( () => {
if ( ! allTemplates ) {
return EMPTY_ARRAY;
Expand Down Expand Up @@ -192,7 +202,9 @@ export default function DataviewsTemplates() {
header: __( 'Template' ),
id: 'title',
getValue: ( { item } ) => item.title?.rendered || item.slug,
render: ( { item } ) => <TemplateTitle item={ item } />,
render: ( { item } ) => (
<TemplateTitle item={ item } view={ view } />
),
maxWidth: 400,
enableHiding: false,
},
Expand Down Expand Up @@ -222,7 +234,7 @@ export default function DataviewsTemplates() {
id: 'author',
getValue: ( { item } ) => item.author_text,
render: ( { item } ) => {
return <AuthorField item={ item } />;
return <AuthorField view={ view } item={ item } />;
},
enableHiding: false,
type: ENUMERATION_TYPE,
Expand Down Expand Up @@ -342,19 +354,54 @@ export default function DataviewsTemplates() {
[ view, setView ]
);
return (
<Page title={ __( 'Templates' ) }>
<DataViews
paginationInfo={ paginationInfo }
fields={ fields }
actions={ actions }
data={ shownTemplates }
getItemId={ ( item ) => item.id }
isLoading={ isLoadingData }
view={ view }
onChangeView={ onChangeView }
supportedLayouts={ [ LAYOUT_TABLE, LAYOUT_GRID ] }
deferredRendering={ ! view.hiddenFields?.includes( 'preview' ) }
/>
</Page>
<>
<Page
className={
view.type === LAYOUT_LIST
? 'edit-site-template-pages-list-view'
: null
}
title={ __( 'Templates' ) }
>
<DataViews
paginationInfo={ paginationInfo }
fields={ fields }
actions={ actions }
data={ shownTemplates }
getItemId={ ( item ) => item.id }
isLoading={ isLoadingData }
view={ view }
onChangeView={ onChangeView }
onSelectionChange={ onSelectionChange }
deferredRendering={
! view.hiddenFields?.includes( 'preview' )
}
/>
</Page>
{ view.type === LAYOUT_LIST && (
<Page>
<div className="edit-site-template-pages-preview">
{ templateId !== null ? (
<PostPreview
postId={ templateId }
postType={ TEMPLATE_POST_TYPE }
/>
) : (
<div
style={ {
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
textAlign: 'center',
height: '100%',
} }
>
<p>{ __( 'Select a template to preview' ) }</p>
</div>
) }
</div>
</Page>
) }
</>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import Editor from '../editor';
import { useInitEditedEntity } from '../sync-state-with-url/use-init-edited-entity-from-url';

export default function SideEditor( { postType, postId } ) {
export default function PostPreview( { postType, postId } ) {
useInitEditedEntity( {
postId,
postType,
Expand Down
Loading