Skip to content
This repository has been archived by the owner on Feb 8, 2024. It is now read-only.

Commit

Permalink
[v9] Add Serverside Pagination, Filtering, and Sorting (#752)
Browse files Browse the repository at this point in the history
  • Loading branch information
rudream authored Apr 20, 2022
1 parent cec889d commit 8c8b692
Show file tree
Hide file tree
Showing 75 changed files with 8,673 additions and 2,504 deletions.
48 changes: 40 additions & 8 deletions packages/design/src/DataTable/Cells.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,41 @@ import React from 'react';
import { Label } from 'design';
import * as Icons from 'design/Icon';
import { displayDate } from 'shared/services/loc';
import { SortDir } from './types';
import { ServersideProps, SortDir, TableColumn } from './types';

export const Cell = props => <td children={props.children} {...props} />;

export const SortHeaderCell = ({ dir, text, onClick }: SortHeaderCellProps) => {
export function SortHeaderCell<T>({
column,
serversideProps,
dir,
text,
onClick,
}: SortHeaderCellProps<T>) {
function handleServersideClick() {
serversideProps.setSort({
dir: serversideProps.sort?.dir === 'ASC' ? 'DESC' : 'ASC',
fieldName: column.key,
});
}

if (serversideProps) {
return (
<th>
<a onClick={handleServersideClick}>
{text}
<SortIndicator
sortDir={
serversideProps.sort?.fieldName === column.key
? serversideProps.sort.dir
: null
}
/>
</a>
</th>
);
}

return (
<th>
<a onClick={onClick}>
Expand All @@ -15,13 +45,13 @@ export const SortHeaderCell = ({ dir, text, onClick }: SortHeaderCellProps) => {
</a>
</th>
);
};
}

export const SortIndicator = ({
export function SortIndicator<T>({
sortDir,
}: {
sortDir?: SortHeaderCellProps['dir'];
}) => {
sortDir?: SortHeaderCellProps<T>['dir'];
}) {
if (sortDir === 'DESC') {
return <Icons.SortDesc />;
}
Expand All @@ -31,7 +61,7 @@ export const SortIndicator = ({
}

return <Icons.Sort />;
};
}

export const TextCell = ({ data }) => <Cell>{`${data || ''}`}</Cell>;

Expand All @@ -52,7 +82,9 @@ const renderLabelCell = (labels: string[] = []) => {
return <Cell>{$labels}</Cell>;
};

type SortHeaderCellProps = {
type SortHeaderCellProps<T> = {
column: TableColumn<T>;
serversideProps: ServersideProps;
text: string;
dir: SortDir;
onClick: () => void;
Expand Down
81 changes: 63 additions & 18 deletions packages/design/src/DataTable/InputSearch/InputSearch.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,83 @@
/*
Copyright 2021-2022 Gravitational, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import React, { SetStateAction } from 'react';
import styled from 'styled-components';
import { height, space, color } from 'design/system';

export default function InputSearch({ searchValue, setSearchValue }: Props) {
export default function InputSearch({
searchValue,
setSearchValue,
children,
}: Props) {
return (
<Input
placeholder="SEARCH..."
px={3}
value={searchValue}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
setSearchValue(e.target.value)
}
/>
<Wrapper>
<StyledInput
placeholder="SEARCH..."
px={3}
value={searchValue}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
setSearchValue(e.target.value)
}
/>
<ChildWrapper>{children}</ChildWrapper>
</Wrapper>
);
}

type Props = {
searchValue: string;
setSearchValue: React.Dispatch<SetStateAction<string>>;
children?: JSX.Element;
};

const Input = styled.input`
box-sizing: border-box;
font-size: 12px;
min-width: 200px;
outline: none;
border: none;
const ChildWrapper = styled.div`
position: absolute;
height: 100%;
right: 0;
display: flex;
align-items: center;
justify-content: center;
background: ${props => props.theme.colors.primary.lighter};
border-radius: 200px;
`;

const Wrapper = styled.div`
position: relative;
display: flex;
overflow: hidden;
width: 100%;
border-radius: 200px;
height: 32px;
transition: all .2s;
${fromTheme}
${space}
background: ${props => props.theme.colors.primary.dark};
`;

const StyledInput = styled.input`
border: none;
outline: none;
box-sizing: border-box;
height: 100%;
font-size: 12px;
width: 100%;
transition: all 0.2s;
${color}
${space}
${height}
${fromTheme};
padding-right: 184px;
`;

function fromTheme(props) {
Expand Down
29 changes: 23 additions & 6 deletions packages/design/src/DataTable/Pager/Pager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,16 @@ export function Pager({
count,
onFetchMore,
fetchStatus,
serversideProps,
}: State) {
const isFetchingEnabled = onFetchMore && fetchStatus !== 'disabled';
return (
<Flex>
<Flex justifyContent="flex-end" width="100%">
<Flex alignItems="center" mr={2}>
<Text typography="body2" color="primary.contrastText" mr={1}>
SHOWING <strong>{from + 1}</strong> - <strong>{to + 1}</strong> of{' '}
<strong>{count}</strong>
</Text>
{isFetchingEnabled && (
{!serversideProps && (
<PageIndicatorText from={from + 1} to={to + 1} count={count} />
)}
{isFetchingEnabled && !serversideProps && (
<StyledFetchMoreBtn
disabled={fetchStatus === 'loading'}
onClick={onFetchMore}
Expand Down Expand Up @@ -58,3 +58,20 @@ export function Pager({
</Flex>
);
}

export function PageIndicatorText({
from,
to,
count,
}: {
from: number;
to: number;
count: number;
}) {
return (
<Text typography="body2" color="primary.contrastText" mr={1}>
SHOWING <strong>{from}</strong> - <strong>{to}</strong> of{' '}
<strong>{count}</strong>
</Text>
);
}
29 changes: 21 additions & 8 deletions packages/design/src/DataTable/Pager/usePager.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FetchStatus } from '../types';
import { FetchStatus, ServersideProps } from './../types';

export default function usePager({
nextPage,
Expand All @@ -7,9 +7,10 @@ export default function usePager({
paginatedData = [],
currentPage,
pageSize,
serversideProps,
...props
}: Props) {
const currentPageData = paginatedData[currentPage];
const currentPageData = paginatedData[currentPage] || [];
const searchFrom = currentPage * pageSize;

const from = data.indexOf(currentPageData[0], searchFrom);
Expand All @@ -18,14 +19,25 @@ export default function usePager({
searchFrom + pageSize - 1
);

const count = data.length;

const isNextDisabled = serversideProps
? serversideProps.startKeys[serversideProps.startKeys.length - 1] === ''
: to === data.length - 1;

const isPrevDisabled = serversideProps
? serversideProps.startKeys.length <= 2
: currentPage === 0;

return {
nextPage,
prevPage,
from,
to,
count: data.length,
isPrevDisabled: currentPage === 0,
isNextDisabled: to === data.length - 1,
count,
isNextDisabled,
isPrevDisabled,
serversideProps,
...props,
};
}
Expand All @@ -34,11 +46,12 @@ export type Props = {
nextPage: () => void;
prevPage: () => void;
data: any[];
paginatedData: Array<Array<any>>;
currentPage: number;
pageSize: number;
paginatedData?: Array<Array<any>>;
currentPage?: number;
pageSize?: number;
onFetchMore?: () => void;
fetchStatus?: FetchStatus;
serversideProps?: ServersideProps;
};

export type State = ReturnType<typeof usePager>;
11 changes: 0 additions & 11 deletions packages/design/src/DataTable/StyledTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ export const StyledTable = styled.table(
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.24);
border-collapse: collapse;
border-spacing: 0;
border-radius: 8px;
font-size: 12px;
width: 100%;
Expand Down Expand Up @@ -83,16 +82,6 @@ export const StyledTable = styled.table(
background-color: ${darken(props.theme.colors.primary.lighter, 0.14)};
}
tbody > tr:last-child {
td:first-child {
border-bottom-left-radius: 8px;
}
td:last-child {
border-bottom-right-radius: 8px;
}
}
`,
space,
borderRadius
Expand Down
Loading

0 comments on commit 8c8b692

Please sign in to comment.