Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to pass a tab count in <TabbedForm.Tab> and <TabbedShowLayout.Tab> #8543

Merged
merged 2 commits into from
Jan 5, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/TabbedForm.md
Original file line number Diff line number Diff line change
Expand Up @@ -471,10 +471,11 @@ export const TagEdit = () => (

## `<TabbedForm.Tab>`

`<TabbedForm>` expect `<TabbedForm.Tab>` elements as children. `<TabbedForm.Tab>` elements accept four props:
`<TabbedForm>` expect `<TabbedForm.Tab>` elements as children. `<TabbedForm.Tab>` elements accept five props:

- `label`: the label of the tab
- `path`: the path of the tab in the URL (ignored when `syncWithLocation={false}`)
- `count`: the number of items in the tab (dislayed close to the label)
- `sx`: custom styles to apply to the tab
- `children`: the content of the tab (usually a list of inputs)

Expand Down
1 change: 1 addition & 0 deletions docs/TabbedShowLayout.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ It accepts the following props:
- `label`: The string displayed for each tab
- `icon`: The icon to show before the label (optional). Must be a component.
- `path`: The string used for custom urls (optional)
- `count`: the number of items in the tab (dislayed close to the label)

```jsx
// in src/posts.js
Expand Down
37 changes: 9 additions & 28 deletions examples/demo/src/orders/OrderList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Fragment, useCallback } from 'react';
import {
AutocompleteInput,
BooleanField,
Count,
DatagridConfigurable,
DateField,
DateInput,
Expand Down Expand Up @@ -72,37 +73,12 @@ const tabs = [
{ id: 'cancelled', name: 'cancelled' },
];

const useGetTotals = (filterValues: any) => {
const { total: totalOrdered } = useGetList('commands', {
fzaninotto marked this conversation as resolved.
Show resolved Hide resolved
pagination: { perPage: 1, page: 1 },
sort: { field: 'id', order: 'ASC' },
filter: { ...filterValues, status: 'ordered' },
});
const { total: totalDelivered } = useGetList('commands', {
pagination: { perPage: 1, page: 1 },
sort: { field: 'id', order: 'ASC' },
filter: { ...filterValues, status: 'delivered' },
});
const { total: totalCancelled } = useGetList('commands', {
pagination: { perPage: 1, page: 1 },
sort: { field: 'id', order: 'ASC' },
filter: { ...filterValues, status: 'cancelled' },
});

return {
ordered: totalOrdered,
delivered: totalDelivered,
cancelled: totalCancelled,
};
};

const TabbedDatagrid = () => {
const listContext = useListContext();
const { filterValues, setFilters, displayedFilters } = listContext;
const isXSmall = useMediaQuery<Theme>(theme =>
theme.breakpoints.down('sm')
);
const totals = useGetTotals(filterValues) as any;

const handleChange = useCallback(
(event: React.ChangeEvent<{}>, value: any) => {
Expand All @@ -129,9 +105,14 @@ const TabbedDatagrid = () => {
<Tab
key={choice.id}
label={
totals[choice.name]
? `${choice.name} (${totals[choice.name]})`
: choice.name
<span>
{choice.name} (
<Count
filter={{ status: choice.name }}
fzaninotto marked this conversation as resolved.
Show resolved Hide resolved
sx={{ lineHeight: 'inherit' }}
/>
)
</span>
}
value={choice.id}
/>
Expand Down
39 changes: 13 additions & 26 deletions examples/demo/src/products/ProductEdit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@ import {
EditButton,
Pagination,
ReferenceManyField,
ReferenceManyCount,
required,
TabbedForm,
TextField,
TextInput,
useRecordContext,
useGetManyReference,
useTranslate,
} from 'react-admin';
import { RichTextInput } from 'ra-input-rich-text';

Expand Down Expand Up @@ -52,7 +51,17 @@ const ProductEdit = () => (
>
<RichTextInput source="description" label="" validate={req} />
</TabbedForm.Tab>
<ReviewsFormTab path="reviews">
<TabbedForm.Tab
label="resources.products.tabs.reviews"
count={
<ReferenceManyCount
reference="reviews"
target="product_id"
sx={{ lineHeight: 'inherit' }}
/>
}
path="reviews"
>
<ReferenceManyField
reference="reviews"
target="product_id"
Expand All @@ -77,33 +86,11 @@ const ProductEdit = () => (
<EditButton />
</Datagrid>
</ReferenceManyField>
</ReviewsFormTab>
</TabbedForm.Tab>
</TabbedForm>
</Edit>
);

const req = [required()];

const ReviewsFormTab = (props: any) => {
const record = useRecordContext();
const { isLoading, total } = useGetManyReference(
'reviews',
{
target: 'product_id',
id: record.id,
pagination: { page: 1, perPage: 25 },
sort: { field: 'id', order: 'DESC' },
},
{
enabled: !!record,
}
);
const translate = useTranslate();
let label = translate('resources.products.tabs.reviews');
if (!isLoading) {
label += ` (${total})`;
}
return <TabbedForm.Tab label={label} {...props} />;
};

export default ProductEdit;
12 changes: 11 additions & 1 deletion examples/simple/src/posts/PostEdit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
ImageInput,
NumberInput,
ReferenceManyField,
ReferenceManyCount,
ReferenceInput,
SelectInput,
SimpleFormIterator,
Expand Down Expand Up @@ -239,7 +240,16 @@ const PostEdit = () => {
</SimpleFormIterator>
</ArrayInput>
</TabbedForm.Tab>
<TabbedForm.Tab label="post.form.comments">
<TabbedForm.Tab
label="post.form.comments"
count={
<ReferenceManyCount
reference="comments"
target="post_id"
sx={{ lineHeight: 'inherit' }}
/>
}
>
<ReferenceManyField
reference="comments"
target="post_id"
Expand Down
12 changes: 11 additions & 1 deletion examples/simple/src/posts/PostShow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
NumberField,
ReferenceArrayField,
ReferenceManyField,
ReferenceManyCount,
RichTextField,
SelectField,
ShowContextProvider,
Expand Down Expand Up @@ -87,7 +88,16 @@ const PostShow = () => {
<TextField source="views" />
<CloneButton />
</TabbedShowLayout.Tab>
<TabbedShowLayout.Tab label="post.form.comments">
<TabbedShowLayout.Tab
label="post.form.comments"
count={
<ReferenceManyCount
reference="comments"
target="post_id"
sx={{ lineHeight: 'inherit' }}
/>
}
>
<ReferenceManyField
reference="comments"
target="post_id"
Expand Down
43 changes: 27 additions & 16 deletions packages/ra-ui-materialui/src/detail/Tab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export const Tab = ({
children,
contentClassName,
context,
count,
className,
divider,
icon,
Expand All @@ -75,21 +76,29 @@ export const Tab = ({
to: { ...location, pathname: value },
};

const renderHeader = () => (
<MuiTab
key={`tab-header-${value}`}
label={
typeof label === 'string'
? translate(label, { _: label })
: label
}
value={value}
icon={icon}
className={clsx('show-tab', className)}
{...(syncWithLocation ? propsForLink : {})} // to avoid TypeScript screams, see https://github.com/mui-org/material-ui/issues/9106#issuecomment-451270521
{...rest}
/>
);
const renderHeader = () => {
let tabLabel =
typeof label === 'string' ? translate(label, { _: label }) : label;
if (count) {
fzaninotto marked this conversation as resolved.
Show resolved Hide resolved
tabLabel = (
<span>
{tabLabel} ({count})
</span>
);
}

return (
<MuiTab
key={`tab-header-${value}`}
label={tabLabel}
value={value}
icon={icon}
className={clsx('show-tab', className)}
{...(syncWithLocation ? propsForLink : {})} // to avoid TypeScript screams, see https://github.com/mui-org/material-ui/issues/9106#issuecomment-451270521
{...rest}
/>
);
};

const renderContent = () => (
<Stack className={contentClassName} spacing={spacing} divider={divider}>
Expand All @@ -115,10 +124,11 @@ export const Tab = ({
};

Tab.propTypes = {
children: PropTypes.node,
className: PropTypes.string,
contentClassName: PropTypes.string,
children: PropTypes.node,
context: PropTypes.oneOf(['header', 'content']),
count: PropTypes.node,
icon: PropTypes.element,
label: PropTypes.oneOfType([PropTypes.string, PropTypes.element])
.isRequired,
Expand All @@ -131,6 +141,7 @@ export interface TabProps extends Omit<MuiTabProps, 'children'> {
children: ReactNode;
contentClassName?: string;
context?: 'header' | 'content';
count?: ReactNode;
className?: string;
divider?: ReactNode;
icon?: ReactElement;
Expand Down
23 changes: 23 additions & 0 deletions packages/ra-ui-materialui/src/detail/TabbedShowLayout.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,29 @@ export const Basic = () => (
</MemoryRouter>
);

export const Count = () => (
<MemoryRouter>
<ResourceContext.Provider value="books">
<RecordContextProvider value={record}>
<TabbedShowLayout>
<TabbedShowLayout.Tab label="Main">
<TextField source="id" />
<TextField source="title" />
</TabbedShowLayout.Tab>
<TabbedShowLayout.Tab label="Details">
<TextField source="author" />
<TextField source="summary" />
<NumberField source="year" />
</TabbedShowLayout.Tab>
<TabbedShowLayout.Tab label="Reviews" count={27}>
<TextField source="reviews" />
</TabbedShowLayout.Tab>
</TabbedShowLayout>
</RecordContextProvider>
</ResourceContext.Provider>
</MemoryRouter>
);

const BookTitle = () => {
const record = useRecordContext();
return record ? <span>{record.title}</span> : null;
Expand Down
1 change: 1 addition & 0 deletions packages/ra-ui-materialui/src/field/ReferenceManyCount.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ export const ReferenceManyCount = (props: ReferenceManyCountProps) => {
})}`,
}}
variant="body2"
component="span"
onClick={e => e.stopPropagation()}
{...rest}
>
Expand Down
6 changes: 5 additions & 1 deletion packages/ra-ui-materialui/src/form/FormTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import { FormTabHeader } from './FormTabHeader';

export const FormTab = (props: FormTabProps) => {
const {
children,
className,
contentClassName,
children,
count,
hidden,
icon,
intent,
Expand All @@ -26,6 +27,7 @@ export const FormTab = (props: FormTabProps) => {
const renderHeader = () => (
<FormTabHeader
label={label}
count={count}
value={value}
icon={icon}
className={className}
Expand Down Expand Up @@ -60,6 +62,7 @@ FormTab.propTypes = {
className: PropTypes.string,
contentClassName: PropTypes.string,
children: PropTypes.node,
count: PropTypes.node,
intent: PropTypes.oneOf(['header', 'content']),
hidden: PropTypes.bool,
icon: PropTypes.element,
Expand All @@ -77,6 +80,7 @@ export interface FormTabProps
className?: string;
children?: ReactNode;
contentClassName?: string;
count?: ReactNode;
hidden?: boolean;
icon?: ReactElement;
intent?: 'header' | 'content';
Expand Down
Loading