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: extract search from filters #55722

Merged
merged 6 commits into from
Oct 31, 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
26 changes: 8 additions & 18 deletions packages/edit-site/src/components/dataviews/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ This file documents the DataViews UI component, which provides an API to render
view={ view }
onChangeView={ onChangeView }
fields={ fields }
filters={ filters }
actions={ [ trashPostAction ] }
paginationInfo={ { totalItems, totalPages } }
/>
Expand Down Expand Up @@ -43,12 +42,12 @@ Example:
field: 'date',
direction: 'desc',
},
search: '',
filters: {
search: '',
author: 2,
status: 'publish, draft'
},
visibleFilters: [ 'search', 'author', 'status' ],
visibleFilters: [ 'author', 'status' ],
hiddenFields: [ 'date', 'featured-image' ],
layout: {},
}
Expand All @@ -59,6 +58,7 @@ Example:
- `page`: the page that is visible.
- `sort.field`: field used for sorting the dataset.
- `sort.direction`: the direction to use for sorting, one of `asc` or `desc`.
- `search`: the text search applied to the dataset.
- `filters`: the filters applied to the dataset. See filters section.
- `visibleFilters`: the `id` of the filters that are visible in the UI.
- `hiddenFields`: the `id` of the fields that are hidden in the UI.
Expand All @@ -82,6 +82,7 @@ function MyCustomPageList() {
page: view.page,
order: view.sort?.direction,
orderby: view.sort?.field
search: view.search,
...view.filters
} ),
[ view ]
Expand Down Expand Up @@ -133,10 +134,7 @@ Example:
{ value: 1, label: 'Admin' }
{ value: 2, label: 'User' }
]
filters: [
'enumeration'
{ id: 'author_search', type: 'search', name: __( 'Search by author' ) }
],
filters: [ 'enumeration' ],
}
]
```
Expand All @@ -150,34 +148,26 @@ Example:

## Filters

Filters describe the conditions a record should match to be listed as part of the dataset.

Filters can be provided globally, as a property of the `DataViews` component, or per field, should they be considered part of a fields' description.
Filters describe the conditions a record should match to be listed as part of the dataset. Filters are provided per field.

```js
const field = [
{
id: 'author',
filters: [
'enumeration'
{ id: 'author_search', type: 'search', name: __( 'Search by author' ) }
],
filters: [ 'enumeration' ],
}
];

