Skip to content

Commit

Permalink
refactor(client): lists (#235)
Browse files Browse the repository at this point in the history
* refactor(client): move lists into a single directory, change filters icon

* fix(client): add missing translations

* fix(client): remove padding from back button on mobile
  • Loading branch information
Jozwiaczek authored Apr 7, 2021
1 parent 945444c commit 7a6b8cf
Show file tree
Hide file tree
Showing 17 changed files with 201 additions and 65 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
import styled from 'styled-components';

import BackArrowIcon from '../../../icons/BackArrowIcon';
import TextButton from '../TextButton';

export const BackIcon = styled(BackArrowIcon)`
margin-right: 10px;
`;

export const StyledTextButton = styled(TextButton)`
${({ theme: { breakpoints, down } }) => `
${down(breakpoints.md)} {
padding: 0;
}
`};
`;
11 changes: 6 additions & 5 deletions packages/client/src/elements/buttons/BackButton/index.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { useHistory } from 'react-router-dom';

import TextButton from '../TextButton';
import { BackIcon } from './BackButton.styled';
import { BackIcon, StyledTextButton } from './BackButton.styled';

const BackButton = () => {
const history = useHistory();
const { t } = useTranslation();

return (
<TextButton onClick={() => history.goBack()}>
<StyledTextButton onClick={() => history.goBack()}>
<BackIcon />
<b>back</b>
</TextButton>
<b>{t('actions.back')}</b>
</StyledTextButton>
);
};

Expand Down
3 changes: 1 addition & 2 deletions packages/client/src/elements/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,11 @@ export {
export { default as BackgroundSideLogo } from './BackgroundSideLogo';
export { BackButton, Button, IconButton } from './buttons';
export { default as Card } from './Card';
export { default as CardList } from './CardList';
export { default as Copyright } from './Copyright';
export { DateField, FunctionField, TextField } from './fields';
export { default as Form } from './Form';
export { Checkbox, Select, TextInput } from './inputs';
export { CardLayout, DefaultLayout, GlobalLayout, TabbedLayout } from './layouts';
export { default as Link } from './Link';
export { default as List } from './List';
export { CardList, DetailedList } from './lists';
export { default as Snackbar } from './Snackbar';
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import styled from 'styled-components';

import { IconButton } from '../buttons';
import Card from '../Card';
import { Button, IconButton } from '../../buttons';
import Card from '../../Card';

export const Wrapper = styled.div`
display: flex;
Expand Down Expand Up @@ -37,10 +37,11 @@ export const StyledCard = styled(Card)`
`};
`;

export const FiltersButton = styled(IconButton)`
svg {
color: ${({ theme }) => theme.palette.primary.light};
}
export const FiltersButton = styled(Button)`
min-width: 0;
width: 55px;
height: 55px;
padding: 10px;
`;

export const EditButton = styled(IconButton)`
Expand Down Expand Up @@ -81,7 +82,7 @@ export const TitleWrapper = styled.div`
export const FiltersContainer = styled.div`
display: flex;
width: 100%;
padding: 40px 20px;
padding: 40px 0;
justify-content: space-between;
align-items: center;
max-width: 740px;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import React, { Children, cloneElement, isValidElement } from 'react';
import { useTranslation } from 'react-i18next';
import { useQuery } from 'react-query';
import { useHistory } from 'react-router-dom';

import { routes } from '../../constants';
import { EditIcon, FiltersIcon } from '../../icons';
import { ApiList } from '../../interfaces/api.types';
import { getLabelFromSource } from '../../utils';
import { BaseFieldProps, BaseRecordField } from '../fields/Fields.types';
import { routes } from '../../../constants';
import { EditIcon, FiltersIcon } from '../../../icons';
import { ApiList } from '../../../interfaces/api.types';
import { ThemeType } from '../../../theme/Theme';
import { BaseFieldProps, BaseRecordField } from '../../fields/Fields.types';
import {
CardFieldContainer,
CardsWrapper,
Expand All @@ -23,6 +24,7 @@ const CardList = ({ children, resource }: CardListProps) => {
const queryResult = useQuery<ApiList<BaseRecordField>>(`/${resource}`);
const records = queryResult.data?.data;
const history = useHistory();
const { t } = useTranslation();

const onClickEdit = (id: string) => {
// TODO: move to user details
Expand All @@ -35,7 +37,7 @@ const CardList = ({ children, resource }: CardListProps) => {
<FiltersContainer>
{/* TODO: add search input */}
<p>Search</p>
<FiltersButton>
<FiltersButton colorVariant={ThemeType.dark}>
<FiltersIcon />
</FiltersButton>
</FiltersContainer>
Expand All @@ -58,7 +60,7 @@ const CardList = ({ children, resource }: CardListProps) => {
return <TitleWrapper>{cloneElement(child, { record })}</TitleWrapper>;
}

const internalLabel = label || getLabelFromSource(source || '');
const internalLabel = label || t(`baseApiFields.${source}` as never);

return (
<CardFieldContainer key={`${id}-${source}`}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import styled from 'styled-components';

import { IconButton } from '../buttons';
import Card from '../Card';
import { IconButton } from '../../buttons';
import Card from '../../Card';

export const StyledCard = styled(Card)<{ isBulkActionsOpen: boolean }>`
padding: 0;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { MouseEvent, ReactNode } from 'react';

export interface ListProps {
export interface DetailedListProps {
onRowClick?: (event: MouseEvent) => void;
resource: string;
children: ReactNode;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import styled from 'styled-components';

import { IconButton } from '../../buttons';
import { IconButton } from '../../../buttons';

export const PaginationWrapper = styled.div`
border-top: 1px solid ${({ theme }) => theme.palette.divider.paper};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { useMemo } from 'react';
import { Select } from 'src/elements';
import { useTranslation } from 'react-i18next';
import { Select } from 'src/elements/index';

import {
PageNavigation,
Expand All @@ -17,6 +18,8 @@ const Pagination = ({
setCurrentPage,
totalRecords,
}: PaginationProps) => {
const { t } = useTranslation();

const totalPages = useMemo((): number => Math.ceil(totalRecords / perPage), [
perPage,
totalRecords,
Expand All @@ -25,7 +28,7 @@ const Pagination = ({
return (
<PaginationWrapper>
<PerPageWrapper>
<PerPageLabel>Rows per page:</PerPageLabel>
<PerPageLabel>{t('lists.detailedList.perPage')}:</PerPageLabel>
<Select<number>
value={perPage}
onChange={(selectedOption) => setPerPage(selectedOption.value)}
Expand All @@ -36,14 +39,15 @@ const Pagination = ({
</Select>
</PerPageWrapper>
<TotalsLabel>
{perPage * currentPage - perPage + 1}-{Math.min(perPage * currentPage, totalRecords)} of{' '}
{perPage * currentPage - perPage + 1}-{Math.min(perPage * currentPage, totalRecords)}&nbsp;
{t('lists.detailedList.ofTotal')}&nbsp;
{totalRecords}
</TotalsLabel>
{totalPages > 1 && (
<>
{currentPage !== 1 && (
<PaginationButton color="primary" onClick={() => setCurrentPage(currentPage - 1)}>
prev
{t('lists.detailedList.prev')}
</PaginationButton>
)}
<PageNavigation>
Expand All @@ -61,7 +65,7 @@ const Pagination = ({
})}
{currentPage !== totalPages && (
<PaginationButton color="primary" onClick={() => setCurrentPage(currentPage + 1)}>
next
{t('lists.detailedList.next')}
</PaginationButton>
)}
</PageNavigation>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import React, {
useMemo,
useState,
} from 'react';
import { useTranslation } from 'react-i18next';
import { useMutation, useQuery } from 'react-query';

import { CancelIcon, TrashIcon } from '../../icons';
import { ApiList } from '../../interfaces/api.types';
import { getLabelFromSource } from '../../utils';
import { BaseFieldProps, BaseRecordField } from '../fields/Fields.types';
import { Checkbox } from '../inputs';
import { CancelIcon, TrashIcon } from '../../../icons';
import { ApiList } from '../../../interfaces/api.types';
import { BaseFieldProps, BaseRecordField } from '../../fields/Fields.types';
import { Checkbox } from '../../inputs';
import {
BulkActionsWrapper,
BulkCancelButton,
Expand All @@ -26,19 +26,20 @@ import {
TableHeader,
TableHeaderCheckbox,
TableRow,
} from './List.styled';
import { ListProps } from './List.types';
} from './DetailedList.styled';
import { DetailedListProps } from './DetailedList.types';
import Pagination from './Pagination';

const List = ({ onRowClick, children, resource }: ListProps) => {
const { data: queryResult } = useQuery<ApiList<BaseRecordField>>(`/${resource}`);
const DetailedList = ({ onRowClick, children, resource }: DetailedListProps) => {
const removeUser = async (id: string) => {
console.log('Removed:', id);
};
const deleteMutation = useMutation(removeUser);
const { data: queryResult } = useQuery<ApiList<BaseRecordField>>(`/${resource}`);
const [selectedRows, setSelectedRows] = useState<Array<string>>([]);
const [perPage, setPerPage] = useState<number>(25);
const [currentPage, setCurrentPage] = useState<number>(1);
const { t } = useTranslation();

const totalRecords = useMemo((): number => {
if (queryResult) {
Expand Down Expand Up @@ -119,11 +120,12 @@ const List = ({ onRowClick, children, resource }: ListProps) => {
<BulkCancelButton onClick={unselectAllRows}>
<CancelIcon />
</BulkCancelButton>
{selectedRows.length} {selectedRows.length > 1 ? 'items' : 'item'} selected
{selectedRows.length}&nbsp;
{selectedRows.length > 1 ? t('lists.detailedList.items') : t('lists.detailedList.item')}
</BulkCancelWrapper>
<DeleteButton color="red" onClick={removeSelectedItems}>
<TrashIcon />
Delete
{t('actions.delete')}
</DeleteButton>
</BulkActionsWrapper>
<Table>
Expand All @@ -134,7 +136,7 @@ const List = ({ onRowClick, children, resource }: ListProps) => {
</TableHeaderCheckbox>
{headers.map(({ label, source }) => (
<TableHeader key={label || source}>
{label || getLabelFromSource(source || '')}
{label || t(`baseApiFields.${source}` as never)}
</TableHeader>
))}
</TableRow>
Expand Down Expand Up @@ -176,6 +178,6 @@ const List = ({ onRowClick, children, resource }: ListProps) => {
);
};

List.displayName = 'List';
DetailedList.displayName = 'DetailedList';

export default List;
export default DetailedList;
2 changes: 2 additions & 0 deletions packages/client/src/elements/lists/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default as CardList } from './CardList';
export { default as DetailedList } from './DetailedList';
21 changes: 21 additions & 0 deletions packages/client/src/i18n/resources/en.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,37 @@
const en = {
translation: {
baseApiFields: {
id: 'Id',
email: 'Email',
createdAt: 'Created at',
updatedAt: 'Updated at',
},
user: {
user: 'User',
firstName: 'First name',
lastName: 'Last name',
password: 'Password',
},
actions: {
back: 'Back',
delete: 'Delete',
},
menu: {
history: 'History',
dashboard: 'Dashboard',
settings: 'Settings',
admin: 'Admin',
},
lists: {
detailedList: {
items: 'items',
item: 'item',
perPage: 'Rows per page',
ofTotal: 'of',
next: 'next',
prev: 'prev',
},
},
form: {
errors: {
onSubmitError: 'Oops! Something went wrong. Operation failed.',
Expand Down
21 changes: 21 additions & 0 deletions packages/client/src/i18n/resources/pl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,38 @@ import { TranslationStructure } from './en';

const pl: TranslationStructure = {
translation: {
baseApiFields: {
id: 'Id',
email: 'Email',
createdAt: 'Data utworzenia',
updatedAt: 'Data aktualizacji',
},
user: {
user: 'Użytkownik',
firstName: 'Imię',
lastName: 'Nazwisko',
password: 'Hasło',
},
actions: {
back: 'Wróć',
delete: 'Usuń',
},
menu: {
history: 'Historia',
dashboard: 'Pulpit',
settings: 'Ustawienia',
admin: 'Admin',
},
lists: {
detailedList: {
items: 'wierszy',
item: 'wiersz',
perPage: 'Wierszy na stronę',
ofTotal: 'z',
next: 'następny',
prev: 'poprzedni',
},
},
form: {
errors: {
onSubmitError: 'Oops! Coś poszło nie tak.',
Expand Down
Loading

0 comments on commit 7a6b8cf

Please sign in to comment.