diff --git a/src/common/Table/Table.tsx b/src/common/Table/Table.tsx index 9222ac6..c17860c 100644 --- a/src/common/Table/Table.tsx +++ b/src/common/Table/Table.tsx @@ -6,7 +6,6 @@ import { Table as MUITable, TableBody, TableProps as MUITableProps, - TableBodyProps, TableContainer, } from '@material-ui/core'; import TableHead from './TableHead'; @@ -23,18 +22,15 @@ export interface TableProps { orderDirection?: OrderDirection; selection?: boolean; idFieldName?: string; - getRowKey?: (row: T, index: number) => string | number | null | undefined; onRequestSort?: ( orderBy: string, orderDirection: OrderDirection ) => void | Promise; onSelect?: (rows: T[]) => void; loading?: boolean; - tableProps?: MUITableProps; - tableBodyProps?: TableBodyProps; footerProps?: TableFooterProps; hideFooter?: boolean; - size?: 'medium' | 'small'; + size?: MUITableProps['size']; selected?: T[]; } @@ -48,19 +44,12 @@ function Table({ selection = false, loading = false, actions = [], - tableBodyProps = {}, - tableProps = {}, hideFooter = false, footerProps = {}, size, selected, onSelect, - getRowKey, }: TableProps) { - const headColumns = - actions.length > 0 - ? [...columns, { field: 'action', label: 'Akcje' }] - : columns; const preparedFooterProps = { page: 0, rowsPerPage: validateRowsPerPage( @@ -86,11 +75,12 @@ function Table({ return ( - + 0} orderDirection={orderDirection} onRequestSort={onRequestSort} size={size} @@ -101,10 +91,9 @@ function Table({ }} allSelected={selected?.length === data.length} /> - + {loading ? ( @@ -113,11 +102,7 @@ function Table({ return ( void; rowsPerPage?: number; onChangeRowsPerPage?: (limit: number) => void; - rowsPerPageOptions?: Array; - size?: 'small' | 'medium'; + rowsPerPageOptions?: MUITablePaginationProps['rowsPerPageOptions']; + size?: MUITablePaginationProps['size']; } export const ROWS_PER_PAGE_DEFAULT = 25; diff --git a/src/common/Table/TableHead.tsx b/src/common/Table/TableHead.tsx index f4e4061..5228ac5 100644 --- a/src/common/Table/TableHead.tsx +++ b/src/common/Table/TableHead.tsx @@ -22,6 +22,7 @@ export interface TableHeadProps { property: string, orderDirection: OrderDirection ) => void | Promise; + hasActions: boolean; } function TableHead({ @@ -33,6 +34,7 @@ function TableHead({ allSelected = false, onRequestSort, size = 'medium', + hasActions = false, }: TableHeadProps) { const createSortHandler = (property: string) => () => { if (onRequestSort) { @@ -85,6 +87,7 @@ function TableHead({ ); })} + {hasActions && Akcje} ); diff --git a/src/common/Table/TableLoading.tsx b/src/common/Table/TableLoading.tsx index 5b6b5da..f64b478 100644 --- a/src/common/Table/TableLoading.tsx +++ b/src/common/Table/TableLoading.tsx @@ -1,30 +1,22 @@ import React, { Fragment } from 'react'; -import { Column } from './types'; import { TableRow, TableCell } from '@material-ui/core'; import { Skeleton } from '@material-ui/lab'; export interface TableLoadingProps { rowsPerPage: number; - columns: Column[]; size?: 'small' | 'medium'; } -function TableLoading({ - rowsPerPage, - columns, - size = 'medium', -}: TableLoadingProps) { +function TableLoading({ rowsPerPage, size = 'medium' }: TableLoadingProps) { return ( {new Array(rowsPerPage).fill(0).map((_, index) => { return ( - {columns.map(col => ( - - - - ))} + + + ); })} diff --git a/src/common/Table/helpers.ts b/src/common/Table/helpers.ts index d306779..724c4bc 100644 --- a/src/common/Table/helpers.ts +++ b/src/common/Table/helpers.ts @@ -1,13 +1,12 @@ import { ROWS_PER_PAGE_DEFAULT, ROWS_PER_PAGE_OPTIONS_DEFAULT, + TableFooterProps, } from './TableFooter'; export const validateRowsPerPage = ( rowsPerPage: number | null = ROWS_PER_PAGE_DEFAULT, - rowsPerPageOptions: Array< - number | { value: number; label: string } - > = ROWS_PER_PAGE_OPTIONS_DEFAULT + rowsPerPageOptions: TableFooterProps['rowsPerPageOptions'] = ROWS_PER_PAGE_OPTIONS_DEFAULT ) => { const opt = rowsPerPageOptions.find(opt => diff --git a/src/features/UsersPage/UsersPage.tsx b/src/features/UsersPage/UsersPage.tsx index b2e0da4..cccab06 100644 --- a/src/features/UsersPage/UsersPage.tsx +++ b/src/features/UsersPage/UsersPage.tsx @@ -2,20 +2,52 @@ import useUsers from './UsersPage.useUsers'; import { NumberParam, useQueryParams, withDefault } from 'use-query-params'; import SortParam, { decodeSort } from 'libs/serialize-query-params/SortParam'; import { validateRowsPerPage } from 'common/Table/helpers'; +import { DEFAULT_SORT, COLUMNS } from './constants'; -const DEFAULT_SORT = decodeSort('id DESC'); +import { Container, Paper } from '@material-ui/core'; +import Table from 'common/Table/Table'; const UsersPage = () => { - const [{ page, sort, ...rest }, setQuery] = useQueryParams({ + const [{ page, sort, ...rest }, setQueryParams] = useQueryParams({ limit: NumberParam, page: withDefault(NumberParam, 0), sort: withDefault(SortParam, DEFAULT_SORT), }); const limit = validateRowsPerPage(rest.limit); - const data = useUsers(page, limit, sort.toString()); - console.log(data); + const { users, total, loading } = useUsers(page, limit, sort.toString()); + console.log(users); - return
UsersPage
; + return ( + + + { + setQueryParams({ + page: 0, + sort: decodeSort(orderBy + ' ' + orderDirection), + }); + }} + footerProps={{ + count: total, + page, + onChangePage: page => { + setQueryParams({ page }); + }, + onChangeRowsPerPage: limit => { + setQueryParams({ page: 0, limit }); + }, + rowsPerPage: limit, + }} + /> + + + ); }; export default UsersPage; diff --git a/src/features/UsersPage/UsersPage.useUsers.ts b/src/features/UsersPage/UsersPage.useUsers.ts index a1c973d..24fc87c 100644 --- a/src/features/UsersPage/UsersPage.useUsers.ts +++ b/src/features/UsersPage/UsersPage.useUsers.ts @@ -18,7 +18,7 @@ const useUsers = (page: number, limit: number, sort: string) => { return { users: data?.users.items ?? [], get loading() { - return this.users.length === 0 || loading; + return this.users.length === 0 && loading; }, total: data?.users.total ?? 0, }; diff --git a/src/features/UsersPage/constants.ts b/src/features/UsersPage/constants.ts new file mode 100644 index 0000000..9828804 --- /dev/null +++ b/src/features/UsersPage/constants.ts @@ -0,0 +1,39 @@ +import { decodeSort } from 'libs/serialize-query-params/SortParam'; +import { formatRole } from './utils'; +import { Column } from 'common/Table/types'; +import { User } from 'libs/graphql/types'; + +export const DEFAULT_SORT = decodeSort('id DESC'); +export const COLUMNS: Column[] = [ + { + field: 'id', + sortable: true, + label: 'ID', + }, + { + field: 'displayName', + sortable: true, + label: 'Użytkownik', + valueFormatter: v => { + return `${v.displayName} (${v.email})`; + }, + }, + { + field: 'role', + sortable: false, + label: 'Rola', + valueFormatter: v => formatRole(v.role), + }, + { + field: 'activated', + sortable: false, + label: 'Aktywowany', + valueFormatter: v => (v.activated ? 'Tak' : 'Nie'), + }, + { + field: 'createdAt', + sortable: true, + label: 'Data utworzenia', + type: 'datetime', + }, +]; diff --git a/src/features/UsersPage/queries.ts b/src/features/UsersPage/queries.ts index ab18df5..562c2fd 100644 --- a/src/features/UsersPage/queries.ts +++ b/src/features/UsersPage/queries.ts @@ -15,6 +15,7 @@ export const QUERY_USERS = gql` displayName email role + createdAt } } } diff --git a/src/features/UsersPage/utils.ts b/src/features/UsersPage/utils.ts new file mode 100644 index 0000000..0293b17 --- /dev/null +++ b/src/features/UsersPage/utils.ts @@ -0,0 +1,4 @@ +import { Role } from '../../libs/graphql/types'; + +export const formatRole = (r: Role): string => + r === Role.Admin ? 'Admin' : 'Użytkownik';