<DataViews
fields={ fields }
filters={ [
{ id: 'search', type: 'search', name: __( 'Filter list' ) }
] }
/>
```

A filter is an object that may contain the following properties:

- `id`: unique identifier for the filter. Matches the entity query param. Field filters may omit it, in which case the field's `id` will be used.
- `name`: nice looking name for the filter. Field filters may omit it, in which case the field's `header` will be used.
- `type`: the type of filter. One of `search` or `enumeration`.
- `type`: the type of filter. Only `enumeration` is supported at the moment.
- `elements`: for filters of type `enumeration`, the list of options to show. A one-dimensional array of object with value/label keys, as in `[ { value: 1, label: "Value name" } ]`.
- `value`: what's serialized into the view's filters.
- `label`: nice-looking name for users.
Expand Down
12 changes: 10 additions & 2 deletions packages/edit-site/src/components/dataviews/dataviews.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@ import ViewList from './view-list';
import Pagination from './pagination';
import ViewActions from './view-actions';
import Filters from './filters';
import TextFilter from './text-filter';
import { ViewGrid } from './view-grid';

export default function DataViews( {
view,
onChangeView,
fields,
filters,
search = true,
searchLabel = undefined,
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 we need to have these props to start with?

Copy link
Member Author

Choose a reason for hiding this comment

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

Those are actions consumers may need to do. Happy to remove them if you rather don't allow them for now.

actions,
data,
isLoading = false,
Expand All @@ -38,8 +40,14 @@ export default function DataViews( {
<VStack spacing={ 4 } justify="flex-start">
<HStack>
<HStack justify="start">
{ search && (
<TextFilter
label={ searchLabel }
view={ view }
onChangeView={ onChangeView }
/>
) }
<Filters
filters={ filters }
fields={ fields }
view={ view }
onChangeView={ onChangeView }
Expand Down
21 changes: 1 addition & 20 deletions packages/edit-site/src/components/dataviews/filters.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,10 @@ import { __ } from '@wordpress/i18n';
/**
* Internal dependencies
*/
import TextFilter from './text-filter';
import InFilter from './in-filter';

export default function Filters( { filters, fields, view, onChangeView } ) {
export default function Filters( { fields, view, onChangeView } ) {
const filterIndex = {};
filters.forEach( ( filter ) => {
if ( 'object' !== typeof filter || ! filter?.id || ! filter?.type ) {
return;
}

filterIndex[ filter.id ] = filter;
} );

fields.forEach( ( field ) => {
if ( ! field.filters ) {
return;
Expand Down Expand Up @@ -67,16 +58,6 @@ export default function Filters( { filters, fields, view, onChangeView } ) {
return null;
}

if ( filter.type === 'search' ) {
return (
<TextFilter
key={ filterName }
filter={ filter }
view={ view }
onChangeView={ onChangeView }
/>
);
}
if ( filter.type === 'enumeration' ) {
return (
<InFilter
Expand Down
4 changes: 2 additions & 2 deletions packages/edit-site/src/components/dataviews/provider.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ export const DEFAULT_STATUSES = 'draft,future,pending,private,publish'; // All s
const DEFAULT_VIEWS = {
page: {
type: 'list',
search: '',
filters: {
search: '',
status: DEFAULT_STATUSES,
},
page: 1,
Expand All @@ -38,7 +38,7 @@ const DEFAULT_VIEWS = {
field: 'date',
direction: 'desc',
},
visibleFilters: [ 'search', 'author', 'status' ],
visibleFilters: [ 'author', 'status' ],
// All fields are visible by default, so it's
// better to keep track of the hidden ones.
hiddenFields: [ 'date', 'featured-image' ],
Expand Down
13 changes: 5 additions & 8 deletions packages/edit-site/src/components/dataviews/text-filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ import { SearchControl } from '@wordpress/components';
*/
import useDebouncedInput from '../../utils/use-debounced-input';

export default function TextFilter( { filter, view, onChangeView } ) {
export default function TextFilter( { label, view, onChangeView } ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This should probably be renamed Search or something like that as it's not generic anymore.

Copy link
Member Author

Choose a reason for hiding this comment

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

Agreed, though didn't want to do it in this PR to make reviews easier.

Copy link
Member Author

Choose a reason for hiding this comment

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

const [ search, setSearch, debouncedSearch ] = useDebouncedInput(
view.filters[ filter.id ]
view.search
);
useEffect( () => {
setSearch( view.filters[ filter.id ] );
setSearch( view.search );
}, [ view ] );
const onChangeViewRef = useRef( onChangeView );
useEffect( () => {
Expand All @@ -25,13 +25,10 @@ export default function TextFilter( { filter, view, onChangeView } ) {
onChangeViewRef.current( ( currentView ) => ( {
...currentView,
page: 1,
filters: {
...currentView.filters,
[ filter.id ]: debouncedSearch,
},
search: debouncedSearch,
} ) );
}, [ debouncedSearch ] );
const searchLabel = filter?.name || __( 'Filter list' );
const searchLabel = label || __( 'Filter list' );
return (
<SearchControl
onChange={ setSearch }
Expand Down
6 changes: 1 addition & 5 deletions packages/edit-site/src/components/page-pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ export default function PagePages() {
_embed: 'author',
order: view.sort?.direction,
orderby: view.sort?.field,
search: view.search,
...view.filters,
} ),
[ view ]
Expand Down Expand Up @@ -208,10 +209,6 @@ export default function PagePages() {
[ statuses, authors ]
);

const filters = useMemo( () => [
{ id: 'search', type: 'search', name: __( 'Filter list' ) },
] );

const trashPostAction = useTrashPostAction();
const editPostAction = useEditPostAction();
const actions = useMemo(
Expand Down Expand Up @@ -249,7 +246,6 @@ export default function PagePages() {
<DataViews
paginationInfo={ paginationInfo }
fields={ fields }
filters={ filters }
actions={ actions }
data={ pages || EMPTY_ARRAY }
isLoading={ isLoadingPages }
Expand Down
Loading