Last active
November 3, 2022 08:19
-
-
Save zigcccc/a945a47d28f6a573a731e6069cda5ef6 to your computer and use it in GitHub Desktop.
Revisions
-
zigcccc revised this gist
Nov 3, 2022 . No changes.There are no files selected for viewing
-
zigcccc revised this gist
Nov 3, 2022 . 4 changed files with 140 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,5 @@ // Organism (utilizes Table component which is a molecule, but is not strictly tied to a single feature) /** * The goal of this component is to: * - render the table data This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,62 @@ // Sub-component of the PageableTable organism component const PageableTableBody = ({ components, hasEmptyResults, hasEmptySearchResults, hasError, isLoading, isSearching, onRefresh, params, ...rest }) => { // Components setup for different Table empty states. We use either component provided by the prop or the // default one. We also memoize this component, since it will (almost) never change dynamically. const TableLoadingState = React.useMemo(() => components?.LoadingState || DefaultTableLoadingState, [components]); const TableErrorState = React.useMemo(() => components?.ErrorState || DefaultTableErrorState, [components]); const TableEmptyResults = React.useMemo(() => components?.EmptyResults || DefaultTableEmptyResults, [components]); /** * The top-most check. Whenever we are in a loading or searching state, we want to display * the table loading state component. */ if (isLoading || isSearching) { return ( <TableBodyEmptyStateBase> <TableLoadingState /> </TableBodyEmptyStateBase> ); } /** * If we have an error (and we are currently not loading anything), we display the table * error state component. */ if (hasError) { return ( <TableBodyEmptyStateBase> <TableErrorState onRefresh={onRefresh} /> </TableBodyEmptyStateBase> ); } /** * If we have empty search results, we want to display empty search results * state. IMPORTANT: This check must happen before the generic empty results check * since by design, empty search results also means empty results, but not vice versa. */ if (hasEmptySearchResults || hasEmptyResults) { return ( <TableBodyEmptyStateBase> <TableEmptyResults onRefresh={onRefresh} searchKey={params?.searchKey} /> </TableBodyEmptyStateBase> ); } /** * If none of the empty state conditions are met, we return * the actual table component */ return <Table {...rest} />; }; This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,5 @@ // System / template (strictly tied to "Products" feature) const ProductsTable = ({ fetchProducts, products, ...rest }) => { const history = useHistory(); @@ -18,4 +20,4 @@ const ProductsTable = ({ fetchProducts, products, ...rest }) => { {...rest} /> ); }; This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,73 @@ // Molecule (since it utilizes Text component, which is an atom) const Table = ({ cellPaddingSize, columns, data, hideHeader, onRowClick }) => { // Data passed to the useTable hook needs to be memoized // to avaid performance leaks const memoColumns = React.useMemo(() => columns, [columns]); const memoData = React.useMemo(() => data, [data]); const numOfColumns = React.useMemo(() => memoColumns.length, [memoColumns]); const defaultTableCellSize = getDefaultTableCellSize(numOfColumns); const handleRowClick = (row) => { onRowClick?.(row); }; const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } = useTable({ columns: memoColumns, data: memoData, }); return ( <div className="table"> <table className="table__table" {...getTableProps()}> {!hideHeader && ( <thead className="table__head"> {headerGroups.map((headerGroup) => ( // Apply the header row props <tr className="table__row" {...headerGroup.getHeaderGroupProps()}> {headerGroup.headers.map((column) => ( <th className={classNames('table__cell', cellPaddingSize, column.size || defaultTableCellSize, { [column.align]: Boolean(column.align), [`${column.alignHeader}--important`]: Boolean(column.alignHeader), })} {...column.getHeaderProps()} > <Text.Regular numOfLines={1}>{column.render('Header')}</Text.Regular> </th> ))} </tr> ))} </thead> )} <tbody className="table__body" {...getTableBodyProps()}> {rows.map((row) => { // Prepare the row for display prepareRow(row); return ( // Apply the row props <tr className={classNames('table__row table__row--body', { 'table__row--clickable': Boolean(onRowClick) })} onClick={() => handleRowClick(row)} {...row.getRowProps()} > {row.cells.map((cell) => ( <td className={classNames('table__cell', cellPaddingSize, cell.column.size || defaultTableCellSize, { [cell.column.align]: Boolean(cell.column.align), })} {...cell.getCellProps()} > {cell.render('Cell')} </td> ))} </tr> ); })} </tbody> </table> </div> ); }; -
zigcccc created this gist
Nov 3, 2022 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,82 @@ /** * The goal of this component is to: * - render the table data * - handle initial API call + any additional page and/or search related API calls * - render table header & footer with pagination and actions */ const PageableTable = ({ columns, components, data, filters, hasError, isLoading, onFetchData, onRowClick, pagination, tableProps: tablePropsBase, title, }) => { const { values: params } = useFormState(); // Joined Table props const tableProps = { ...tablePropsBase, columns, data, onRowClick }; const emptyResults = hasEmptyResults({ data, isLoading }); const emptySearchResults = hasEmptySearchResults({ data, isLoading, params }); // We are setting isSearching to true if we are in a loading state and the value // for the search Query exists const isSearching = isLoading && Boolean(params.searchKey); // Props shared between all of the PageableTable child components const commonProps = { isLoading, isSearching }; const handleRefresh = () => { onFetchData({ page: pagination.currentPage, params }); }; const handleFetchPreviousPage = () => { if (pagination.hasPreviousPage) { onFetchData({ page: pagination.currentPage - 1, params }); } }; const handleFetchNextPage = () => { if (pagination.hasNextPage) { onFetchData({ page: pagination.currentPage + 1, params }); } }; return ( <div className="pageable-table"> <TableActionbar {...commonProps} filters={filters} hasError={hasError} onGoToNextPage={handleFetchNextPage} onGoToPreviousPage={handleFetchPreviousPage} onRefresh={handleRefresh} pagination={pagination} title={title} /> <PageableTableBody {...commonProps} {...tableProps} components={components} hasEmptyResults={emptyResults} hasEmptySearchResults={emptySearchResults} hasError={hasError} onRefresh={handleRefresh} params={params} /> <TableFooter {...commonProps} hasError={hasError} onGoToNextPage={handleFetchNextPage} onGoToPreviousPage={handleFetchPreviousPage} pagination={pagination} /> </div> ); }; This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,21 @@ const ProductsTable = ({ fetchProducts, products, ...rest }) => { const history = useHistory(); const handleEditProductClick = (row) => { history.push(getJoinedPath('products', row.original.id)); }; const columns = getProductsTableColumns({ onEditProduct: handleEditProductClick }); return ( <PageableTable columns={columns} components={{ ErrorState: ProductsTableErrorState, EmptyResults: ProductsTableEmptyState }} data={products} onFetchData={fetchProducts} onRowClick={handleEditProductClick} title="Seznam izdelkov" {...rest} /> ); };