Skip to content

Commit

Permalink
Merge pull request #336 from City-of-Helsinki/fix/LINK-1765_refactor-…
Browse files Browse the repository at this point in the history
…tables

LINK-1765, LINK-1766 | Refactor tables
  • Loading branch information
jorilindell committed Mar 4, 2024
2 parents b3b2a2f + 2003c73 commit e20810d
Show file tree
Hide file tree
Showing 72 changed files with 1,315 additions and 1,974 deletions.
45 changes: 33 additions & 12 deletions src/common/components/table/CustomTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,19 @@ import 'hds-core';
import { TableProps as HdsTableProps } from 'hds-react';
import React, { FC, PropsWithChildren } from 'react';

import LoadingSpinner from '../loadingSpinner/LoadingSpinner';
import NoResults from './noResults/NoResults';
import styles from './table.module.scss';
import { TableContainer } from './tableContainer/TableContainer';
import TableWrapper, { TableWrapperProps } from './tableWrapper/TableWrapper';

type TableProps = React.ComponentPropsWithoutRef<'table'> & {
className?: string;
} & Pick<
loading?: boolean;
noResultsText?: string;
showNoResults?: boolean;
} & TableWrapperProps &
Pick<
HdsTableProps,
'caption' | 'dataTestId' | 'dense' | 'variant' | 'verticalLines' | 'zebra'
>;
Expand All @@ -20,25 +27,39 @@ const CustomTable: FC<PropsWithChildren<TableProps>> = ({
children,
dataTestId = 'hds-table-data-testid',
dense = false,
hasActionButtons,
id = 'hds-table-id',
inlineWithBackground,
loading,
noResultsText,
showNoResults,
variant,
verticalLines = false,
zebra = false,
wrapperClassName,
...rest
}) => {
return (
<TableContainer
variant={variant}
dataTestId={dataTestId}
dense={dense}
id={id}
zebra={zebra}
verticalLines={verticalLines}
{...rest}
<TableWrapper
hasActionButtons={hasActionButtons}
inlineWithBackground={inlineWithBackground}
wrapperClassName={wrapperClassName}
>
{caption && <caption className={styles.caption}>{caption}</caption>}
{children}
</TableContainer>
<TableContainer
variant={variant}
dataTestId={dataTestId}
dense={dense}
id={id}
zebra={zebra}
verticalLines={verticalLines}
{...rest}
>
{caption && <caption className={styles.caption}>{caption}</caption>}
{children}
</TableContainer>
{loading && <LoadingSpinner isLoading={true} />}
{!loading && showNoResults && <NoResults noResultsText={noResultsText} />}
</TableWrapper>
);
};

Expand Down
184 changes: 30 additions & 154 deletions src/common/components/table/Table.tsx
Original file line number Diff line number Diff line change
@@ -1,171 +1,47 @@
/* eslint-disable max-len */
// import core base styles
import 'hds-core';

import { TableProps as HdsTableProps } from 'hds-react';
import React, { useMemo, useState } from 'react';
import { Table as HdsTable, TableProps as HdsTableProps } from 'hds-react';
import { FC } from 'react';

import { useTheme } from '../../../domain/app/theme/Theme';
import LoadingSpinner from '../loadingSpinner/LoadingSpinner';
import BodyRow from './bodyRow/BodyRow';
import HeaderRow from './headerRow/HeaderRow';
import NoResultsRow from './noResultsRow/NoResultsRow';
import { SortingHeaderCell } from './sortingHeaderCell/SortingHeaderCell';
import styles from './table.module.scss';
import TableBody from './tableBody/TableBody';
import { TableContainer } from './tableContainer/TableContainer';
import { Header, Order } from './types';
import { processRows } from './utils';

export type GetRowPropsFunc = (
item: object
) => React.ComponentPropsWithoutRef<'tr'>;
import NoResults from './noResults/NoResults';
import TableWrapper, { TableWrapperProps } from './tableWrapper/TableWrapper';

