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 preview and grid view in templates list #56382

Merged
merged 6 commits into from
Nov 23, 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
13 changes: 10 additions & 3 deletions packages/edit-site/src/components/dataviews/view-grid.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
FlexBlock,
Placeholder,
} from '@wordpress/components';
import { useAsyncList } from '@wordpress/compose';

/**
* Internal dependencies
Expand All @@ -23,9 +24,15 @@ export function ViewGrid( { data, fields, view, actions, getItemId } ) {
! view.hiddenFields.includes( field.id ) &&
field.id !== view.layout.mediaField
);
const shownData = useAsyncList( data, { step: 3 } );
return (
<Grid gap={ 8 } columns={ 2 } alignment="top">
{ data.map( ( item, index ) => {
<Grid
gap={ 8 }
columns={ 2 }
alignment="top"
className="dataviews-grid-view"
>
{ shownData.map( ( item, index ) => {
return (
<VStack key={ getItemId?.( item ) || index }>
<div className="dataviews-view-grid__media">
Expand All @@ -50,7 +57,7 @@ export function ViewGrid( { data, fields, view, actions, getItemId } ) {
) ) }
</VStack>
</FlexBlock>
<FlexBlock>
<FlexBlock style={ { maxWidth: 'min-content' } }>
<ItemActions
item={ item }
actions={ actions }
Expand Down
10 changes: 9 additions & 1 deletion packages/edit-site/src/components/dataviews/view-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { useAsyncList } from '@wordpress/compose';
import {
chevronDown,
chevronUp,
Expand Down Expand Up @@ -332,8 +333,9 @@ function ViewList( {
return { field, operator, value };
} );

const shownData = useAsyncList( data );
const dataView = useReactTable( {
data,
data: shownData,
columns,
manualSorting: true,
manualFiltering: true,
Expand Down Expand Up @@ -455,6 +457,9 @@ function ViewList( {
width:
header.column.columnDef.width ||
undefined,
minWidth:
header.column.columnDef
.minWidth || undefined,
maxWidth:
header.column.columnDef
.maxWidth || undefined,
Expand All @@ -480,6 +485,9 @@ function ViewList( {
width:
cell.column.columnDef.width ||
undefined,
minWidth:
cell.column.columnDef
.minWidth || undefined,
maxWidth:
cell.column.columnDef
.maxWidth || undefined,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ import { __, _x } from '@wordpress/i18n';
import { useState, useMemo, useCallback } from '@wordpress/element';
import { useEntityRecords } from '@wordpress/core-data';
import { decodeEntities } from '@wordpress/html-entities';
import { parse } from '@wordpress/blocks';
import {
BlockPreview,
privateApis as blockEditorPrivateApis,
} from '@wordpress/block-editor';

/**
* Internal dependencies
Expand All @@ -31,17 +36,28 @@ import {
deleteTemplateAction,
renameTemplateAction,
} from './template-actions';
import usePatternSettings from '../page-patterns/use-pattern-settings';
import { unlock } from '../../lock-unlock';

const { ExperimentalBlockEditorProvider } = unlock( blockEditorPrivateApis );

const EMPTY_ARRAY = [];

const defaultConfigPerViewType = {
list: {},
grid: {
mediaField: 'preview',
},
};

const DEFAULT_VIEW = {
type: 'list',
search: '',
page: 1,
perPage: 20,
// All fields are visible by default, so it's
// better to keep track of the hidden ones.
hiddenFields: [],
hiddenFields: [ 'preview' ],
Copy link
Member

Choose a reason for hiding this comment

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

I still consider a bug that the preview field cannot be hidden in the grid layout :/ Not to fix in this PR, though.

Gravacao.do.ecra.2023-11-23.as.11.25.43.mov

layout: {},
};

Expand Down Expand Up @@ -94,6 +110,32 @@ function AuthorField( { item } ) {
);
}

function TemplatePreview( { content, viewType } ) {
const settings = usePatternSettings();
Copy link
Member

@oandregal oandregal Nov 23, 2023

Choose a reason for hiding this comment

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

It's a bit weird that we use this hook when this page is unrelated to patterns. Looking at the data the hook provides, it sounds like we'd only need the settings from the site editor (everything else is related to patterns). Can we pull those settings directly here?

Copy link
Contributor

Choose a reason for hiding this comment

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

This hook is misnamed I think. It's about providing the block editor with the settings it needs to render anything (with all the patterns, styles...)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually this hook loads the patterns are needed here too, in order to render previews with patterns inside. These patterns are loaded within a Block Editor instance and in our case we don't load one.

const blocks = useMemo( () => {
return parse( content );
}, [ content ] );
if ( ! blocks?.length ) {
return null;
}
// Wrap everything in a block editor provider to ensure 'styles' that are needed
// for the previews are synced between the site editor store and the block editor store.
// Additionally we need to have the `__experimentalBlockPatterns` setting in order to
// render patterns inside the previews.
// TODO: Same approach is used in the patterns list and it becomes obvious that some of
// the block editor settings are needed in context where we don't have the block editor.
// Explore how we can solve this in a better way.
return (
<ExperimentalBlockEditorProvider settings={ settings }>
<div
className={ `page-templates-preview-field is-viewtype-${ viewType }` }
>
<BlockPreview blocks={ blocks } />
</div>
</ExperimentalBlockEditorProvider>
);
}

export default function DataviewsTemplates() {
const [ view, setView ] = useState( DEFAULT_VIEW );
const { records: allTemplates, isResolving: isLoadingData } =
Expand Down Expand Up @@ -153,6 +195,21 @@ export default function DataviewsTemplates() {
}, [ allTemplates, view ] );
const fields = useMemo(
() => [
{
header: __( 'Preview' ),
id: 'preview',
render: ( { item, view: { type: viewType } } ) => {
return (
<TemplatePreview
content={ item.content.raw }
viewType={ viewType }
/>
);
},
minWidth: 120,
Copy link
Member

@oandregal oandregal Nov 23, 2023

Choose a reason for hiding this comment

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

I mentioned elsewhere, but this data is only for one of the layouts (list). We should find a different way to provide this. Either by making it explicit in the field API (e.g.: scope it under layout.list.minWidth, for example) or by absorbing it in the view config (in principle, I'd prefer this option, as it relates to controlling layout).

Not to fix in this PR, but important to figure out before stabilizing/creating a package for dataviews.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed, but let's explore this separately. Probably it should be enough by just adding specific css on each field, per view type.

maxWidth: 120,
enableSorting: false,
},
{
header: __( 'Template' ),
id: 'title',
Expand Down Expand Up @@ -180,7 +237,6 @@ export default function DataviewsTemplates() {
{
header: __( 'Author' ),
id: 'author',
getValue: () => {},
render: ( { item } ) => <AuthorField item={ item } />,
enableHiding: false,
enableSorting: false,
Expand All @@ -199,10 +255,19 @@ export default function DataviewsTemplates() {
);
const onChangeView = useCallback(
( viewUpdater ) => {
const updatedView =
let updatedView =
typeof viewUpdater === 'function'
? viewUpdater( view )
: viewUpdater;
if ( updatedView.type !== view.type ) {
updatedView = {
...updatedView,
layout: {
...defaultConfigPerViewType[ updatedView.type ],
},
};
}

setView( updatedView );
},
[ view, setView ]
Expand All @@ -218,7 +283,7 @@ export default function DataviewsTemplates() {
isLoading={ isLoadingData }
view={ view }
onChangeView={ onChangeView }
supportedLayouts={ [ 'list' ] }
supportedLayouts={ [ 'list', 'grid' ] }
/>
</Page>
);
Expand Down
18 changes: 18 additions & 0 deletions packages/edit-site/src/components/page-templates/style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.page-templates-preview-field {
.block-editor-block-preview__container {
border: 1px solid $gray-300;
border-radius: $radius-block-ui;
}

&.is-viewtype-list {
.block-editor-block-preview__container {
height: 120px;
}
}

&.is-viewtype-grid {
.block-editor-block-preview__container {
height: 320px;
}
}
}
1 change: 1 addition & 0 deletions packages/edit-site/src/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
@import "./components/page/style.scss";
@import "./components/page-pages/style.scss";
@import "./components/page-patterns/style.scss";
@import "./components/page-templates/style.scss";
@import "./components/table/style.scss";
@import "./components/sidebar-edit-mode/style.scss";
@import "./components/sidebar-edit-mode/page-panels/style.scss";
Expand Down
Loading