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

Adds Pagination to Data Table #1367

Merged
merged 11 commits into from
Feb 2, 2022
52 changes: 38 additions & 14 deletions ui/components/DataTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import styled from "styled-components";
import Button from "./Button";
import Flex from "./Flex";
import Icon, { IconType } from "./Icon";
import Link from "./Link";
import Spacer from "./Spacer";
import Text from "./Text";

Expand All @@ -26,14 +27,15 @@ export interface Props {
}[];
/** A list of data that will be iterated through to create the columns described in `fields`. */
rows: any[];
/** A list of strings representing the sortable columns of the table, passed into lodash's `_.sortBy`. */
sortFields: string[];
/** A list of strings representing the sortable columns of the table, passed into lodash's `_.sortBy`. Must be lowercase. */
sortFields?: string[];
/** an optional list of string widths for each field/column. */
widths?: string[];
/** for passing pagination */
children?: any;
}

const EmptyRow = styled(TableRow)<{ colSpan: number }>`
font-style: italic;
td {
text-align: center;
}
Expand All @@ -46,24 +48,24 @@ const TableButton = styled(Button)`
text-transform: none;
}
&.MuiButton-text {
color: ${(props) => props.theme.colors.neutral30};
min-width: 0px;
.selected {
color: ${(props) => props.theme.colors.neutral40};
}
}
&.arrow {
min-width: 0px;
}
&.selected {
color: ${(props) => props.theme.colors.neutral40};
}
`;

/** Form DataTable */
function UnstyledDataTable({
className,
fields,
rows,
sortFields,
sortFields = [],
widths,
children,
}: Props) {
const [sort, setSort] = React.useState(sortFields[0]);
const [reverseSort, setReverseSort] = React.useState(false);
Expand All @@ -85,7 +87,9 @@ function UnstyledDataTable({
setSort(label.toLowerCase());
}}
>
<h2>{label}</h2>
<h2 className={sort === label.toLowerCase() && "selected"}>
{label}
</h2>
</TableButton>
<Spacer padding="xxs" />
{sort === label.toLowerCase() ? (
Expand Down Expand Up @@ -122,7 +126,7 @@ function UnstyledDataTable({
{sortFields.includes(f.label.toLowerCase()) ? (
<SortableLabel label={f.label} />
) : (
<h2 className="thead">{f.label}</h2>
<h2>{f.label}</h2>
)}
</TableCell>
))}
Expand All @@ -134,24 +138,44 @@ function UnstyledDataTable({
) : (
<EmptyRow colSpan={fields.length}>
<TableCell colSpan={fields.length}>
<span style={{ fontStyle: "italic" }}>No rows</span>
<Flex center align>
<Icon
color="neutral20"
type={IconType.RemoveCircleIcon}
size="base"
/>
<Spacer padding="xxs" />
<Text color="neutral30">No data</Text>
</Flex>
</TableCell>
</EmptyRow>
)}
</TableBody>
</Table>
</TableContainer>
<Spacer padding="xs" />
{/* optional pagination component */}
{children}
</div>
);
}

export const DataTable = styled(UnstyledDataTable)`
h2 {
font-size: 14px;
font-weight: 600;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have played around with this in the inspector and for me this only renders bold (> 600) or regular (<600) – is semi-bold Proxima Nova not getting imported somewhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmmm...I feel like I've seen that before, but I just tested it here's the screenshots:

font-weight 800:
image

font-weight 600:
image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It DEFINITELY changes but it is subtle for sure

color: ${(props) => props.theme.colors.neutral30};
margin: 0px;
}
.thead {
color: ${(props) => props.theme.colors.neutral30};
font-weight: 800;
.MuiTableRow-root {
transition: background 0.5s ease-in-out;
}
.MuiTableRow-root:not(.MuiTableRow-head):hover {
background: ${(props) => props.theme.colors.neutral10};
transition: background 0.5s ease-in-out;
}
${Link} ${Text} {
font-size: 14px;
}
`;

Expand Down
28 changes: 24 additions & 4 deletions ui/components/Icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,12 @@ import DeleteIcon from "@material-ui/icons/Delete";
import ErrorIcon from "@material-ui/icons/Error";
import HourglassFullIcon from "@material-ui/icons/HourglassFull";
import LaunchIcon from "@material-ui/icons/Launch";
import NavigateBeforeIcon from "@material-ui/icons/NavigateBefore";
import NavigateNextIcon from "@material-ui/icons/NavigateNext";
import RemoveCircleIcon from "@material-ui/icons/RemoveCircle";
import SaveAltIcon from "@material-ui/icons/SaveAlt";
import SkipNextIcon from "@material-ui/icons/SkipNext";
import SkipPreviousIcon from "@material-ui/icons/SkipPrevious";
import * as React from "react";
import styled from "styled-components";
import { colors, spacing } from "../typedefs/styled";
Expand All @@ -21,11 +25,15 @@ export enum IconType {
AddIcon,
ArrowUpwardIcon,
DeleteIcon,
NavigateNextIcon,
SaveAltIcon,
ErrorIcon,
CheckCircleIcon,
HourglassFullIcon,
NavigateNextIcon,
NavigateBeforeIcon,
SkipNextIcon,
SkipPreviousIcon,
RemoveCircleIcon,
}

type Props = {
Expand Down Expand Up @@ -56,9 +64,6 @@ function getIcon(i: IconType) {
case IconType.DeleteIcon:
return DeleteIcon;

case IconType.NavigateNextIcon:
return NavigateNextIcon;

case IconType.SaveAltIcon:
return SaveAltIcon;

Expand All @@ -71,6 +76,21 @@ function getIcon(i: IconType) {
case IconType.ErrorIcon:
return ErrorIcon;

case IconType.NavigateNextIcon:
return NavigateNextIcon;

case IconType.NavigateBeforeIcon:
return NavigateBeforeIcon;

case IconType.SkipNextIcon:
return SkipNextIcon;

case IconType.SkipPreviousIcon:
return SkipPreviousIcon;

case IconType.RemoveCircleIcon:
return RemoveCircleIcon;

default:
break;
}
Expand Down
10 changes: 9 additions & 1 deletion ui/components/Link.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,15 @@ type Props = {
newTab?: boolean;
};

function Link({ children, href, className, to = "", newTab, ...props }: Props) {
function Link({
children,
href,
className,
to = "",
newTab,

...props
}: Props) {
const txt = <Text color="primary">{children}</Text>;

if (href) {
Expand Down
118 changes: 118 additions & 0 deletions ui/components/Pagination.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import { FormControl, MenuItem, Select } from "@material-ui/core";
import * as React from "react";
import styled from "styled-components";
import Button from "./Button";
import Flex from "./Flex";
import Icon, { IconType } from "./Icon";
import Spacer from "./Spacer";
import Text from "./Text";

export interface Props {
/** CSS MUI Overrides or other styling. */
className?: string;
/** func for forward one page button */
onForward: () => void;
/** func for skip to last page button */
onSkipForward: () => void;
/** func for back one page button */
onBack: () => void;
/** func for skip to start button */
onSkipBack: () => void;
/** onChange func for perPage select */
onSelect: (value: string) => void;
/** options for perPage select */
perPageOptions?: number[];
/** starting index */
index: number;
/** total rows */
length: number;
/** all objects */
totalObjects: number;
}

function unstyledPagination({
className,
onForward,
onSkipForward,
onBack,
onSkipBack,
onSelect,
perPageOptions = [25, 50, 75, 100],
index,
length,
totalObjects,
}: Props) {
return (
<Flex wide align end className={className}>
<FormControl>
<Flex align>
<label htmlFor="pagination">Rows Per Page: </label>
<Spacer padding="xxs" />
<Select
id="pagination"
variant="outlined"
defaultValue={perPageOptions[0]}
onChange={(e: React.ChangeEvent<HTMLSelectElement>) => {
onSelect(e.target.value);
}}
>
{perPageOptions.map((option, index) => {
return (
<MenuItem key={index} value={option}>
{option}
</MenuItem>
);
})}
</Select>
</Flex>
</FormControl>
<Spacer padding="base" />
<Text>
{index + 1} - {index + length} out of {totalObjects}
</Text>
<Spacer padding="base" />
<Flex>
<Button
color="inherit"
variant="text"
aria-label="skip to first page"
disabled={index === 0}
onClick={onSkipBack}
>
<Icon type={IconType.SkipPreviousIcon} size="medium" />
</Button>
<Button
color="inherit"
variant="text"
aria-label="back one page"
disabled={index === 0}
onClick={onBack}
>
<Icon type={IconType.NavigateBeforeIcon} size="medium" />
</Button>
<Button
color="inherit"
variant="text"
aria-label="forward one page"
disabled={index + length >= totalObjects}
onClick={onForward}
>
<Icon type={IconType.NavigateNextIcon} size="medium" />
</Button>
<Button
color="inherit"
variant="text"
aria-label="skip to last page"
disabled={index + length >= totalObjects}
onClick={onSkipForward}
>
<Icon type={IconType.SkipNextIcon} size="medium" />
</Button>
</Flex>
</Flex>
);
}

export const Pagination = styled(unstyledPagination)``;

export default Pagination;