Skip to content

Commit

Permalink
DataViews: Replace supportedLayouts prop with defaultLayouts prop ins…
Browse files Browse the repository at this point in the history
…tead (#63287)

Co-authored-by: youknowriad <[email protected]>
Co-authored-by: ntsekouras <[email protected]>
  • Loading branch information
3 people authored Jul 9, 2024
1 parent eb74cf5 commit c1c46e6
Show file tree
Hide file tree
Showing 15 changed files with 126 additions and 139 deletions.
1 change: 1 addition & 0 deletions packages/dataviews/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
### Breaking Changes

- Replace the `hiddenFields` property in the view prop of `DataViews` with a `fields` property that accepts an array of visible fields instead.
- Replace the `supportedLayouts` prop in the `DataViews` component with a `defaultLayouts` prop that accepts an object whose keys are the layout names and values are the default view objects for these layouts.

### New features

Expand Down
4 changes: 2 additions & 2 deletions packages/dataviews/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -274,9 +274,9 @@ Function that receives an item and returns an unique identifier for it. By defau

Whether the data is loading. `false` by default.

### `supportedLayouts`: `String[]`
### `defaultLayouts`: `Record< string, view >`

Array of layouts supported. By default, all are: `table`, `grid`, `list`.
Default layouts. By default, uses empty layouts: `table`, `grid`, `list`.

### `onSelectionChange`: `function`

Expand Down
14 changes: 10 additions & 4 deletions packages/dataviews/src/dataviews.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,13 @@ import {
} from './bulk-actions';
import { normalizeFields } from './normalize-fields';
import BulkActionsToolbar from './bulk-actions-toolbar';
import type { Action, Field, View, ViewBaseProps } from './types';
import type {
Action,
Field,
View,
ViewBaseProps,
SupportedLayouts,
} from './types';
import type { SetSelection, SelectionOrUpdater } from './private-types';

type ItemWithId = { id: string };
Expand All @@ -42,7 +48,7 @@ type DataViewsProps< Item > = {
totalItems: number;
totalPages: number;
};
supportedLayouts: string[];
defaultLayouts: SupportedLayouts;
selection?: string[];
setSelection?: SetSelection;
onSelectionChange?: ( items: Item[] ) => void;
Expand All @@ -65,7 +71,7 @@ export default function DataViews< Item >( {
getItemId = defaultGetItemId,
isLoading = false,
paginationInfo,
supportedLayouts,
defaultLayouts,
selection: selectionProperty,
setSelection: setSelectionProperty,
onSelectionChange = defaultOnSelectionChange,
Expand Down Expand Up @@ -142,7 +148,7 @@ export default function DataViews< Item >( {
fields={ _fields }
view={ view }
onChangeView={ onChangeView }
supportedLayouts={ supportedLayouts }
defaultLayouts={ defaultLayouts }
/>
</HStack>
<ViewComponent
Expand Down
2 changes: 1 addition & 1 deletion packages/dataviews/src/filter-and-sort-data-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export function filterSortAndPaginate< Item >(
} );
}

if ( view.filters?.length > 0 ) {
if ( view.filters && view.filters?.length > 0 ) {
view.filters.forEach( ( filter ) => {
const field = _fields.find(
( _field ) => _field.id === filter.field
Expand Down
30 changes: 18 additions & 12 deletions packages/dataviews/src/filter-summary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ function OperatorSelector( {
value: operator,
label: OPERATORS[ operator ]?.label,
} ) );
const currentFilter = view.filters.find(
const currentFilter = view.filters?.find(
( _filter ) => _filter.field === filter.field
);
const value = currentFilter?.operator || filter.operators[ 0 ];
Expand All @@ -180,18 +180,22 @@ function OperatorSelector( {
const operator = newValue as Operator;
const newFilters = currentFilter
? [
...view.filters.map( ( _filter ) => {
if ( _filter.field === filter.field ) {
return {
..._filter,
operator,
};
...( view.filters ?? [] ).map(
( _filter ) => {
if (
_filter.field === filter.field
) {
return {
..._filter,
operator,
};
}
return _filter;
}
return _filter;
} ),
),
]
: [
...view.filters,
...( view.filters ?? [] ),
{
field: filter.field,
operator,
Expand Down Expand Up @@ -220,7 +224,9 @@ export default function FilterSummary( {
}: FilterSummaryProps ) {
const toggleRef = useRef< HTMLDivElement >( null );
const { filter, view, onChangeView } = commonProps;
const filterInView = view.filters.find( ( f ) => f.field === filter.field );
const filterInView = view.filters?.find(
( f ) => f.field === filter.field
);
const activeElements = filter.elements.filter( ( element ) => {
if ( filter.singleSelection ) {
return element.value === filterInView?.value;
Expand Down Expand Up @@ -290,7 +296,7 @@ export default function FilterSummary( {
onChangeView( {
...view,
page: 1,
filters: view.filters.filter(
filters: view.filters?.filter(
( _filter ) =>
_filter.field !== filter.field
),
Expand Down
2 changes: 1 addition & 1 deletion packages/dataviews/src/filters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ function _Filters< Item >( {
operators,
isVisible:
isPrimary ||
view.filters.some(
!! view.filters?.some(
( f ) =>
f.field === field.id &&
ALL_OPERATORS.includes( f.operator )
Expand Down
12 changes: 6 additions & 6 deletions packages/dataviews/src/search-widget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ function ListBox( { view, filter, onChangeView }: SearchWidgetProps ) {
// so the first item is not selected, since the focus is on the operators control.
defaultActiveId: filter.operators?.length === 1 ? undefined : null,
} );
const currentFilter = view.filters.find(
const currentFilter = view.filters?.find(
( f ) => f.field === filter.field
);
const currentValue = getCurrentValue( filter, currentFilter );
Expand Down Expand Up @@ -130,7 +130,7 @@ function ListBox( { view, filter, onChangeView }: SearchWidgetProps ) {
onClick={ () => {
const newFilters = currentFilter
? [
...view.filters.map(
...( view.filters ?? [] ).map(
( _filter ) => {
if (
_filter.field ===
Expand All @@ -154,7 +154,7 @@ function ListBox( { view, filter, onChangeView }: SearchWidgetProps ) {
),
]
: [
...view.filters,
...( view.filters ?? [] ),
{
field: filter.field,
operator: filter.operators[ 0 ],
Expand Down Expand Up @@ -201,7 +201,7 @@ function ListBox( { view, filter, onChangeView }: SearchWidgetProps ) {
function ComboboxList( { view, filter, onChangeView }: SearchWidgetProps ) {
const [ searchValue, setSearchValue ] = useState( '' );
const deferredSearchValue = useDeferredValue( searchValue );
const currentFilter = view.filters.find(
const currentFilter = view.filters?.find(
( _filter ) => _filter.field === filter.field
);
const currentValue = getCurrentValue( filter, currentFilter );
Expand All @@ -218,7 +218,7 @@ function ComboboxList( { view, filter, onChangeView }: SearchWidgetProps ) {
setSelectedValue={ ( value ) => {
const newFilters = currentFilter
? [
...view.filters.map( ( _filter ) => {
...( view.filters ?? [] ).map( ( _filter ) => {
if ( _filter.field === filter.field ) {
return {
..._filter,
Expand All @@ -232,7 +232,7 @@ function ComboboxList( { view, filter, onChangeView }: SearchWidgetProps ) {
} ),
]
: [
...view.filters,
...( view.filters ?? [] ),
{
field: filter.field,
operator: filter.operators[ 0 ],
Expand Down
43 changes: 15 additions & 28 deletions packages/dataviews/src/stories/index.story.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* WordPress dependencies
*/
import { useState, useMemo, useCallback } from '@wordpress/element';
import { useState, useMemo } from '@wordpress/element';

/**
* Internal dependencies
Expand All @@ -17,48 +17,35 @@ const meta = {
};
export default meta;

const defaultConfigPerViewType = {
[ LAYOUT_TABLE ]: {
primaryField: 'title',
},
[ LAYOUT_GRID ]: {
mediaField: 'image',
primaryField: 'title',
},
};

export const Default = ( props ) => {
const [ view, setView ] = useState( DEFAULT_VIEW );
const { data: shownData, paginationInfo } = useMemo( () => {
return filterSortAndPaginate( data, view, fields );
}, [ view ] );
const onChangeView = useCallback(
( newView ) => {
if ( newView.type !== view.type ) {
newView = {
...newView,
layout: {
...defaultConfigPerViewType[ newView.type ],
},
};
}

setView( newView );
},
[ view.type, setView ]
);
return (
<DataViews
{ ...props }
paginationInfo={ paginationInfo }
data={ shownData }
view={ view }
fields={ fields }
onChangeView={ onChangeView }
onChangeView={ setView }
/>
);
};
Default.args = {
actions,
supportedLayouts: [ LAYOUT_TABLE, LAYOUT_GRID ],
defaultLayouts: {
[ LAYOUT_TABLE ]: {
layout: {
primaryField: 'title',
},
},
[ LAYOUT_GRID ]: {
layout: {
mediaField: 'image',
primaryField: 'title',
},
},
},
};
14 changes: 10 additions & 4 deletions packages/dataviews/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ interface ViewBase {
/**
* The filters to apply.
*/
filters: Filter[];
filters?: Filter[];

/**
* The sorting configuration.
Expand Down Expand Up @@ -257,7 +257,7 @@ interface ViewBase {
export interface ViewTable extends ViewBase {
type: 'table';

layout: {
layout?: {
/**
* The field to use as the primary field.
*/
Expand All @@ -273,7 +273,7 @@ export interface ViewTable extends ViewBase {
export interface ViewList extends ViewBase {
type: 'list';

layout: {
layout?: {
/**
* The field to use as the primary field.
*/
Expand All @@ -289,7 +289,7 @@ export interface ViewList extends ViewBase {
export interface ViewGrid extends ViewBase {
type: 'grid';

layout: {
layout?: {
/**
* The field to use as the primary field.
*/
Expand Down Expand Up @@ -429,3 +429,9 @@ export type ViewProps< Item > =
| ViewTableProps< Item >
| ViewGridProps< Item >
| ViewListProps< Item >;

export interface SupportedLayouts {
list?: Omit< ViewList, 'type' >;
grid?: Omit< ViewGrid, 'type' >;
table?: Omit< ViewTable, 'type' >;
}
Loading

0 comments on commit c1c46e6

Please sign in to comment.