diff --git a/packages/edit-site/src/components/dataviews/dataviews.js b/packages/edit-site/src/components/dataviews/dataviews.js
index a0973a82a291ca..755ce8a2ea348d 100644
--- a/packages/edit-site/src/components/dataviews/dataviews.js
+++ b/packages/edit-site/src/components/dataviews/dataviews.js
@@ -1,211 +1,54 @@
-/**
- * External dependencies
- */
-import {
- getCoreRowModel,
- getFilteredRowModel,
- getSortedRowModel,
- getPaginationRowModel,
- useReactTable,
-} from '@tanstack/react-table';
-
/**
* WordPress dependencies
*/
import {
__experimentalVStack as VStack,
__experimentalHStack as HStack,
- VisuallyHidden,
- DropdownMenu,
- MenuGroup,
- MenuItem,
} from '@wordpress/components';
-import { useMemo } from '@wordpress/element';
-import { __ } from '@wordpress/i18n';
/**
* Internal dependencies
*/
-import ListView from './list-view';
-import { Pagination } from './pagination';
+import ViewList from './view-list';
+import Pagination from './pagination';
import ViewActions from './view-actions';
import TextFilter from './text-filter';
-import { moreVertical } from '@wordpress/icons';
-
-const EMPTY_OBJECT = {};
+import { ViewGrid } from './view-grid';
export default function DataViews( {
- actions,
- data,
- fields,
view,
onChangeView,
- isLoading,
+ fields,
+ actions,
+ data,
+ isLoading = false,
paginationInfo,
- options: { pageCount },
} ) {
- const columns = useMemo( () => {
- const _columns = [ ...fields ];
- if ( actions?.length ) {
- _columns.push( {
- header: { __( 'Actions' ) },
- id: 'actions',
- cell: ( props ) => {
- return (
-
- { () => (
-
- { actions.map( ( action ) => (
-
- ) ) }
-
- ) }
-
- );
- },
- enableHiding: false,
- } );
- }
-
- return _columns;
- }, [ fields, actions ] );
-
- const columnVisibility = useMemo( () => {
- if ( ! view.hiddenFields?.length ) {
- return;
- }
- return view.hiddenFields.reduce(
- ( accumulator, fieldId ) => ( {
- ...accumulator,
- [ fieldId ]: false,
- } ),
- {}
- );
- }, [ view.hiddenFields ] );
-
- const dataView = useReactTable( {
- data,
- columns,
- manualSorting: true,
- manualFiltering: true,
- manualPagination: true,
- enableRowSelection: true,
- state: {
- sorting: view.sort
- ? [
- {
- id: view.sort.field,
- desc: view.sort.direction === 'desc',
- },
- ]
- : [],
- globalFilter: view.search,
- pagination: {
- pageIndex: view.page,
- pageSize: view.perPage,
- },
- columnVisibility: columnVisibility ?? EMPTY_OBJECT,
- },
- onSortingChange: ( sortingUpdater ) => {
- onChangeView( ( currentView ) => {
- const sort =
- typeof sortingUpdater === 'function'
- ? sortingUpdater(
- currentView.sort
- ? [
- {
- id: currentView.sort.field,
- desc:
- currentView.sort
- .direction === 'desc',
- },
- ]
- : []
- )
- : sortingUpdater;
- if ( ! sort.length ) {
- return {
- ...currentView,
- sort: {},
- };
- }
- const [ { id, desc } ] = sort;
- return {
- ...currentView,
- sort: { field: id, direction: desc ? 'desc' : 'asc' },
- };
- } );
- },
- onColumnVisibilityChange: ( columnVisibilityUpdater ) => {
- onChangeView( ( currentView ) => {
- const hiddenFields = Object.entries(
- columnVisibilityUpdater()
- ).reduce(
- ( accumulator, [ fieldId, value ] ) => {
- if ( value ) {
- return accumulator.filter(
- ( id ) => id !== fieldId
- );
- }
- return [ ...accumulator, fieldId ];
- },
- [ ...( currentView.hiddenFields || [] ) ]
- );
- return {
- ...currentView,
- hiddenFields,
- };
- } );
- },
- onGlobalFilterChange: ( value ) => {
- onChangeView( { ...view, search: value, page: 0 } );
- },
- onPaginationChange: ( paginationUpdater ) => {
- onChangeView( ( currentView ) => {
- const { pageIndex, pageSize } = paginationUpdater( {
- pageIndex: currentView.page,
- pageSize: currentView.perPage,
- } );
- return { ...view, page: pageIndex, perPage: pageSize };
- } );
- },
- getCoreRowModel: getCoreRowModel(),
- getFilteredRowModel: getFilteredRowModel(),
- getSortedRowModel: getSortedRowModel(),
- getPaginationRowModel: getPaginationRowModel(),
- pageCount,
- } );
+ const ViewComponent = view.type === 'list' ? ViewList : ViewGrid;
return (
-
+
- { /* This component will be selected based on viewConfigs. Now we only have the list view. */ }
-
+
diff --git a/packages/edit-site/src/components/dataviews/index.js b/packages/edit-site/src/components/dataviews/index.js
index 3fea6fd63714b7..422d128b1461d0 100644
--- a/packages/edit-site/src/components/dataviews/index.js
+++ b/packages/edit-site/src/components/dataviews/index.js
@@ -1,2 +1 @@
export { default as DataViews } from './dataviews';
-export { PAGE_SIZE_VALUES } from './view-actions';
diff --git a/packages/edit-site/src/components/dataviews/pagination.js b/packages/edit-site/src/components/dataviews/pagination.js
index 3adecd2bb80851..bd6cb503653b07 100644
--- a/packages/edit-site/src/components/dataviews/pagination.js
+++ b/packages/edit-site/src/components/dataviews/pagination.js
@@ -6,26 +6,54 @@ import {
__experimentalHStack as HStack,
__experimentalText as Text,
__experimentalNumberControl as NumberControl,
+ __experimentalInputControlPrefixWrapper as InputControlPrefixWrapper,
+ SelectControl,
} from '@wordpress/components';
import { createInterpolateElement } from '@wordpress/element';
import { sprintf, __, _x, _n } from '@wordpress/i18n';
-/**
- * Internal dependencies
- */
-import { PageSizeControl } from './view-actions';
+const PAGE_SIZE_VALUES = [ 5, 20, 50 ];
+function PageSizeControl( { view, onChangeView } ) {
+ const label = __( 'Rows per page:' );
+ return (
+
+ { label }
+
+ }
+ value={ view.perPage }
+ options={ PAGE_SIZE_VALUES.map( ( pageSize ) => ( {
+ value: pageSize,
+ label: pageSize,
+ } ) ) }
+ onChange={ ( value ) =>
+ onChangeView( { ...view, perPage: value } )
+ }
+ />
+ );
+}
// For now this is copied from the patterns list Pagination component, because
// the datatable pagination starts from index zero(`0`). Eventually all lists will be
// using this one.
-export function Pagination( {
- dataView,
- // If passed, use it, as it's for controlled pagination.
- totalItems = 0,
+function Pagination( {
+ view,
+ onChangeView,
+ paginationInfo: { totalItems = 0, totalPages },
} ) {
- const currentPage = dataView.getState().pagination.pageIndex + 1;
- const numPages = dataView.getPageCount();
- const _totalItems = totalItems || dataView.getCoreRowModel().rows.length;
+ const currentPage = view.page + 1;
+ if ( ! totalItems || ! totalPages ) {
+ return null;
+ }
return (
- { !! _totalItems && (
+ { !! totalItems && (
) }
-
+
);
}
+
+export default Pagination;
diff --git a/packages/edit-site/src/components/dataviews/text-filter.js b/packages/edit-site/src/components/dataviews/text-filter.js
index 76a06c14486170..0b5f7b3cf6790e 100644
--- a/packages/edit-site/src/components/dataviews/text-filter.js
+++ b/packages/edit-site/src/components/dataviews/text-filter.js
@@ -1,8 +1,3 @@
-/**
- * External dependencies
- */
-import classnames from 'classnames';
-
/**
* WordPress dependencies
*/
@@ -15,18 +10,19 @@ import { SearchControl } from '@wordpress/components';
*/
import useDebouncedInput from '../../utils/use-debounced-input';
-export default function TextFilter( {
- className,
- searchLabel = __( 'Filter list' ),
- onChange,
-} ) {
- const [ search, setSearch, debouncedSearch ] = useDebouncedInput();
+export default function TextFilter( { view, onChangeView } ) {
+ const [ search, setSearch, debouncedSearch ] = useDebouncedInput(
+ view.search
+ );
useEffect( () => {
- onChange( debouncedSearch );
- }, [ debouncedSearch, onChange ] );
+ onChangeView( ( currentView ) => ( {
+ ...currentView,
+ search: debouncedSearch,
+ } ) );
+ }, [ debouncedSearch, onChangeView ] );
+ const searchLabel = __( 'Filter list' );
return (
view.type === v.id );
return (
-
+ { activeView.label }
+
+ >
+ }
>
- { label }
-
+ { __( 'Layout' ) }
+
}
- value={ dataView.getState().pagination.pageSize }
- options={ PAGE_SIZE_VALUES.map( ( pageSize ) => ( {
- value: pageSize,
- label: pageSize,
- } ) ) }
- onChange={ ( value ) => dataView.setPageSize( +value ) }
- />
+ >
+ { availableViews.map( ( availableView ) => {
+ return (
+
+ )
+ }
+ onSelect={ ( event ) => {
+ // We need to handle this on DropDown component probably..
+ event.preventDefault();
+ onChangeView( { ...view, type: availableView.id } );
+ } }
+ // TODO: check about role and a11y.
+ role="menuitemcheckbox"
+ >
+ { availableView.label }
+
+ );
+ } ) }
+
);
}
+const PAGE_SIZE_VALUES = [ 5, 20, 50 ];
function PageSizeMenu( { view, onChangeView } ) {
return (
+
);
}
-function ListView( { dataView, className, isLoading = false }, ref ) {
+function ViewList( {
+ view,
+ onChangeView,
+ fields,
+ actions,
+ data,
+ isLoading = false,
+ paginationInfo,
+} ) {
+ const columns = useMemo( () => {
+ const _columns = [ ...fields ];
+ if ( actions?.length ) {
+ _columns.push( {
+ header: { __( 'Actions' ) },
+ id: 'actions',
+ cell: ( props ) => {
+ return (
+
+ { () => (
+
+ { actions.map( ( action ) => (
+
+ ) ) }
+
+ ) }
+
+ );
+ },
+ enableHiding: false,
+ } );
+ }
+
+ return _columns;
+ }, [ fields, actions ] );
+
+ const columnVisibility = useMemo( () => {
+ if ( ! view.hiddenFields?.length ) {
+ return;
+ }
+ return view.hiddenFields.reduce(
+ ( accumulator, fieldId ) => ( {
+ ...accumulator,
+ [ fieldId ]: false,
+ } ),
+ {}
+ );
+ }, [ view.hiddenFields ] );
+
+ const dataView = useReactTable( {
+ data,
+ columns,
+ manualSorting: true,
+ manualFiltering: true,
+ manualPagination: true,
+ enableRowSelection: true,
+ state: {
+ sorting: view.sort
+ ? [
+ {
+ id: view.sort.field,
+ desc: view.sort.direction === 'desc',
+ },
+ ]
+ : [],
+ globalFilter: view.search,
+ pagination: {
+ pageIndex: view.page,
+ pageSize: view.perPage,
+ },
+ columnVisibility: columnVisibility ?? EMPTY_OBJECT,
+ },
+ onSortingChange: ( sortingUpdater ) => {
+ onChangeView( ( currentView ) => {
+ const sort =
+ typeof sortingUpdater === 'function'
+ ? sortingUpdater(
+ currentView.sort
+ ? [
+ {
+ id: currentView.sort.field,
+ desc:
+ currentView.sort
+ .direction === 'desc',
+ },
+ ]
+ : []
+ )
+ : sortingUpdater;
+ if ( ! sort.length ) {
+ return {
+ ...currentView,
+ sort: {},
+ };
+ }
+ const [ { id, desc } ] = sort;
+ return {
+ ...currentView,
+ sort: { field: id, direction: desc ? 'desc' : 'asc' },
+ };
+ } );
+ },
+ onColumnVisibilityChange: ( columnVisibilityUpdater ) => {
+ onChangeView( ( currentView ) => {
+ const hiddenFields = Object.entries(
+ columnVisibilityUpdater()
+ ).reduce(
+ ( accumulator, [ fieldId, value ] ) => {
+ if ( value ) {
+ return accumulator.filter(
+ ( id ) => id !== fieldId
+ );
+ }
+ return [ ...accumulator, fieldId ];
+ },
+ [ ...( currentView.hiddenFields || [] ) ]
+ );
+ return {
+ ...currentView,
+ hiddenFields,
+ };
+ } );
+ },
+ onGlobalFilterChange: ( value ) => {
+ onChangeView( { ...view, search: value, page: 0 } );
+ },
+ onPaginationChange: ( paginationUpdater ) => {
+ onChangeView( ( currentView ) => {
+ const { pageIndex, pageSize } = paginationUpdater( {
+ pageIndex: currentView.page,
+ pageSize: currentView.perPage,
+ } );
+ return { ...view, page: pageIndex, perPage: pageSize };
+ } );
+ },
+ getCoreRowModel: getCoreRowModel(),
+ getFilteredRowModel: getFilteredRowModel(),
+ getSortedRowModel: getSortedRowModel(),
+ getPaginationRowModel: getPaginationRowModel(),
+ pageCount: paginationInfo.totalPages,
+ } );
+
const { rows } = dataView.getRowModel();
const hasRows = !! rows?.length;
if ( isLoading ) {
@@ -123,10 +290,7 @@ function ListView( { dataView, className, isLoading = false }, ref ) {
return (
{ hasRows && (
-
+
{ dataView.getHeaderGroups().map( ( headerGroup ) => (
@@ -183,4 +347,4 @@ function ListView( { dataView, className, isLoading = false }, ref ) {
);
}
-export default forwardRef( ListView );
+export default ViewList;
diff --git a/packages/edit-site/src/components/page-pages/index.js b/packages/edit-site/src/components/page-pages/index.js
index a616ea617feb91..728f7c2c716fe6 100644
--- a/packages/edit-site/src/components/page-pages/index.js
+++ b/packages/edit-site/src/components/page-pages/index.js
@@ -167,9 +167,6 @@ export default function PagePages() {
isLoading={ isLoadingPages }
view={ view }
onChangeView={ setView }
- options={ {
- pageCount: totalPages,
- } }
/>
);