saleor-dashboard/src/components/ColumnPicker/ColumnPickerContent.tsx

199 lines
5.8 KiB
TypeScript
Raw Normal View History

2019-08-09 10:17:04 +00:00
import Button from "@material-ui/core/Button";
import Card from "@material-ui/core/Card";
import CardContent from "@material-ui/core/CardContent";
2019-08-13 09:04:52 +00:00
import CircularProgress from "@material-ui/core/CircularProgress";
2019-10-28 16:16:49 +00:00
import makeStyles from "@material-ui/core/styles/makeStyles";
2019-08-09 10:17:04 +00:00
import Typography from "@material-ui/core/Typography";
import classNames from "classnames";
import React from "react";
2019-08-13 09:04:52 +00:00
import InfiniteScroll from "react-infinite-scroller";
import { FormattedMessage } from "react-intl";
2019-08-09 10:17:04 +00:00
import useElementScroll from "@saleor/hooks/useElementScroll";
import { buttonMessages } from "@saleor/intl";
2019-08-13 09:04:52 +00:00
import { FetchMoreProps } from "@saleor/types";
2019-08-09 10:17:04 +00:00
import { isSelected } from "@saleor/utils/lists";
import ControlledCheckbox from "../ControlledCheckbox";
import Hr from "../Hr";
export interface ColumnPickerChoice {
label: string;
value: string;
}
2019-08-13 09:04:52 +00:00
export interface ColumnPickerContentProps extends Partial<FetchMoreProps> {
2019-08-09 10:17:04 +00:00
columns: ColumnPickerChoice[];
selectedColumns: string[];
2019-08-13 09:04:52 +00:00
total?: number;
2019-08-09 10:17:04 +00:00
onCancel: () => void;
onColumnToggle: (column: string) => void;
onReset: () => void;
onSave: () => void;
}
2019-12-03 15:28:40 +00:00
const useStyles = makeStyles(
theme => ({
actionBar: {
display: "flex",
justifyContent: "space-between"
2019-11-12 16:28:21 +00:00
},
2019-12-03 15:28:40 +00:00
actionBarContainer: {
boxShadow: `0px 0px 0px 0px ${theme.palette.background.paper}`,
transition: theme.transitions.duration.short + "ms"
},
cancelButton: {
marginRight: theme.spacing(2)
},
content: {
[theme.breakpoints.down("sm")]: {
gridTemplateColumns: "repeat(2, 1fr)"
},
display: "grid",
gridColumnGap: theme.spacing(3),
gridTemplateColumns: "repeat(3, 1fr)",
maxHeight: 256,
overflowX: "visible",
overflowY: "scroll",
padding: theme.spacing(2, 3)
},
contentContainer: {
padding: 0
},
dropShadow: {
boxShadow: `0px -5px 10px 0px ${theme.palette.divider}`
},
loadMoreLoaderContainer: {
alignItems: "center",
display: "flex",
gridColumnEnd: "span 3",
height: theme.spacing(3),
justifyContent: "center"
},
root: {
boxShadow: "0px 4px 4px rgba(0, 0, 0, 0.25)"
},
titleContainer: {
padding: theme.spacing(1.5, 3.5)
}
}),
{ name: "ColumnPickerContent" }
);
2019-08-09 10:17:04 +00:00
const ColumnPickerContent: React.FC<ColumnPickerContentProps> = props => {
const {
columns,
2019-08-13 09:04:52 +00:00
hasMore,
loading,
2019-08-09 10:17:04 +00:00
selectedColumns,
2019-08-13 09:04:52 +00:00
total,
2019-08-09 10:17:04 +00:00
onCancel,
onColumnToggle,
2019-08-13 09:04:52 +00:00
onFetchMore,
2019-08-09 10:17:04 +00:00
onReset,
onSave
} = props;
const classes = useStyles(props);
const anchor = React.useRef<HTMLDivElement>();
const scrollPosition = useElementScroll(anchor);
2019-10-23 12:21:34 +00:00
const dropShadow =
anchor.current && scrollPosition
? scrollPosition.y + anchor.current.clientHeight <
anchor.current.scrollHeight
: false;
2019-08-09 10:17:04 +00:00
return (
<Card className={classes.root}>
2019-11-13 12:56:51 +00:00
<CardContent className={classes.titleContainer}>
2019-08-09 10:17:04 +00:00
<Typography color="textSecondary">
<FormattedMessage
defaultMessage="{numberOfSelected} columns selected out of {numberOfTotal}"
description="pick columns to display"
values={{
2019-08-09 10:17:04 +00:00
numberOfSelected: selectedColumns.length,
2019-08-13 09:04:52 +00:00
numberOfTotal: total || columns.length
}}
/>
2019-08-09 10:17:04 +00:00
</Typography>
</CardContent>
<Hr />
2019-08-13 09:04:52 +00:00
{hasMore && onFetchMore ? (
<InfiniteScroll
pageStart={0}
loadMore={onFetchMore}
hasMore={hasMore}
useWindow={false}
threshold={100}
key="infinite-scroll"
>
<CardContent className={classes.contentContainer}>
<div className={classes.content} ref={anchor}>
{columns.map(column => (
<ControlledCheckbox
checked={isSelected(
column.value,
selectedColumns,
(a, b) => a === b
)}
name={column.value}
label={column.label}
onChange={() => onColumnToggle(column.value)}
2020-01-31 15:20:14 +00:00
key={column.value}
2019-08-13 09:04:52 +00:00
/>
))}
{loading && (
<div className={classes.loadMoreLoaderContainer}>
<CircularProgress size={16} />
</div>
2019-08-09 10:17:04 +00:00
)}
2019-08-13 09:04:52 +00:00
</div>
</CardContent>
</InfiniteScroll>
) : (
<CardContent className={classes.contentContainer}>
<div className={classes.content} ref={anchor}>
{columns.map(column => (
<ControlledCheckbox
checked={isSelected(
column.value,
selectedColumns,
(a, b) => a === b
)}
name={column.value}
label={column.label}
onChange={() => onColumnToggle(column.value)}
2020-01-31 15:20:14 +00:00
key={column.value}
2019-08-13 09:04:52 +00:00
/>
))}
</div>
</CardContent>
)}
2019-08-09 10:17:04 +00:00
<Hr />
<CardContent
className={classNames(classes.actionBarContainer, {
[classes.dropShadow]: dropShadow
})}
>
<div className={classes.actionBar}>
<Button color="default" onClick={onReset}>
<FormattedMessage defaultMessage="Reset" description="button" />
2019-08-09 10:17:04 +00:00
</Button>
<div>
2019-09-02 11:22:48 +00:00
<Button
className={classes.cancelButton}
color="default"
onClick={onCancel}
>
<FormattedMessage {...buttonMessages.cancel} />
2019-08-09 10:17:04 +00:00
</Button>
<Button color="primary" variant="contained" onClick={onSave}>
<FormattedMessage {...buttonMessages.save} />
2019-08-09 10:17:04 +00:00
</Button>
</div>
</div>
</CardContent>
</Card>
);
};
export default ColumnPickerContent;