Skip to content

Commit f2fc70f

Browse files
committed
Improve doc and stories about facets
1 parent 8517141 commit f2fc70f

File tree

4 files changed

+124
-59
lines changed

4 files changed

+124
-59
lines changed

docs/List.md

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,37 +1144,58 @@ const ProductList = () => (
11441144

11451145
If `dataProvider.getList()` returns additional metadata in the response under the `meta` key, you can access it in the list view using the `meta` property of the `ListContext`.
11461146

1147-
This is often used by APIs to return statistics or other metadata about the list of records.
1147+
![List metadata](./img/List-facets.png)
1148+
1149+
This is often used by APIs to return facets, aggregations, statistics, or other metadata about the list of records.
11481150

11491151
```tsx
1150-
// dataProvider.getLists('posts') returns response like
1152+
// dataProvider.getLists('books') returns response like
11511153
// {
11521154
// data: [ ... ],
11531155
// total: 293,
11541156
// meta: {
1155-
// facets: [
1156-
// { value: 'Novels', count: 245 },
1157-
// { value: 'Essays', count: 23 },
1158-
// { value: 'Short stories', count: 25 },
1157+
// genres: [
1158+
// { value: 'Fictions', count: 134 },
1159+
// { value: 'Essays', count: 24 },
1160+
// ],
1161+
// centuries: [
1162+
// { value: '18th', count: 23 },
1163+
// { value: '19th', count: 78 },
1164+
// { value: '20th', count: 57 },
1165+
// { value: '21st', count: 34 },
11591166
// ],
11601167
// },
11611168
// }
11621169
const Facets = () => {
11631170
const { isLoading, error, meta } = useListContext();
11641171
if (isLoading || error) return null;
1165-
const facets = meta.facets;
11661172
return (
1167-
<Stack direction="row" gap={3} mt={2} ml={1}>
1168-
{facets.map(facet => (
1169-
<Badge
1170-
key={facet.value}
1171-
badgeContent={facet.count}
1172-
color="primary"
1173-
>
1174-
<Chip label={facet.value} size="small" />
1175-
</Badge>
1176-
))}
1177-
</Stack>
1173+
<Box>
1174+
<Typography variant="subtitle2">
1175+
Genres
1176+
</Typography>
1177+
<Typography component="ul">
1178+
{meta.genres.map(facet => (
1179+
<li key={facet.value}>
1180+
<Link href="#">
1181+
{facet.value} ({facet.count})
1182+
</Link>
1183+
</li>
1184+
))}
1185+
</Typography>
1186+
<Typography variant="subtitle2">
1187+
Century
1188+
</Typography>
1189+
<Typography component="ul">
1190+
{meta.centuries.map(facet => (
1191+
<li key={facet.value}>
1192+
<Link href="#">
1193+
{facet.value} ({facet.count})
1194+
</Link>
1195+
</li>
1196+
))}
1197+
</Typography>
1198+
</Box>
11781199
);
11791200
};
11801201
```

docs/img/List-facets.png

227 KB
Loading

packages/ra-ui-materialui/src/list/List.spec.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -296,25 +296,25 @@ describe('<List />', () => {
296296
describe('title', () => {
297297
it('should display by default the title of the resource', async () => {
298298
render(<Basic />);
299-
await screen.findByText('War and Peace');
299+
await screen.findByText('War and Peace (1869)');
300300
screen.getAllByText('Books');
301301
});
302302

303303
it('should render custom title string when defined', async () => {
304304
render(<Title />);
305-
await screen.findByText('War and Peace');
305+
await screen.findByText('War and Peace (1869)');
306306
screen.getByText('Custom list title');
307307
});
308308

309309
it('should render custom title element when defined', async () => {
310310
render(<TitleElement />);
311-
await screen.findByText('War and Peace');
311+
await screen.findByText('War and Peace (1869)');
312312
screen.getByText('Custom list title');
313313
});
314314

315315
it('should not render default title when false', async () => {
316316
render(<TitleFalse />);
317-
await screen.findByText('War and Peace');
317+
await screen.findByText('War and Peace (1869)');
318318
screen.getByText('Books');
319319
});
320320
});

packages/ra-ui-materialui/src/list/List.stories.tsx

Lines changed: 81 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,10 @@ import {
77
TestMemoryRouter,
88
} from 'ra-core';
99
import fakeRestDataProvider from 'ra-data-fakerest';
10-
import {
11-
Box,
12-
Card,
13-
Stack,
14-
Typography,
15-
Button,
16-
Badge,
17-
Chip,
18-
} from '@mui/material';
10+
import { Box, Card, Typography, Button, Link as MuiLink } from '@mui/material';
1911

2012
import { List } from './List';
13+
import { SimpleList } from './SimpleList';
2114
import { ListActions } from './ListActions';
2215
import { Datagrid } from './datagrid';
2316
import { TextField } from '../field';
@@ -37,100 +30,125 @@ const data = {
3730
title: 'War and Peace',
3831
author: 'Leo Tolstoy',
3932
year: 1869,
33+
summary:
34+
'A historical novel that intertwines the lives of Russian aristocrats with the events of the Napoleonic wars.',
4035
},
4136
{
4237
id: 2,
43-
title: 'Pride and Predjudice',
38+
title: 'Pride and Prejudice',
4439
author: 'Jane Austen',
4540
year: 1813,
41+
summary:
42+
'A romantic novel exploring the themes of class, family, and societal expectations through the story of Elizabeth Bennet and Mr. Darcy.',
4643
},
4744
{
4845
id: 3,
4946
title: 'The Picture of Dorian Gray',
5047
author: 'Oscar Wilde',
5148
year: 1890,
49+
summary:
50+
'A philosophical tale about a man who remains youthful while a portrait of him ages, reflecting his moral corruption.',
5251
},
5352
{
5453
id: 4,
5554
title: 'Le Petit Prince',
5655
author: 'Antoine de Saint-Exupéry',
5756
year: 1943,
57+
summary:
58+
'A poetic and philosophical story about a young prince’s journey across planets, exploring themes of innocence and human nature.',
5859
},
5960
{
6061
id: 5,
6162
title: "Alice's Adventures in Wonderland",
6263
author: 'Lewis Carroll',
6364
year: 1865,
65+
summary:
66+
'A fantasy tale where Alice falls into a whimsical world, encountering strange creatures and exploring absurd adventures.',
6467
},
6568
{
6669
id: 6,
6770
title: 'Madame Bovary',
6871
author: 'Gustave Flaubert',
6972
year: 1856,
73+
summary:
74+
'A story of a dissatisfied woman trapped in provincial life, leading her to pursue romantic fantasies with tragic consequences.',
7075
},
7176
{
7277
id: 7,
7378
title: 'The Lord of the Rings',
7479
author: 'J. R. R. Tolkien',
7580
year: 1954,
81+
summary:
82+
'An epic fantasy novel following a group of heroes as they attempt to destroy a powerful ring and defeat the dark lord Sauron.',
7683
},
7784
{
7885
id: 8,
7986
title: "Harry Potter and the Philosopher's Stone",
8087
author: 'J. K. Rowling',
8188
year: 1997,
89+
summary:
90+
'The beginning of Harry Potter’s magical journey at Hogwarts, where he uncovers secrets about his past and faces dark forces.',
8291
},
8392
{
8493
id: 9,
8594
title: 'The Alchemist',
8695
author: 'Paulo Coelho',
8796
year: 1988,
97+
summary:
98+
'A spiritual novel that follows a young shepherd on a journey to find treasure, exploring themes of destiny and self-discovery.',
8899
},
89100
{
90101
id: 10,
91-
title: 'A Catcher in the Rye',
102+
title: 'The Catcher in the Rye',
92103
author: 'J. D. Salinger',
93104
year: 1951,
105+
summary:
106+
'A coming-of-age story about Holden Caulfield, a rebellious teenager navigating feelings of alienation and identity in post-war America.',
94107
},
95108
{
96109
id: 11,
97110
title: 'Ulysses',
98111
author: 'James Joyce',
99112
year: 1922,
113+
summary:
114+
'A modernist novel that chronicles the experiences of Leopold Bloom in Dublin, reflecting the complexity of human thought and life.',
100115
},
101116
{
102117
id: 12,
103118
title: 'One Hundred Years of Solitude',
104119
author: 'Gabriel García Márquez',
105120
year: 1967,
121+
summary:
122+
'A multi-generational tale of the Buendía family, blending reality and magic in the fictional town of Macondo.',
106123
},
107124
{
108125
id: 13,
109126
title: 'Snow Country',
110127
author: 'Yasunari Kawabata',
111128
year: 1956,
129+
summary:
130+
'A tragic love story set in Japan’s remote snowy regions, exploring beauty, isolation, and fleeting relationships.',
112131
},
113132
],
114133
authors: [],
115134
};
135+
116136
const dataProvider = fakeRestDataProvider(data);
117137

118138
const BookList = () => {
119-
const { data, error, isPending } = useListContext();
139+
const { error, isPending } = useListContext();
120140
if (isPending) {
121141
return <div>Loading...</div>;
122142
}
123143
if (error) {
124144
return <div>Error: {error.message}</div>;
125145
}
126146
return (
127-
<Stack spacing={2} sx={{ padding: 2 }}>
128-
{data.map(book => (
129-
<Typography key={book.id}>
130-
<i>{book.title}</i>, by {book.author} ({book.year})
131-
</Typography>
132-
))}
133-
</Stack>
147+
<SimpleList
148+
primaryText="%{title} (%{year})"
149+
secondaryText="%{summary}"
150+
tertiaryText={record => record.year}
151+
/>
134152
);
135153
};
136154

@@ -610,19 +628,41 @@ export const ErrorInFetch = () => (
610628
const Facets = () => {
611629
const { isLoading, error, meta } = useListContext();
612630
if (isLoading || error) return null;
613-
const facets = meta.facets;
614631
return (
615-
<Stack direction="row" gap={3} mt={2} ml={1}>
616-
{facets.map(facet => (
617-
<Badge
618-
key={facet.value}
619-
badgeContent={facet.count}
620-
color="primary"
621-
>
622-
<Chip label={facet.value} size="small" />
623-
</Badge>
624-
))}
625-
</Stack>
632+
<Box order={-1} width={200} mt={7}>
633+
<Typography variant="subtitle2" gutterBottom>
634+
Genres
635+
</Typography>
636+
<Typography
637+
component="ul"
638+
p={0}
639+
sx={{ listStylePosition: 'inside' }}
640+
>
641+
{meta.genres.map(facet => (
642+
<li key={facet.value}>
643+
<MuiLink href="#">
644+
{facet.value} ({facet.count})
645+
</MuiLink>
646+
</li>
647+
))}
648+
</Typography>
649+
<Typography variant="subtitle2" gutterBottom mt={2}>
650+
Century
651+
</Typography>
652+
<Typography
653+
component="ul"
654+
p={0}
655+
sx={{ listStylePosition: 'inside' }}
656+
>
657+
{meta.centuries.map(facet => (
658+
<li key={facet.value}>
659+
<MuiLink href="#">
660+
{facet.value} ({facet.count})
661+
</MuiLink>
662+
</li>
663+
))}
664+
</Typography>
665+
</Box>
626666
);
627667
};
628668
export const ResponseMetadata = () => (
@@ -635,10 +675,15 @@ export const ResponseMetadata = () => (
635675
return {
636676
...result,
637677
meta: {
638-
facets: [
639-
{ value: 'Novels', count: 13 },
640-
{ value: 'Essays', count: 0 },
641-
{ value: 'Short stories', count: 0 },
678+
genres: [
679+
{ value: 'Fictions', count: 168 },
680+
{ value: 'Essays', count: 24 },
681+
],
682+
centuries: [
683+
{ value: '18th', count: 23 },
684+
{ value: '19th', count: 78 },
685+
{ value: '20th', count: 57 },
686+
{ value: '21st', count: 34 },
642687
],
643688
},
644689
};
@@ -648,8 +693,7 @@ export const ResponseMetadata = () => (
648693
<Resource
649694
name="books"
650695
list={
651-
<List>
652-
<Facets />
696+
<List aside={<Facets />}>
653697
<BookList />
654698
</List>
655699
}

0 commit comments

Comments
 (0)