如何解决如何使用简单列表启用批量操作
我需要为列表创建不同的视图,以便可以在移动设备上查看。有人建议我使用 SimpleList,但我仍然希望用户能够选择列表中的多个项目并完成批量操作。有没有办法做到这一点? React Admin 文档中没有太多关于此场景的文档。
解决方法
我没有足够的声誉来对此进行投票,但是,使用当前的 SimpleList,我制作了一个适用于我的目的的可选(批量操作)版本。
它可能对您也有用。
它是在普通的 JS 中,而不是像原来的 TypeScript。
要使用它,只需导入文件,例如:
import SelectSimpleList from './SelectSimpleList'
并以与原始 SimpleList 完全相同的方式使用它。
SelectSimpleList.js:
import * as React from 'react';
import PropTypes from 'prop-types';
import {
Avatar,List,//ListProps,ListItem,ListItemAvatar,ListItemIcon,ListItemSecondaryAction,ListItemText,} from '@material-ui/core';
import { makeStyles } from '@material-ui/core/styles';
import { Link } from 'react-router-dom';
import {
linkToRecord,sanitizeListRestProps,useListContext,//Record,//RecordMap,//Identifier,} from 'ra-core';
import Checkbox from '@material-ui/core/Checkbox';
import { useTimeout } from 'ra-core';
import classnames from 'classnames';
const useStylesPlaceholder = makeStyles(
theme => ({
root: {
backgroundColor: theme.palette.grey[300],display: 'flex',},}),{ name: 'RaPlaceholder' }
);
const Placeholder = props => {
const classes = useStylesPlaceholder(props);
return (
<span className={classnames(classes.root,props.className)}>
</span>
);
};
const useStylesLoading = makeStyles(
theme => ({
primary: {
width: '30vw',display: 'inline-block',marginBottom: theme.spacing(),tertiary: { float: 'right',opacity: 0.541176,minWidth: '10vw' },{ name: 'RaSimpleListLoading' },);
const times = (nbChildren,fn) =>
Array.from({ length: nbChildren },(_,key) => fn(key));
const SimpleListLoading = props => {
const {
classes: classesOverride,className,hasLeftAvatarOrIcon,hasRightAvatarOrIcon,hasSecondaryText,hasTertiaryText,nbFakeLines = 5,...rest
} = props;
const classes = useStylesLoading(props);
const oneSecondHasPassed = useTimeout(1000);
return oneSecondHasPassed ? (
<List className={className} {...rest}>
{times(nbFakeLines,key => (
<ListItem key={key}>
{hasLeftAvatarOrIcon && (
<ListItemAvatar>
<Avatar> </Avatar>
</ListItemAvatar>
)}
<ListItemText
primary={
<div>
<Placeholder className={classes.primary} />
{hasTertiaryText && (
<span className={classes.tertiary}>
<Placeholder />
</span>
)}
</div>
}
secondary={
hasSecondaryText ? <Placeholder /> : undefined
}
/>
{hasRightAvatarOrIcon && (
<ListItemSecondaryAction>
<Avatar> </Avatar>
</ListItemSecondaryAction>
)}
</ListItem>
))}
</List>
) : null;
};
SimpleListLoading.propTypes = {
className: PropTypes.string,hasLeftAvatarOrIcon: PropTypes.bool,hasRightAvatarOrIcon: PropTypes.bool,hasSecondaryText: PropTypes.bool,hasTertiaryText: PropTypes.bool,nbFakeLines: PropTypes.number,};
const useStyles = makeStyles(
{
tertiary: { float: 'right',opacity: 0.541176 },{ name: 'RaSimpleList' }
);
/**
* The <SimpleList> component renders a list of records as a material-ui <List>.
* It is usually used as a child of react-admin's <List> and <ReferenceManyField> components.
*
* Also widely used on Mobile.
*
* Props:
* - primaryText: function returning a React element (or some text) based on the record
* - secondaryText: same
* - tertiaryText: same
* - leftAvatar: function returning a React element based on the record
* - leftIcon: same
* - rightAvatar: same
* - rightIcon: same
* - linkType: 'edit' or 'show',or a function returning 'edit' or 'show' based on the record
* - rowStyle: function returning a style object based on (record,index)
*
* @example // Display all posts as a List
* const postRowStyle = (record,index) => ({
* backgroundColor: record.views >= 500 ? '#efe' : 'white',* });
* export const PostList = (props) => (
* <List {...props}>
* <SimpleList
* primaryText={record => record.title}
* secondaryText={record => `${record.views} views`}
* tertiaryText={record =>
* new Date(record.published_at).toLocaleDateString()
* }
* rowStyle={postRowStyle}
* />
* </List>
* );
*/
const SelectSimpleList = props => {
const {
className,classes: classesOverride,hasBulkActions,leftAvatar,leftIcon,linkType = 'edit',primaryText,rightAvatar,rightIcon,secondaryText,tertiaryText,rowStyle,...rest
} = props;
const { basePath,data,ids,loaded,total,onToggleItem,selectedIds } = useListContext(props);
const classes = useStyles(props);
if (loaded === false) {
return (
<SimpleListLoading
classes={classes}
className={className}
hasLeftAvatarOrIcon={!!leftIcon || !!leftAvatar}
hasRightAvatarOrIcon={!!rightIcon || !!rightAvatar}
hasSecondaryText={!!secondaryText}
hasTertiaryText={!!tertiaryText}
/>
);
}
const isSelected = id => {
if (selectedIds.includes(id)){
return true;
}
return false;
}
return (
total > 0 && (
<List className={className} {...sanitizeListRestProps(rest)}>
{ids.map((id,rowIndex) => (
<LinkOrNot
linkType={linkType}
basePath={basePath}
id={id}
key={id}
record={data[id]}
>
<ListItem
//onClick={() => {onToggleItem(id)}}
button={!!linkType}
style={
rowStyle
? rowStyle(data[id],rowIndex)
: undefined
}
>
<Checkbox
checked={isSelected(id)}
onChange={() => onToggleItem(id)}
color="primary"
onClick={(e) => e.stopPropagation()}
inputProps={{ 'aria-label': 'primary checkbox' }}
/>
{leftIcon && (
<ListItemIcon>
{leftIcon(data[id],id)}
</ListItemIcon>
)}
{leftAvatar && (
<ListItemAvatar>
<Avatar>{leftAvatar(data[id],id)}</Avatar>
</ListItemAvatar>
)}
<ListItemText
primary={
<div>
{primaryText(data[id],id)}
{tertiaryText && (
<span className={classes.tertiary}>
{tertiaryText(data[id],id)}
</span>
)}
</div>
}
secondary={
secondaryText && secondaryText(data[id],id)
}
/>
{(rightAvatar || rightIcon) && (
<ListItemSecondaryAction>
{rightAvatar && (
<Avatar>
{rightAvatar(data[id],id)}
</Avatar>
)}
{rightIcon && (
<ListItemIcon>
{rightIcon(data[id],id)}
</ListItemIcon>
)}
</ListItemSecondaryAction>
)}
</ListItem>
</LinkOrNot>
))}
</List>
)
);
};
SelectSimpleList.propTypes = {
className: PropTypes.string,classes: PropTypes.object,leftAvatar: PropTypes.func,leftIcon: PropTypes.func,linkType: PropTypes.oneOfType([
PropTypes.string,PropTypes.bool,PropTypes.func,]),primaryText: PropTypes.func,rightAvatar: PropTypes.func,rightIcon: PropTypes.func,secondaryText: PropTypes.func,tertiaryText: PropTypes.func,rowStyle: PropTypes.func,};
const useLinkOrNotStyles = makeStyles(
{
link: {
textDecoration: 'none',color: 'inherit',{ name: 'RaLinkOrNot' }
);
const LinkOrNot = ({
classes: classesOverride,linkType,basePath,id,children,record,}) => {
const classes = useLinkOrNotStyles({ classes: classesOverride });
const link =
typeof linkType === 'function' ? linkType(record,id) : linkType;
return link === 'edit' || link === true ? (
<Link to={linkToRecord(basePath,id)} className={classes.link}>
{children}
</Link>
) : link === 'show' ? (
<Link
to={`${linkToRecord(basePath,id)}/show`}
className={classes.link}
>
{children}
</Link>
) : (
<span>{children}</span>
);
};
export default SelectSimpleList;
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。