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: Update the view actions menu to be independent from current view APIs #55294

Merged
merged 1 commit into from
Oct 12, 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
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();
Copy link
Contributor

Choose a reason for hiding this comment

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

I see you separated the code again here. That's fine, but the plan is to update the code here to update the view, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't really know whether we should merge the two, especially since list view heavily depends on tanstack. We'll see how that menu grows.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, we'll see, but I think we can use tanstack for the other views too(at least the simpler ones like grid, etc..).

} 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
Loading