Skip to content

Commit

Permalink
Fix TS check failures in Datagrid
Browse files Browse the repository at this point in the history
  • Loading branch information
fzaninotto committed Apr 9, 2024
1 parent bb3bd8b commit e9b4b6c
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 142 deletions.
6 changes: 3 additions & 3 deletions packages/ra-ui-materialui/src/list/datagrid/Datagrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ export const Datagrid: FC<DatagridProps> = React.forwardRef((props, ref) => {
// we manage row selection at the datagrid level to allow shift+click to select an array of rows
const handleToggleItem = useCallback(
(id, event) => {
if (!data) return;
const ids = data.map(record => record.id);
const lastSelectedIndex = ids.indexOf(lastSelected.current);
lastSelected.current = event.target.checked ? id : null;
Expand All @@ -182,7 +183,7 @@ export const Datagrid: FC<DatagridProps> = React.forwardRef((props, ref) => {
? union(selectedIds, idsBetweenSelections)
: difference(selectedIds, idsBetweenSelections);

onSelect(
onSelect?.(
isRowSelectable
? newSelectedIds.filter((id: Identifier) =>
isRowSelectable(
Expand All @@ -192,7 +193,7 @@ export const Datagrid: FC<DatagridProps> = React.forwardRef((props, ref) => {
: newSelectedIds
);
} else {
onToggleItem(id);
onToggleItem?.(id);
}
},
[data, isRowSelectable, onSelect, onToggleItem, selectedIds]
Expand Down Expand Up @@ -259,7 +260,6 @@ export const Datagrid: FC<DatagridProps> = React.forwardRef((props, ref) => {
hasBulkActions,
isRowSelectable,
onSelect,
resource,
selectedIds,
setSort,
},
Expand Down
26 changes: 11 additions & 15 deletions packages/ra-ui-materialui/src/list/datagrid/DatagridHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { Children, isValidElement, useCallback } from 'react';
import PropTypes from 'prop-types';
import {
useListContextWithProps,
useResourceContext,
Identifier,
RaRecord,
SortPayload,
Expand All @@ -30,7 +29,6 @@ export const DatagridHeader = (props: DatagridHeaderProps) => {
hasBulkActions = false,
isRowSelectable,
} = props;
const resource = useResourceContext(props);
const translate = useTranslate();
const {
sort,
Expand All @@ -44,23 +42,24 @@ export const DatagridHeader = (props: DatagridHeaderProps) => {
const updateSortCallback = useCallback(
event => {
event.stopPropagation();
if (!setSort) return;
const newField = event.currentTarget.dataset.field;
const newOrder =
sort.field === newField
? sort.order === 'ASC'
sort?.field === newField
? sort?.order === 'ASC'
? 'DESC'
: 'ASC'
: event.currentTarget.dataset.order;

setSort({ field: newField, order: newOrder });
},
[sort.field, sort.order, setSort]
[sort?.field, sort?.order, setSort]
);

const updateSort = setSort ? updateSortCallback : null;

const handleSelectAll = useCallback(
event =>
event => {
if (!onSelect || !selectedIds || !data) return;
onSelect(
event.target.checked
? selectedIds.concat(
Expand All @@ -76,7 +75,8 @@ export const DatagridHeader = (props: DatagridHeaderProps) => {
.map(record => record.id)
)
: []
),
);
},
[data, onSelect, isRowSelectable, selectedIds]
);

Expand All @@ -101,9 +101,8 @@ export const DatagridHeader = (props: DatagridHeaderProps) => {
DatagridClasses.expandHeader
)}
>
{!expandSingle ? (
{!expandSingle && data ? (
<ExpandAllButton
resource={resource}
ids={data.map(record => record.id)}
/>
) : null}
Expand Down Expand Up @@ -142,13 +141,12 @@ export const DatagridHeader = (props: DatagridHeaderProps) => {
sort={sort}
field={field}
isSorting={
sort.field ===
sort?.field ===
((field.props as any).sortBy ||
(field.props as any).source)
}
key={(field.props as any).source || index}
resource={resource}
updateSort={updateSort}
updateSort={updateSort || undefined}
/>
) : null
)}
Expand All @@ -171,7 +169,6 @@ DatagridHeader.propTypes = {
isRowExpandable: PropTypes.func,
onSelect: PropTypes.func,
onToggleItem: PropTypes.func,
resource: PropTypes.string,
selectedIds: PropTypes.arrayOf(PropTypes.any),
setSort: PropTypes.func,
};
Expand All @@ -189,7 +186,6 @@ export interface DatagridHeaderProps<RecordType extends RaRecord = any> {
data?: RecordType[];
onSelect?: (ids: Identifier[]) => void;
onToggleItem?: (id: Identifier) => void;
resource?: string;
selectedIds?: Identifier[];
setSort?: (sort: SortPayload) => void;
}
Expand Down
171 changes: 70 additions & 101 deletions packages/ra-ui-materialui/src/list/datagrid/DatagridHeaderCell.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,19 @@ import * as React from 'react';
import { render } from '@testing-library/react';

import { DatagridHeaderCell } from './DatagridHeaderCell';
import { ResourceContextProvider } from 'ra-core';

const Wrapper = ({ children }) => (
<table>
<tbody>
<tr>
<ResourceContextProvider value="posts">
{children}
</ResourceContextProvider>
</tr>
</tbody>
</table>
);

describe('<DatagridHeaderCell />', () => {
it('should accept a React element as Field label', () => {
Expand All @@ -12,18 +25,13 @@ describe('<DatagridHeaderCell />', () => {
label?: React.ReactNode;
}) => <div />;
const { getByText } = render(
<table>
<tbody>
<tr>
<DatagridHeaderCell
resource="posts"
sort={{ field: 'title', order: 'ASC' }}
field={<Field source="title" label={<Label />} />}
updateSort={() => true}
/>
</tr>
</tbody>
</table>
<Wrapper>
<DatagridHeaderCell
sort={{ field: 'title', order: 'ASC' }}
field={<Field source="title" label={<Label />} />}
updateSort={() => true}
/>
</Wrapper>
);
expect(getByText('Label')).not.toBeNull();
});
Expand All @@ -43,18 +51,13 @@ describe('<DatagridHeaderCell />', () => {

it('should be enabled when field has a source', () => {
const { getByLabelText } = render(
<table>
<tbody>
<tr>
<DatagridHeaderCell
resource="posts"
sort={{ field: 'title', order: 'ASC' }}
field={<Field source="title" />}
updateSort={() => true}
/>
</tr>
</tbody>
</table>
<Wrapper>
<DatagridHeaderCell
sort={{ field: 'title', order: 'ASC' }}
field={<Field source="title" />}
updateSort={() => true}
/>
</Wrapper>
);
expect(getByLabelText('ra.action.sort').dataset.field).toBe(
'title'
Expand All @@ -63,18 +66,13 @@ describe('<DatagridHeaderCell />', () => {

it('should be enabled when field has a sortBy props', () => {
const { getByLabelText } = render(
<table>
<tbody>
<tr>
<DatagridHeaderCell
resource="posts"
sort={{ field: 'title', order: 'ASC' }}
field={<Field sortBy="title" />}
updateSort={() => true}
/>
</tr>
</tbody>
</table>
<Wrapper>
<DatagridHeaderCell
sort={{ field: 'title', order: 'ASC' }}
field={<Field sortBy="title" />}
updateSort={() => true}
/>
</Wrapper>
);
expect(getByLabelText('ra.action.sort').dataset.field).toBe(
'title'
Expand All @@ -83,95 +81,66 @@ describe('<DatagridHeaderCell />', () => {

it('should be change order when field has a sortByOrder props', () => {
const { getByLabelText } = render(
<table>
<tbody>
<tr>
<DatagridHeaderCell
resource="posts"
sort={{ field: 'title', order: 'ASC' }}
field={
<Field sortBy="title" sortByOrder="DESC" />
}
updateSort={() => true}
/>
</tr>
</tbody>
</table>
<Wrapper>
<DatagridHeaderCell
sort={{ field: 'title', order: 'ASC' }}
field={<Field sortBy="title" sortByOrder="DESC" />}
updateSort={() => true}
/>
</Wrapper>
);
expect(getByLabelText('ra.action.sort').dataset.order).toBe('DESC');
});

it('should be keep ASC order when field has not sortByOrder props', () => {
const { getByLabelText } = render(
<table>
<tbody>
<tr>
<DatagridHeaderCell
resource="posts"
sort={{ field: 'title', order: 'ASC' }}
field={<Field source="title" />}
updateSort={() => true}
/>
</tr>
</tbody>
</table>
<Wrapper>
<DatagridHeaderCell
sort={{ field: 'title', order: 'ASC' }}
field={<Field source="title" />}
updateSort={() => true}
/>
</Wrapper>
);
expect(getByLabelText('ra.action.sort').dataset.order).toBe('ASC');
});

it('should be disabled when field has no sortBy and no source', () => {
const { queryAllByLabelText } = render(
<table>
<tbody>
<tr>
<DatagridHeaderCell
resource="posts"
sort={{ field: 'title', order: 'ASC' }}
field={<Field />}
updateSort={() => true}
/>
</tr>
</tbody>
</table>
<Wrapper>
<DatagridHeaderCell
sort={{ field: 'title', order: 'ASC' }}
field={<Field />}
updateSort={() => true}
/>
</Wrapper>
);
expect(queryAllByLabelText('ra.action.sort')).toHaveLength(0);
});

it('should be disabled when sortable prop is explicitly set to false', () => {
const { queryAllByLabelText } = render(
<table>
<tbody>
<tr>
<DatagridHeaderCell
resource="posts"
sort={{ field: 'title', order: 'ASC' }}
field={
<Field source="title" sortable={false} />
}
updateSort={() => true}
/>
</tr>
</tbody>
</table>
<Wrapper>
<DatagridHeaderCell
sort={{ field: 'title', order: 'ASC' }}
field={<Field source="title" sortable={false} />}
updateSort={() => true}
/>
</Wrapper>
);
expect(queryAllByLabelText('ra.action.sort')).toHaveLength(0);
});

it('should use cell className if specified', () => {
const { container } = render(
<table>
<tbody>
<tr>
<DatagridHeaderCell
resource="posts"
sort={{ field: 'title', order: 'ASC' }}
updateSort={() => true}
field={<Field />}
className="blue"
/>
</tr>
</tbody>
</table>
<Wrapper>
<DatagridHeaderCell
sort={{ field: 'title', order: 'ASC' }}
updateSort={() => true}
field={<Field />}
className="blue"
/>
</Wrapper>
);
expect(container.querySelector('td')?.className).toContain('blue');
});
Expand Down
Loading

0 comments on commit e9b4b6c

Please sign in to comment.