Skip to content

Commit 172a3bf

Browse files
authored
Merge pull request #10160 from marmelab/fix-datagrid-row-style-rowclick
Fix Datagrid row does not appear clickable although it is
2 parents 0b7dd0c + 3b6e171 commit 172a3bf

File tree

2 files changed

+127
-18
lines changed

2 files changed

+127
-18
lines changed

packages/ra-ui-materialui/src/list/datagrid/DatagridRow.spec.tsx

Lines changed: 122 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,15 @@ describe('<DatagridRow />', () => {
109109
</RecordContextProvider>
110110
</LocationSpy>
111111
);
112-
fireEvent.click(screen.getByText('hello'));
112+
const cell = screen.getByText('hello');
113+
const row = cell.closest('tr');
114+
if (!row) {
115+
throw new Error('row not found');
116+
}
117+
expect(
118+
row.classList.contains('RaDatagrid-clickableRow')
119+
).toBeTruthy();
120+
fireEvent.click(row);
113121

114122
await waitFor(() => {
115123
expect(spy).toHaveBeenCalledWith(
@@ -129,7 +137,16 @@ describe('<DatagridRow />', () => {
129137
</RecordContextProvider>
130138
</LocationSpy>
131139
);
132-
fireEvent.click(screen.getByText('hello'));
140+
const cell = screen.getByText('hello');
141+
const row = cell.closest('tr');
142+
if (!row) {
143+
throw new Error('row not found');
144+
}
145+
expect(
146+
row.classList.contains('RaDatagrid-clickableRow')
147+
).toBeTruthy();
148+
fireEvent.click(row);
149+
133150
await waitFor(() => {
134151
expect(spy).toHaveBeenCalledWith(
135152
expect.objectContaining({ pathname: '/posts/15/show' })
@@ -150,19 +167,27 @@ describe('<DatagridRow />', () => {
150167
</RecordContextProvider>
151168
);
152169
expect(screen.queryAllByText('expanded')).toHaveLength(0);
153-
fireEvent.click(screen.getByText('hello'));
170+
const cell = screen.getByText('hello');
171+
const row = cell.closest('tr');
172+
if (!row) {
173+
throw new Error('row not found');
174+
}
175+
expect(
176+
row.classList.contains('RaDatagrid-clickableRow')
177+
).toBeTruthy();
178+
fireEvent.click(row);
154179
await waitFor(() => {
155180
expect(screen.queryAllByText('expanded')).toHaveLength(1);
156181
});
157-
fireEvent.click(screen.getByText('hello'));
182+
fireEvent.click(row);
158183
await waitFor(() => {
159184
expect(screen.queryAllByText('expanded')).toHaveLength(0);
160185
});
161186
});
162187

163188
it("should execute the onToggleItem function if the 'toggleSelection' option is selected", async () => {
164189
const onToggleItem = jest.fn();
165-
const { getByText } = render(
190+
render(
166191
<RecordContextProvider value={defaultRecord}>
167192
<DatagridRow
168193
{...defaultProps}
@@ -173,15 +198,23 @@ describe('<DatagridRow />', () => {
173198
</DatagridRow>
174199
</RecordContextProvider>
175200
);
176-
fireEvent.click(getByText('hello'));
201+
const cell = screen.getByText('hello');
202+
const row = cell.closest('tr');
203+
if (!row) {
204+
throw new Error('row not found');
205+
}
206+
expect(
207+
row.classList.contains('RaDatagrid-clickableRow')
208+
).toBeTruthy();
209+
fireEvent.click(row);
177210
await waitFor(() => {
178211
expect(onToggleItem.mock.calls.length).toEqual(1);
179212
});
180213
});
181214

182215
it('should not execute the onToggleItem function if the row is not selectable', () => {
183216
const onToggleItem = jest.fn();
184-
const { getByText } = render(
217+
render(
185218
<RecordContextProvider value={defaultRecord}>
186219
<DatagridRow
187220
{...defaultProps}
@@ -193,7 +226,16 @@ describe('<DatagridRow />', () => {
193226
</DatagridRow>
194227
</RecordContextProvider>
195228
);
196-
fireEvent.click(getByText('hello'));
229+
const cell = screen.getByText('hello');
230+
const row = cell.closest('tr');
231+
if (!row) {
232+
throw new Error('row not found');
233+
}
234+
// FIXME ideally, the row style shouldn't show a pointer in this case
235+
expect(
236+
row.classList.contains('RaDatagrid-clickableRow')
237+
).toBeTruthy();
238+
fireEvent.click(row);
197239
expect(onToggleItem).not.toHaveBeenCalled();
198240
});
199241

@@ -209,7 +251,15 @@ describe('<DatagridRow />', () => {
209251
</RecordContextProvider>
210252
</LocationSpy>
211253
);
212-
fireEvent.click(screen.getByText('hello'));
254+
const cell = screen.getByText('hello');
255+
const row = cell.closest('tr');
256+
if (!row) {
257+
throw new Error('row not found');
258+
}
259+
expect(
260+
row.classList.contains('RaDatagrid-clickableRow')
261+
).toBeTruthy();
262+
fireEvent.click(row);
213263
await waitFor(() => {
214264
expect(spy).toHaveBeenCalledWith(
215265
expect.objectContaining({ pathname: path })
@@ -232,7 +282,15 @@ describe('<DatagridRow />', () => {
232282
</RecordContextProvider>
233283
</LocationSpy>
234284
);
235-
fireEvent.click(screen.getByText('hello'));
285+
const cell = screen.getByText('hello');
286+
const row = cell.closest('tr');
287+
if (!row) {
288+
throw new Error('row not found');
289+
}
290+
expect(
291+
row.classList.contains('RaDatagrid-clickableRow')
292+
).toBeTruthy();
293+
fireEvent.click(row);
236294
await new Promise(resolve => setTimeout(resolve)); // waitFor one tick
237295
await waitFor(() => {
238296
expect(spy).toHaveBeenCalledWith(
@@ -252,7 +310,15 @@ describe('<DatagridRow />', () => {
252310
</RecordContextProvider>
253311
</LocationSpy>
254312
);
255-
fireEvent.click(screen.getByText('hello'));
313+
const cell = screen.getByText('hello');
314+
const row = cell.closest('tr');
315+
if (!row) {
316+
throw new Error('row not found');
317+
}
318+
expect(
319+
row.classList.contains('RaDatagrid-clickableRow')
320+
).toBeFalsy();
321+
fireEvent.click(row);
256322
expect(spy).toHaveBeenCalledWith(
257323
expect.objectContaining({ pathname: '/' })
258324
);
@@ -269,7 +335,15 @@ describe('<DatagridRow />', () => {
269335
</RecordContextProvider>
270336
</LocationSpy>
271337
);
272-
fireEvent.click(screen.getByText('hello'));
338+
const cell = screen.getByText('hello');
339+
const row = cell.closest('tr');
340+
if (!row) {
341+
throw new Error('row not found');
342+
}
343+
expect(
344+
row.classList.contains('RaDatagrid-clickableRow')
345+
).toBeFalsy();
346+
fireEvent.click(row);
273347
expect(spy).toHaveBeenCalledWith(
274348
expect.objectContaining({ pathname: '/' })
275349
);
@@ -292,7 +366,15 @@ describe('<DatagridRow />', () => {
292366
</ResourceDefinitionContextProvider>
293367
</LocationSpy>
294368
);
295-
fireEvent.click(screen.getByText('hello'));
369+
const cell = screen.getByText('hello');
370+
const row = cell.closest('tr');
371+
if (!row) {
372+
throw new Error('row not found');
373+
}
374+
expect(
375+
row.classList.contains('RaDatagrid-clickableRow')
376+
).toBeTruthy();
377+
fireEvent.click(row);
296378
await waitFor(() => {
297379
expect(spy).toHaveBeenCalledWith(
298380
expect.objectContaining({ pathname: '/posts/15' })
@@ -317,7 +399,15 @@ describe('<DatagridRow />', () => {
317399
</ResourceDefinitionContextProvider>
318400
</LocationSpy>
319401
);
320-
fireEvent.click(screen.getByText('hello'));
402+
const cell = screen.getByText('hello');
403+
const row = cell.closest('tr');
404+
if (!row) {
405+
throw new Error('row not found');
406+
}
407+
expect(
408+
row.classList.contains('RaDatagrid-clickableRow')
409+
).toBeTruthy();
410+
fireEvent.click(row);
321411
await waitFor(() => {
322412
expect(spy).toHaveBeenCalledWith(
323413
expect.objectContaining({ pathname: '/posts/15/show' })
@@ -346,7 +436,15 @@ describe('<DatagridRow />', () => {
346436
</ResourceDefinitionContextProvider>
347437
</LocationSpy>
348438
);
349-
fireEvent.click(screen.getByText('hello'));
439+
const cell = screen.getByText('hello');
440+
const row = cell.closest('tr');
441+
if (!row) {
442+
throw new Error('row not found');
443+
}
444+
expect(
445+
row.classList.contains('RaDatagrid-clickableRow')
446+
).toBeTruthy();
447+
fireEvent.click(row);
350448
await waitFor(() => {
351449
expect(spy).toHaveBeenCalledWith(
352450
expect.objectContaining({ pathname: '/posts/15/show' })
@@ -374,7 +472,15 @@ describe('<DatagridRow />', () => {
374472
</ResourceDefinitionContextProvider>
375473
</LocationSpy>
376474
);
377-
fireEvent.click(screen.getByText('hello'));
475+
const cell = screen.getByText('hello');
476+
const row = cell.closest('tr');
477+
if (!row) {
478+
throw new Error('row not found');
479+
}
480+
expect(
481+
row.classList.contains('RaDatagrid-clickableRow')
482+
).toBeFalsy();
483+
fireEvent.click(row);
378484
expect(spy).toHaveBeenCalledWith(
379485
expect.objectContaining({ pathname: '/' })
380486
);

packages/ra-ui-materialui/src/list/datagrid/DatagridRow.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
useTranslate,
2020
useRecordContext,
2121
useGetPathForRecordCallback,
22+
useResourceDefinition,
2223
} from 'ra-core';
2324
import { useNavigate } from 'react-router-dom';
2425

@@ -65,6 +66,9 @@ const DatagridRow: React.ForwardRefExoticComponent<
6566
);
6667
}
6768
const resource = useResourceContext(props);
69+
const resourceDefinition = useResourceDefinition(props);
70+
const hasDetailView =
71+
resourceDefinition.hasShow || resourceDefinition.hasEdit;
6872
if (!resource) {
6973
throw new Error(
7074
'DatagridRow can only be used within a ResourceContext or be passed a resource prop'
@@ -162,8 +166,7 @@ const DatagridRow: React.ForwardRefExoticComponent<
162166
className={clsx(className, {
163167
[DatagridClasses.expandable]: expandable,
164168
[DatagridClasses.selectable]: selectable,
165-
[DatagridClasses.clickableRow]:
166-
typeof rowClick === 'function' ? true : rowClick,
169+
[DatagridClasses.clickableRow]: rowClick ?? hasDetailView,
167170
})}
168171
key={id}
169172
style={style}

0 commit comments

Comments
 (0)