Skip to content

Commit

Permalink
DataViews: Update the view actions menu to be independent from curren…
Browse files Browse the repository at this point in the history
…t view APIs (#55294)
  • Loading branch information
youknowriad authored Oct 12, 2023
1 parent 01876a8 commit 6afcd18
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 63 deletions.
6 changes: 5 additions & 1 deletion packages/edit-site/src/components/dataviews/dataviews.js
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,11 @@ export default function DataViews( {
<VStack spacing={ 4 }>
<HStack justify="space-between">
<TextFilter onChange={ dataView.setGlobalFilter } />
<ViewActions dataView={ dataView } />
<ViewActions
fields={ fields }
view={ view }
onChangeView={ onChangeView }
/>
</HStack>
{ /* This component will be selected based on viewConfigs. Now we only have the list view. */ }
<ListView dataView={ dataView } isLoading={ isLoading } />
Expand Down
47 changes: 41 additions & 6 deletions packages/edit-site/src/components/dataviews/list-view.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,14 @@ import { flexRender } from '@tanstack/react-table';
* WordPress dependencies
*/
import { __ } from '@wordpress/i18n';
import { chevronDown, chevronUp, unseen } from '@wordpress/icons';
import {
chevronDown,
chevronUp,
unseen,
check,
arrowUp,
arrowDown,
} from '@wordpress/icons';
import {
Button,
Icon,
Expand All @@ -20,7 +27,6 @@ import { forwardRef } from '@wordpress/element';
* Internal dependencies
*/
import { unlock } from '../../lock-unlock';
import { FieldSortingItems } from './view-actions';

const {
DropdownMenuV2,
Expand All @@ -29,6 +35,10 @@ const {
DropdownMenuSeparatorV2,
} = unlock( componentsPrivateApis );

const sortingItemsInfo = {
asc: { icon: arrowUp, label: __( 'Sort ascending' ) },
desc: { icon: arrowDown, label: __( 'Sort descending' ) },
};
const sortIcons = { asc: chevronUp, desc: chevronDown };
function HeaderMenu( { dataView, header } ) {
if ( header.isPlaceholder ) {
Expand All @@ -43,6 +53,7 @@ function HeaderMenu( { dataView, header } ) {
if ( ! isSortable && ! isHidable ) {
return text;
}
const sortedDirection = header.column.getIsSorted();
return (
<DropdownMenuV2
align="start"
Expand All @@ -57,10 +68,34 @@ function HeaderMenu( { dataView, header } ) {
>
{ isSortable && (
<DropdownMenuGroupV2>
<FieldSortingItems
field={ header.column }
dataView={ dataView }
/>
{ Object.entries( sortingItemsInfo ).map(
( [ direction, info ] ) => (
<DropdownMenuItemV2
key={ direction }
prefix={ <Icon icon={ info.icon } /> }
suffix={
sortedDirection === direction && (
<Icon icon={ check } />
)
}
onSelect={ ( event ) => {
event.preventDefault();
if ( sortedDirection === direction ) {
dataView.resetSorting();
} else {
dataView.setSorting( [
{
id: header.column.id,
desc: direction === 'desc',
},
] );
}
} }
>
{ info.label }
</DropdownMenuItemV2>
)
) }
</DropdownMenuGroupV2>
) }
{ isSortable && isHidable && <DropdownMenuSeparatorV2 /> }
Expand Down
135 changes: 81 additions & 54 deletions packages/edit-site/src/components/dataviews/view-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,14 @@ export function PageSizeControl( { dataView } ) {
);
}

function PageSizeMenu( { dataView } ) {
const currenPageSize = dataView.getState().pagination.pageSize;
function PageSizeMenu( { view, onChangeView } ) {
return (
<DropdownSubMenuV2
trigger={
<DropdownSubMenuTriggerV2
suffix={
<>
{ currenPageSize }
{ view.perPage }
<Icon icon={ chevronRightSmall } />
</>
}
Expand All @@ -83,12 +82,12 @@ function PageSizeMenu( { dataView } ) {
<DropdownMenuItemV2
key={ size }
prefix={
currenPageSize === size && <Icon icon={ check } />
view.perPage === size && <Icon icon={ check } />
}
onSelect={ ( event ) => {
// We need to handle this on DropDown component probably..
event.preventDefault();
dataView.setPageSize( size );
onChangeView( { ...view, perPage: size, page: 0 } );
} }
// TODO: check about role and a11y.
role="menuitemcheckbox"
Expand All @@ -101,10 +100,10 @@ function PageSizeMenu( { dataView } ) {
);
}

function FieldsVisibilityMenu( { dataView } ) {
const hidableFields = dataView
.getAllColumns()
.filter( ( columnn ) => columnn.getCanHide() );
function FieldsVisibilityMenu( { view, onChangeView, fields } ) {
const hidableFields = fields.filter(
( field ) => field.enableHiding !== false
);
if ( ! hidableFields?.length ) {
return null;
}
Expand All @@ -123,15 +122,26 @@ function FieldsVisibilityMenu( { dataView } ) {
<DropdownMenuItemV2
key={ field.id }
prefix={
field.getIsVisible() && <Icon icon={ check } />
! view.hiddenFields?.includes( field.id ) && (
<Icon icon={ check } />
)
}
onSelect={ ( event ) => {
event.preventDefault();
field.getToggleVisibilityHandler()( event );
onChangeView( {
...view,
hiddenFields: view.hiddenFields?.includes(
field.id
)
? view.hiddenFields.filter(
( id ) => id !== field.id
)
: [ ...view.hiddenFields, field.id ],
} );
} }
role="menuitemcheckbox"
>
{ field.columnDef.header }
{ field.header }
</DropdownMenuItemV2>
);
} ) }
Expand All @@ -144,48 +154,23 @@ const sortingItemsInfo = {
asc: { icon: arrowUp, label: __( 'Sort ascending' ) },
desc: { icon: arrowDown, label: __( 'Sort descending' ) },
};
export function FieldSortingItems( { field, dataView } ) {
const sortedDirection = field.getIsSorted();
return Object.entries( sortingItemsInfo ).map( ( [ direction, info ] ) => (
<DropdownMenuItemV2
key={ direction }
prefix={ <Icon icon={ info.icon } /> }
suffix={ sortedDirection === direction && <Icon icon={ check } /> }
onSelect={ ( event ) => {
event.preventDefault();
if ( sortedDirection === direction ) {
dataView.resetSorting();
} else {
dataView.setSorting( [
{
id: field.id,
desc: direction === 'desc',
},
] );
}
} }
>
{ info.label }
</DropdownMenuItemV2>
) );
}
function SortMenu( { dataView } ) {
const sortableFields = dataView
.getAllColumns()
.filter( ( columnn ) => columnn.getCanSort() );
function SortMenu( { fields, view, onChangeView } ) {
const sortableFields = fields.filter(
( field ) => field.enableSorting !== false
);
if ( ! sortableFields?.length ) {
return null;
}
const currentSortedField = sortableFields.find( ( field ) =>
field.getIsSorted()
const currentSortedField = fields.find(
( field ) => field.id === view.sort?.field
);
return (
<DropdownSubMenuV2
trigger={
<DropdownSubMenuTriggerV2
suffix={
<>
{ currentSortedField?.columnDef.header }
{ currentSortedField?.header }
<Icon icon={ chevronRightSmall } />
</>
}
Expand All @@ -195,34 +180,68 @@ function SortMenu( { dataView } ) {
}
>
{ sortableFields?.map( ( field ) => {
const sortedDirection = view.sort?.direction;
return (
<DropdownSubMenuV2
key={ field.id }
trigger={
<DropdownSubMenuTriggerV2
suffix={ <Icon icon={ chevronRightSmall } /> }
>
{ field.columnDef.header }
{ field.header }
</DropdownSubMenuTriggerV2>
}
side="left"
>
<FieldSortingItems
field={ field }
dataView={ dataView }
/>
{ Object.entries( sortingItemsInfo ).map(
( [ direction, info ] ) => {
const isActive =
currentSortedField &&
sortedDirection === direction &&
field.id === currentSortedField.id;
return (
<DropdownMenuItemV2
key={ direction }
prefix={ <Icon icon={ info.icon } /> }
suffix={
isActive && <Icon icon={ check } />
}
onSelect={ ( event ) => {
event.preventDefault();
if (
sortedDirection === direction
) {
onChangeView( {
...view,
sort: undefined,
} );
} else {
onChangeView( {
...view,
sort: {
field: field.id,
direction,
},
} );
}
} }
>
{ info.label }
</DropdownMenuItemV2>
);
}
) }
</DropdownSubMenuV2>
);
} ) }
</DropdownSubMenuV2>
);
}

export default function ViewActions( { dataView, className } ) {
export default function ViewActions( { fields, view, onChangeView } ) {
return (
<DropdownMenuV2
label={ __( 'Actions' ) }
className={ className }
trigger={
<Button variant="tertiary" icon={ blockTable }>
{ __( 'View' ) }
Expand All @@ -231,9 +250,17 @@ export default function ViewActions( { dataView, className } ) {
}
>
<DropdownMenuGroupV2>
<SortMenu dataView={ dataView } />
<FieldsVisibilityMenu dataView={ dataView } />
<PageSizeMenu dataView={ dataView } />
<SortMenu
fields={ fields }
view={ view }
onChangeView={ onChangeView }
/>
<FieldsVisibilityMenu
fields={ fields }
view={ view }
onChangeView={ onChangeView }
/>
<PageSizeMenu view={ view } onChangeView={ onChangeView } />
</DropdownMenuGroupV2>
</DropdownMenuV2>
);
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 @@ -52,8 +52,8 @@ export default function PagePages() {
per_page: view.perPage,
page: view.page + 1, // tanstack starts from zero.
_embed: 'author',
order: view.sort.direction,
orderby: view.sort.field,
order: view.sort?.direction,
orderby: view.sort?.field,
search: view.search,
status: [ 'publish', 'draft' ],
} ),
Expand Down

1 comment on commit 6afcd18

@github-actions
Copy link

Choose a reason for hiding this comment

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

Flaky tests detected in 6afcd18.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/6496399488
📝 Reported issues:

Please sign in to comment.