From fe183e0b702b3e1f431c8eb30c584fe7c2294b1d Mon Sep 17 00:00:00 2001 From: Aleksandr Gumroian Date: Mon, 4 Nov 2024 22:27:21 +0100 Subject: [PATCH] Add RichTable component with header, body, and pagination --- src/common/RichTable/RichTable.js | 66 +++++++++ src/common/RichTable/RichTableBody.js | 33 +++++ src/common/RichTable/RichTableHeader.js | 73 ++++++++++ src/common/RichTable/RichTablePagination.js | 153 ++++++++++++++++++++ src/index.js | 1 + 5 files changed, 326 insertions(+) create mode 100644 src/common/RichTable/RichTable.js create mode 100644 src/common/RichTable/RichTableBody.js create mode 100644 src/common/RichTable/RichTableHeader.js create mode 100644 src/common/RichTable/RichTablePagination.js diff --git a/src/common/RichTable/RichTable.js b/src/common/RichTable/RichTable.js new file mode 100644 index 0000000..43cabc2 --- /dev/null +++ b/src/common/RichTable/RichTable.js @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2019-2024 CZ.NIC z.s.p.o. (https://www.nic.cz/) + * + * This is free software, licensed under the GNU General Public License v3. + * See /LICENSE for more information. + */ + +import React, { useMemo, useState } from "react"; + +import { + flexRender, + getCoreRowModel, + getSortedRowModel, + getPaginationRowModel, + useReactTable, +} from "@tanstack/react-table"; + +import RichTableBody from "./RichTableBody"; +import RichTableHeader from "./RichTableHeader"; +import RichTablePagination from "./RichTablePagination"; + +const fallbackData = []; + +const RichTable = ({ + columns, + data, + withPagination, + pageSize = 10, + pageIndex = 0, +}) => { + const tableColumns = useMemo(() => columns, []); + const [tableData, _] = useState(data ?? fallbackData); + const [sorting, setSorting] = useState([]); + const [pagination, setPagination] = useState({ + pageIndex, + pageSize, + }); + + const table = useReactTable({ + columns: tableColumns, + data: tableData, + getCoreRowModel: getCoreRowModel(), + getSortedRowModel: getSortedRowModel(), + getPaginationRowModel: getPaginationRowModel(), + onPaginationChange: setPagination, + onSortingChange: setSorting, + state: { + sorting, + pagination, + }, + }); + + return ( +
+ + + +
+ {withPagination && ( + + )} +
+ ); +}; + +export default RichTable; diff --git a/src/common/RichTable/RichTableBody.js b/src/common/RichTable/RichTableBody.js new file mode 100644 index 0000000..b02d6bc --- /dev/null +++ b/src/common/RichTable/RichTableBody.js @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2019-2024 CZ.NIC z.s.p.o. (https://www.nic.cz/) + * + * This is free software, licensed under the GNU General Public License v3. + * See /LICENSE for more information. + */ + +import React from "react"; + +const RichTableBody = ({ table, flexRender }) => { + return ( + + {table.getRowModel().rows.map((row) => { + return ( + + {row.getVisibleCells().map((cell) => { + return ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext() + )} + + ); + })} + + ); + })} + + ); +}; + +export default RichTableBody; diff --git a/src/common/RichTable/RichTableHeader.js b/src/common/RichTable/RichTableHeader.js new file mode 100644 index 0000000..3abdf1c --- /dev/null +++ b/src/common/RichTable/RichTableHeader.js @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2019-2024 CZ.NIC z.s.p.o. (https://www.nic.cz/) + * + * This is free software, licensed under the GNU General Public License v3. + * See /LICENSE for more information. + */ + +import React from "react"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { + faSquareCaretUp, + faSquareCaretDown, +} from "@fortawesome/free-solid-svg-icons"; + +const RichTableHeader = ({ table, flexRender }) => { + const getThTitle = (header) => + header.column.getCanSort() + ? header.column.getNextSortingOrder() === "asc" + ? _("Sort ascending") + : header.column.getNextSortingOrder() === "desc" + ? _("Sort descending") + : _("Clear sort") + : undefined; + + return ( + + {table.getHeaderGroups().map((headerGroup) => ( + + {headerGroup.headers.map((header) => { + return ( + + {header.isPlaceholder ? null : ( + + )} + + ); + })} + + ))} + + ); +}; + +export default RichTableHeader; diff --git a/src/common/RichTable/RichTablePagination.js b/src/common/RichTable/RichTablePagination.js new file mode 100644 index 0000000..bbafb96 --- /dev/null +++ b/src/common/RichTable/RichTablePagination.js @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2019-2024 CZ.NIC z.s.p.o. (https://www.nic.cz/) + * + * This is free software, licensed under the GNU General Public License v3. + * See /LICENSE for more information. + */ + +import React from "react"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { + faAngleLeft, + faAnglesLeft, + faAngleRight, + faAnglesRight, +} from "@fortawesome/free-solid-svg-icons"; + +const RichTablePagination = ({ table, tablePageSize }) => { + const prevPagBtnDisabled = !table.getCanPreviousPage(); + const nextPagBtnDisabled = !table.getCanNextPage(); + + return ( + + ); +}; + +export default RichTablePagination; diff --git a/src/index.js b/src/index.js index 4e7839f..8052fb1 100644 --- a/src/index.js +++ b/src/index.js @@ -43,6 +43,7 @@ export { Modal, ModalBody, ModalFooter, ModalHeader } from "./bootstrap/Modal"; export { default as RebootButton } from "./common/RebootButton"; export { default as WiFiSettings } from "./common/WiFiSettings/WiFiSettings"; export { default as ResetWiFiSettings } from "./common/WiFiSettings/ResetWiFiSettings"; +export { default as RichTable } from "./common/RichTable/RichTable"; // Form export { default as ForisForm } from "./form/components/ForisForm"; export {