type TableProps = {
cols: Header[];
getRowProps?: GetRowPropsFunc;
loading?: boolean;
noResultsText?: string;
onRowClick?: (item: object) => void;
showNoResultsRow?: boolean;
} & Omit<
HdsTableProps,
| 'ariaLabelCheckboxSelection'
| 'checkboxSelection'
| 'clearSelectionsText'
| 'cols'
| 'customActionButtons'
| 'heading'
| 'headingAriaLevel'
| 'headingClassName'
| 'headingId'
| 'selectAllRowsText'
| 'selectedRows'
| 'setSelectedRows'
| 'theme'
| 'verticalHeaders'
>;
} & TableWrapperProps &
HdsTableProps;

const Table = ({
ariaLabelSortButtonAscending,
ariaLabelSortButtonDescending,
ariaLabelSortButtonUnset = '',
caption,
cols,
dataTestId = 'hds-table-data-testid',
dense = false,
getRowProps,
id = 'hds-table-id',
indexKey,
initialSortingColumnKey,
initialSortingOrder,
const Table: FC<TableProps> = ({
hasActionButtons,
inlineWithBackground,
loading,
noResultsText,
onRowClick,
onSort,
renderIndexCol = true,
rows,
showNoResultsRow = true,
textAlignContentRight = false,
variant = 'dark',
verticalLines = false,
zebra = false,
...rest
}: TableProps) => {
const [sorting, setSorting] = useState<string | undefined>(
initialSortingColumnKey
);
const [order, setOrder] = useState<Order | undefined>(initialSortingOrder);

const setSortingAndOrder = (colKey: string): void => {
if (sorting === colKey) {
setOrder(order === 'desc' ? 'asc' : 'desc');
} else {
setOrder('asc');
}
setSorting(colKey);
};

const processedRows = useMemo(
() => processRows(rows, order, sorting, cols),
[rows, sorting, order, cols]
);

const visibleColumns = renderIndexCol
? cols
: cols.filter((column) => column.key !== indexKey);

variant = 'light',
wrapperClassName,
...props
}) => {
const { theme } = useTheme();
return (
<>
<TableContainer
<TableWrapper
hasActionButtons={hasActionButtons}
inlineWithBackground={inlineWithBackground}
wrapperClassName={wrapperClassName}
>
<HdsTable
{...props}
theme={theme.table.variant?.[variant]}
rows={loading ? [] : rows}
variant={variant}
dataTestId={dataTestId}
dense={dense}
id={id}
zebra={zebra}
verticalLines={verticalLines}
{...rest}
>
{caption && <caption className={styles.caption}>{caption}</caption>}
<thead>
<HeaderRow>
{visibleColumns.map((column) => {
if (column.isSortable) {
return (
<SortingHeaderCell
key={column.key}
className={column.className}
colKey={column.key}
title={column.headerName}
ariaLabelSortButtonUnset={ariaLabelSortButtonUnset}
ariaLabelSortButtonAscending={ariaLabelSortButtonAscending}
ariaLabelSortButtonDescending={
ariaLabelSortButtonDescending
}
setSortingAndOrder={setSortingAndOrder}
onSort={onSort}
order={sorting === column.key ? (order as Order) : 'unset'}
sortIconType={column.sortIconType ?? 'string'}
/>
);
}
return (
<th className={column.className} key={column.key} scope="col">
{column.headerName}
</th>
);
})}
</HeaderRow>
</thead>
<TableBody textAlignContentRight={textAlignContentRight}>
{loading ? (
<tr>
<td colSpan={visibleColumns.length}>
<LoadingSpinner isLoading={true} />
</td>
</tr>
) : (
<>
{processedRows.map((row, index) => (
<BodyRow
cols={visibleColumns}
getRowProps={getRowProps}
index={index}
key={row[indexKey as keyof typeof row]}
onRowClick={onRowClick}
row={row}
/>
))}
{showNoResultsRow && !processedRows.length && (
<NoResultsRow
colSpan={visibleColumns.length}
noResultsText={noResultsText}
/>
)}
</>
)}
</TableBody>
</TableContainer>
</>
/>
{loading && <LoadingSpinner isLoading={true} />}
{!loading && showNoResultsRow && !rows.length && (
<NoResults noResultsText={noResultsText} />
)}
</TableWrapper>
);
};

Expand Down
Loading

0 comments on commit e20810d

Please sign in to comment.