Skip to content

Commit

Permalink
DataViews: Support combined fields (WordPress#63236)
Browse files Browse the repository at this point in the history
Co-authored-by: youknowriad <youknowriad@git.wordpress.org>
Co-authored-by: jameskoster <jameskoster@git.wordpress.org>
  • Loading branch information
3 people authored and carstingaxion committed Jul 18, 2024
1 parent 5335f34 commit 89dff42
Show file tree
Hide file tree
Showing 11 changed files with 327 additions and 147 deletions.
27 changes: 27 additions & 0 deletions packages/dataviews/src/layouts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import ViewTable from './view-table';
import ViewGrid from './view-grid';
import ViewList from './view-list';
import { LAYOUT_GRID, LAYOUT_LIST, LAYOUT_TABLE } from './constants';
import type { View } from './types';

export const VIEW_LAYOUTS = [
{
Expand All @@ -37,3 +38,29 @@ export const VIEW_LAYOUTS = [
icon: isRTL() ? formatListBulletsRTL : formatListBullets,
},
];

export function getMandatoryFields( view: View ): string[] {
if ( view.type === 'table' ) {
return [ view.layout?.primaryField ]
.concat(
view.layout?.combinedFields?.flatMap(
( field ) => field.children
) ?? []
)
.filter( ( item ): item is string => !! item );
}

if ( view.type === 'grid' ) {
return [ view.layout?.primaryField, view.layout?.mediaField ].filter(
( item ): item is string => !! item
);
}

if ( view.type === 'list' ) {
return [ view.layout?.primaryField, view.layout?.mediaField ].filter(
( item ): item is string => !! item
);
}

return [];
}
4 changes: 0 additions & 4 deletions packages/dataviews/src/stories/fixtures.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,20 +167,17 @@ export const fields = [
<img src={ item.image } alt="" style={ { width: '100%' } } />
);
},
width: 50,
enableSorting: false,
},
{
header: 'Title',
id: 'title',
maxWidth: 400,
enableHiding: false,
enableGlobalSearch: true,
},
{
header: 'Type',
id: 'type',
maxWidth: 400,
enableHiding: false,
elements: [
{ value: 'Not a planet', label: 'Not a planet' },
Expand All @@ -197,7 +194,6 @@ export const fields = [
{
header: 'Description',
id: 'description',
maxWidth: 200,
enableSorting: false,
enableGlobalSearch: true,
},
Expand Down
14 changes: 14 additions & 0 deletions packages/dataviews/src/stories/index.story.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,20 @@ Default.args = {
[ LAYOUT_TABLE ]: {
layout: {
primaryField: 'title',
styles: {
image: {
width: 50,
},
title: {
maxWidth: 400,
},
type: {
maxWidth: 400,
},
description: {
maxWidth: 200,
},
},
},
},
[ LAYOUT_GRID ]: {
Expand Down
6 changes: 5 additions & 1 deletion packages/dataviews/src/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@
padding: $grid-unit-15;
white-space: nowrap;

&[data-field-id="actions"] {
&.dataviews-view-table__actions-column {
text-align: right;
}

Expand Down Expand Up @@ -215,6 +215,10 @@
}
}
}

.components-v-stack > .dataviews-view-table__cell-content-wrapper:not(:first-child) {
min-height: 0;
}
}
.dataviews-view-table-header-button {
padding: $grid-unit-05 $grid-unit-10;
Expand Down
59 changes: 41 additions & 18 deletions packages/dataviews/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,21 +75,6 @@ export type Field< Item > = {
*/
render?: ( args: { item: Item } ) => ReactNode;

/**
* The width of the field column.
*/
width?: string | number;

/**
* The minimum width of the field column.
*/
maxWidth?: string | number;

/**
* The maximum width of the field column.
*/
minWidth?: string | number;

/**
* Whether the field is sortable.
*/
Expand Down Expand Up @@ -249,11 +234,44 @@ interface ViewBase {
perPage?: number;

/**
* The hidden fields.
* The fields to render
*/
fields?: string[];
}

export interface CombinedField {
id: string;

header: string;

/**
* The fields to use as columns.
*/
children: string[];

/**
* The direction of the stack.
*/
direction: 'horizontal' | 'vertical';
}

export interface ColumnStyle {
/**
* The width of the field column.
*/
width?: string | number;

/**
* The minimum width of the field column.
*/
maxWidth?: string | number;

/**
* The maximum width of the field column.
*/
minWidth?: string | number;
}

export interface ViewTable extends ViewBase {
type: 'table';

Expand All @@ -264,9 +282,14 @@ export interface ViewTable extends ViewBase {
primaryField?: string;

/**
* The field to use as the media field.
* The fields to use as columns.
*/
mediaField?: string;
combinedFields?: CombinedField[];

/**
* The styles for the columns.
*/
styles?: Record< string, ColumnStyle >;
};
}

Expand Down
5 changes: 3 additions & 2 deletions packages/dataviews/src/view-actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { cog } from '@wordpress/icons';
*/
import { unlock } from './lock-unlock';
import { SORTING_DIRECTIONS, sortLabels } from './constants';
import { VIEW_LAYOUTS } from './layouts';
import { VIEW_LAYOUTS, getMandatoryFields } from './layouts';
import type { NormalizedField, View, SupportedLayouts } from './types';

const {
Expand Down Expand Up @@ -147,10 +147,11 @@ function FieldsVisibilityMenu< Item >( {
onChangeView,
fields,
}: FieldsVisibilityMenuProps< Item > ) {
const mandatoryFields = getMandatoryFields( view );
const hidableFields = fields.filter(
( field ) =>
field.enableHiding !== false &&
field.id !== view?.layout?.mediaField
! mandatoryFields.includes( field.id )
);
const viewFields = view.fields || fields.map( ( field ) => field.id );
if ( ! hidableFields?.length ) {
Expand Down
Loading

0 comments on commit 89dff42

Please sign in to comment.