foris 6.4.0 → 6.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/common/ActionButtonWithModal/ActionButtonWithModal.js +135 -0
  2. package/common/ActionButtonWithModal/ActionButtonWithModal.md +39 -0
  3. package/common/RichTable/RichTable.js +84 -0
  4. package/common/RichTable/RichTable.md +135 -0
  5. package/common/RichTable/RichTableBody.js +48 -0
  6. package/common/RichTable/RichTableHeader.js +96 -0
  7. package/common/RichTable/RichTablePagination.js +128 -0
  8. package/foris-6.5.0.tgz +0 -0
  9. package/index.js +2 -1
  10. package/package.json +2 -1
  11. package/testUtils/customTestRender.js +1 -1
  12. package/translations/cs/LC_MESSAGES/forisjs.po +79 -21
  13. package/translations/da/LC_MESSAGES/forisjs.po +75 -16
  14. package/translations/de/LC_MESSAGES/forisjs.po +79 -21
  15. package/translations/el/LC_MESSAGES/forisjs.po +76 -19
  16. package/translations/en/LC_MESSAGES/forisjs.po +75 -16
  17. package/translations/es/LC_MESSAGES/forisjs.po +79 -21
  18. package/translations/fi/LC_MESSAGES/forisjs.po +75 -16
  19. package/translations/fo/LC_MESSAGES/forisjs.po +75 -16
  20. package/translations/forisjs.pot +61 -17
  21. package/translations/fr/LC_MESSAGES/forisjs.po +79 -21
  22. package/translations/hr/LC_MESSAGES/forisjs.po +75 -16
  23. package/translations/hu/LC_MESSAGES/forisjs.po +76 -16
  24. package/translations/it/LC_MESSAGES/forisjs.po +75 -16
  25. package/translations/ja/LC_MESSAGES/forisjs.po +76 -17
  26. package/translations/ko/LC_MESSAGES/forisjs.po +75 -16
  27. package/translations/lt/LC_MESSAGES/forisjs.po +75 -16
  28. package/translations/nb_NO/LC_MESSAGES/forisjs.po +78 -21
  29. package/translations/nl/LC_MESSAGES/forisjs.po +78 -22
  30. package/translations/pl/LC_MESSAGES/forisjs.po +79 -21
  31. package/translations/pt_BR/LC_MESSAGES/forisjs.po +77 -20
  32. package/translations/ro/LC_MESSAGES/forisjs.po +75 -16
  33. package/translations/ru/LC_MESSAGES/forisjs.po +79 -21
  34. package/translations/sk/LC_MESSAGES/forisjs.po +79 -21
  35. package/translations/sv/LC_MESSAGES/forisjs.po +78 -21
  36. package/common/RebootButton.js +0 -80
  37. package/foris-6.4.0.tgz +0 -0
  38. /package/testUtils/{cutomizationContextMock.js → customizationContextMock.js} +0 -0
@@ -0,0 +1,135 @@
1
+ /*
2
+ * Copyright (C) 2019-2024 CZ.NIC z.s.p.o. (https://www.nic.cz/)
3
+ *
4
+ * This is free software, licensed under the GNU General Public License v3.
5
+ * See /LICENSE for more information.
6
+ */
7
+
8
+ import React, { useState, useEffect } from "react";
9
+
10
+ import PropTypes from "prop-types";
11
+
12
+ import { useAPIPost } from "../../api/hooks";
13
+ import { API_STATE } from "../../api/utils";
14
+ import Button from "../../bootstrap/Button";
15
+ import {
16
+ Modal,
17
+ ModalHeader,
18
+ ModalBody,
19
+ ModalFooter,
20
+ } from "../../bootstrap/Modal";
21
+ import { useAlert } from "../../context/alertContext/AlertContext";
22
+
23
+ ActionButtonWithModal.propTypes = {
24
+ /** Component that triggers the action. */
25
+ actionTrigger: PropTypes.elementType.isRequired,
26
+ /** URL to send the action to. */
27
+ actionUrl: PropTypes.string.isRequired,
28
+ /** Title of the modal. */
29
+ modalTitle: PropTypes.string.isRequired,
30
+ /** Message of the modal. */
31
+ modalMessage: PropTypes.string.isRequired,
32
+ /** Text of the action button in the modal. */
33
+ modalActionText: PropTypes.string,
34
+ /** Props for the action button in the modal. */
35
+ modalActionProps: PropTypes.object,
36
+ /** Message to display on successful action. */
37
+ successMessage: PropTypes.string,
38
+ /** Message to display on failed action. */
39
+ errorMessage: PropTypes.string,
40
+ };
41
+
42
+ function ActionButtonWithModal({
43
+ actionTrigger: ActionTriggerComponent,
44
+ actionUrl,
45
+ modalTitle,
46
+ modalMessage,
47
+ modalActionText,
48
+ modalActionProps,
49
+ successMessage,
50
+ errorMessage,
51
+ }) {
52
+ const [triggered, setTriggered] = useState(false);
53
+ const [modalShown, setModalShown] = useState(false);
54
+ const [triggerActionStatus, triggerAction] = useAPIPost(actionUrl);
55
+
56
+ const [setAlert] = useAlert();
57
+ useEffect(() => {
58
+ if (triggerActionStatus.state === API_STATE.SUCCESS) {
59
+ setAlert(
60
+ successMessage || _("Action successful."),
61
+ API_STATE.SUCCESS
62
+ );
63
+ }
64
+ if (triggerActionStatus.state === API_STATE.ERROR) {
65
+ setAlert(errorMessage || _("Action failed."));
66
+ }
67
+ }, [triggerActionStatus, setAlert, successMessage, errorMessage]);
68
+
69
+ const actionHandler = () => {
70
+ setTriggered(true);
71
+ triggerAction();
72
+ setModalShown(false);
73
+ };
74
+
75
+ return (
76
+ <>
77
+ <ActionModal
78
+ shown={modalShown}
79
+ setShown={setModalShown}
80
+ onAction={actionHandler}
81
+ title={modalTitle}
82
+ message={modalMessage}
83
+ actionText={modalActionText}
84
+ actionProps={modalActionProps}
85
+ />
86
+ <ActionTriggerComponent
87
+ loading={triggered}
88
+ disabled={triggered}
89
+ onClick={() => setModalShown(true)}
90
+ />
91
+ </>
92
+ );
93
+ }
94
+
95
+ ActionModal.propTypes = {
96
+ shown: PropTypes.bool.isRequired,
97
+ setShown: PropTypes.func.isRequired,
98
+ onAction: PropTypes.func.isRequired,
99
+ title: PropTypes.string.isRequired,
100
+ message: PropTypes.string.isRequired,
101
+ actionText: PropTypes.string,
102
+ actionProps: PropTypes.object,
103
+ };
104
+
105
+ function ActionModal({
106
+ shown,
107
+ setShown,
108
+ onAction,
109
+ title,
110
+ message,
111
+ actionText,
112
+ actionProps,
113
+ }) {
114
+ return (
115
+ <Modal shown={shown} setShown={setShown}>
116
+ <ModalHeader setShown={setShown} title={title} />
117
+ <ModalBody>
118
+ <p className="mb-0">{message}</p>
119
+ </ModalBody>
120
+ <ModalFooter>
121
+ <Button
122
+ className="btn-secondary"
123
+ onClick={() => setShown(false)}
124
+ >
125
+ {_("Cancel")}
126
+ </Button>
127
+ <Button onClick={onAction} {...actionProps}>
128
+ {actionText || _("Confirm")}
129
+ </Button>
130
+ </ModalFooter>
131
+ </Modal>
132
+ );
133
+ }
134
+
135
+ export default ActionButtonWithModal;
@@ -0,0 +1,39 @@
1
+ RebootButton component is a button that opens a modal dialog to confirm the
2
+ reboot of the device.
3
+
4
+ ## Usage
5
+
6
+ ```jsx
7
+ import React, { useEffect, createContext } from "react";
8
+
9
+ import Button from "../../bootstrap/Button";
10
+ import { AlertContextProvider } from "../../context/alertContext/AlertContext";
11
+ import ActionButtonWithModal from "./ActionButtonWithModal";
12
+
13
+ window.AlertContext = React.createContext();
14
+
15
+ const RebootButtonExample = () => {
16
+ const ActionButton = (props) => {
17
+ return <Button {...props}>Action</Button>;
18
+ };
19
+
20
+ return (
21
+ <AlertContextProvider>
22
+ <div id="modal-container" />
23
+ <div id="alert-container" />
24
+ <ActionButtonWithModal
25
+ actionTrigger={ActionButton}
26
+ actionUrl="/reforis/api/action"
27
+ modalTitle="Warning!"
28
+ modalMessage="Are you sure you want to perform this action?"
29
+ modalActionText="Confirm action"
30
+ modalActionProps={{ className: "btn-danger" }}
31
+ successMessage="Action request succeeded."
32
+ errorMessage="Action request failed."
33
+ />
34
+ </AlertContextProvider>
35
+ );
36
+ };
37
+
38
+ <RebootButtonExample />;
39
+ ```
@@ -0,0 +1,84 @@
1
+ /*
2
+ * Copyright (C) 2019-2024 CZ.NIC z.s.p.o. (https://www.nic.cz/)
3
+ *
4
+ * This is free software, licensed under the GNU General Public License v3.
5
+ * See /LICENSE for more information.
6
+ */
7
+
8
+ import React, { useMemo, useState } from "react";
9
+
10
+ import {
11
+ flexRender,
12
+ getCoreRowModel,
13
+ getSortedRowModel,
14
+ getPaginationRowModel,
15
+ useReactTable,
16
+ } from "@tanstack/react-table";
17
+ import PropTypes from "prop-types";
18
+
19
+ import RichTableBody from "./RichTableBody";
20
+ import RichTableHeader from "./RichTableHeader";
21
+ import RichTablePagination from "./RichTablePagination";
22
+
23
+ const fallbackData = [];
24
+
25
+ RichTable.propTypes = {
26
+ /** Columns to be displayed in the table */
27
+ columns: PropTypes.array.isRequired,
28
+ /** Data to be displayed in the table */
29
+ data: PropTypes.array.isRequired,
30
+ /** Whether to display pagination */
31
+ withPagination: PropTypes.bool,
32
+ /** Number of rows per page */
33
+ pageSize: PropTypes.number,
34
+ /** Index of the current page */
35
+ pageIndex: PropTypes.number,
36
+ };
37
+
38
+ function RichTable({
39
+ columns,
40
+ data,
41
+ withPagination,
42
+ pageSize = 5,
43
+ pageIndex = 0,
44
+ }) {
45
+ const tableColumns = useMemo(() => columns, [columns]);
46
+ const [tableData] = useState(data ?? fallbackData);
47
+ const [sorting, setSorting] = useState([]);
48
+ const [pagination, setPagination] = useState({
49
+ pageIndex,
50
+ pageSize,
51
+ });
52
+
53
+ const table = useReactTable({
54
+ data: tableData,
55
+ columns: tableColumns,
56
+ getCoreRowModel: getCoreRowModel(),
57
+ getSortedRowModel: getSortedRowModel(),
58
+ getPaginationRowModel: getPaginationRowModel(),
59
+ onPaginationChange: setPagination,
60
+ onSortingChange: setSorting,
61
+ state: {
62
+ sorting,
63
+ pagination,
64
+ },
65
+ });
66
+
67
+ return (
68
+ <div className="table-responsive">
69
+ <table className="table table-hover text-nowrap">
70
+ <RichTableHeader table={table} flexRender={flexRender} />
71
+ <RichTableBody table={table} flexRender={flexRender} />
72
+ </table>
73
+ {withPagination && (
74
+ <RichTablePagination
75
+ table={table}
76
+ tablePageSize={pageSize}
77
+ allRows={tableData.length}
78
+ />
79
+ )}
80
+ </div>
81
+ );
82
+ }
83
+
84
+ export default RichTable;
@@ -0,0 +1,135 @@
1
+ ### Description
2
+
3
+ Rich Table is a table component based on
4
+ [Tanstack React Table](https://tanstack.com/table/). It adds some features to
5
+ the table component, such as:
6
+
7
+ - **Pagination**: The table can be paginated.
8
+ - **Sorting**: The table can be sorted by columns.
9
+ - **Row Expansion**: The table rows can be expanded. (To be implemented)
10
+
11
+ ### Example
12
+
13
+ ```js
14
+ import RichTable from "./RichTable";
15
+
16
+ const columns = [
17
+ {
18
+ header: "Name",
19
+ accessorKey: "name",
20
+ },
21
+ {
22
+ header: "Surname",
23
+ accessorKey: "surname",
24
+ },
25
+ {
26
+ header: "Age",
27
+ accessorKey: "age",
28
+ },
29
+ {
30
+ header: "Phone",
31
+ accessorKey: "phone",
32
+ },
33
+ ];
34
+
35
+ const data = [
36
+ {
37
+ name: "John",
38
+ surname: "Coltrane",
39
+ age: 30,
40
+ phone: "123456789",
41
+ },
42
+ {
43
+ name: "Jane",
44
+ surname: "Doe",
45
+ age: 25,
46
+ phone: "987654321",
47
+ },
48
+ {
49
+ name: "Alice",
50
+ surname: "Smith",
51
+ age: 35,
52
+ phone: "123456789",
53
+ },
54
+ {
55
+ name: "Bob",
56
+ surname: "Smith",
57
+ age: 40,
58
+ phone: "987654321",
59
+ },
60
+ {
61
+ name: "Charlie",
62
+ surname: "Brown",
63
+ age: 45,
64
+ phone: "123456789",
65
+ },
66
+ {
67
+ name: "Daisy",
68
+ surname: "Brown",
69
+ age: 50,
70
+ phone: "987654321",
71
+ },
72
+ {
73
+ name: "Eve",
74
+ surname: "Johnson",
75
+ age: 55,
76
+ phone: "123456789",
77
+ },
78
+ {
79
+ name: "Frank",
80
+ surname: "Johnson",
81
+ age: 60,
82
+ phone: "987654321",
83
+ },
84
+ {
85
+ name: "Grace",
86
+ surname: "Williams",
87
+ age: 65,
88
+ phone: "123456789",
89
+ },
90
+ {
91
+ name: "Henry",
92
+ surname: "Williams",
93
+ age: 70,
94
+ phone: "987654321",
95
+ },
96
+ {
97
+ name: "Ivy",
98
+ surname: "Brown",
99
+ age: 75,
100
+ phone: "123456789",
101
+ },
102
+ {
103
+ name: "Jack",
104
+ surname: "Brown",
105
+ age: 80,
106
+ phone: "987654321",
107
+ },
108
+ {
109
+ name: "Kelly",
110
+ surname: "Johnson",
111
+ age: 85,
112
+ phone: "123456789",
113
+ },
114
+ {
115
+ name: "Liam",
116
+ surname: "Johnson",
117
+ age: 90,
118
+ phone: "987654321",
119
+ },
120
+ {
121
+ name: "Mia",
122
+ surname: "Williams",
123
+ age: 95,
124
+ phone: "123456789",
125
+ },
126
+ {
127
+ name: "Nathan",
128
+ surname: "Williams",
129
+ age: 100,
130
+ phone: "987654321",
131
+ },
132
+ ];
133
+
134
+ <RichTable columns={columns} data={data} withPagination />;
135
+ ```
@@ -0,0 +1,48 @@
1
+ /*
2
+ * Copyright (C) 2019-2024 CZ.NIC z.s.p.o. (https://www.nic.cz/)
3
+ *
4
+ * This is free software, licensed under the GNU General Public License v3.
5
+ * See /LICENSE for more information.
6
+ */
7
+
8
+ import React from "react";
9
+
10
+ import propTypes from "prop-types";
11
+
12
+ RichTableBody.propTypes = {
13
+ table: propTypes.shape({
14
+ getRowModel: propTypes.func.isRequired,
15
+ }).isRequired,
16
+ flexRender: propTypes.func.isRequired,
17
+ };
18
+
19
+ function RichTableBody({ table, flexRender }) {
20
+ return (
21
+ <tbody>
22
+ {table.getRowModel().rows.map((row) => {
23
+ return (
24
+ <tr key={row.id} className="align-middle">
25
+ {row.getVisibleCells().map((cell) => {
26
+ return (
27
+ <td
28
+ key={cell.id}
29
+ {...(cell.column.columnDef.className && {
30
+ className:
31
+ cell.column.columnDef.className,
32
+ })}
33
+ >
34
+ {flexRender(
35
+ cell.column.columnDef.cell,
36
+ cell.getContext()
37
+ )}
38
+ </td>
39
+ );
40
+ })}
41
+ </tr>
42
+ );
43
+ })}
44
+ </tbody>
45
+ );
46
+ }
47
+
48
+ export default RichTableBody;
@@ -0,0 +1,96 @@
1
+ /*
2
+ * Copyright (C) 2019-2024 CZ.NIC z.s.p.o. (https://www.nic.cz/)
3
+ *
4
+ * This is free software, licensed under the GNU General Public License v3.
5
+ * See /LICENSE for more information.
6
+ */
7
+
8
+ import React from "react";
9
+
10
+ import {
11
+ faSquareCaretUp,
12
+ faSquareCaretDown,
13
+ } from "@fortawesome/free-solid-svg-icons";
14
+ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
15
+ import propTypes from "prop-types";
16
+
17
+ RichTableHeader.propTypes = {
18
+ table: propTypes.shape({
19
+ getHeaderGroups: propTypes.func.isRequired,
20
+ }).isRequired,
21
+ flexRender: propTypes.func.isRequired,
22
+ };
23
+
24
+ function RichTableHeader({ table, flexRender }) {
25
+ const getThTitle = (header) => {
26
+ if (!header.column.getCanSort()) return undefined;
27
+
28
+ const nextSortingOrder = header.column.getNextSortingOrder();
29
+ if (nextSortingOrder === "asc") return _("Sort ascending");
30
+ if (nextSortingOrder === "desc") return _("Sort descending");
31
+ return _("Clear sort");
32
+ };
33
+
34
+ return (
35
+ <thead className="thead-light">
36
+ {table.getHeaderGroups().map((headerGroup) => (
37
+ <tr key={headerGroup.id} role="row">
38
+ {headerGroup.headers.map((header) => (
39
+ <th
40
+ key={header.id}
41
+ colSpan={header.colSpan}
42
+ {...(header.column.columnDef.headerClassName && {
43
+ className:
44
+ header.column.columnDef.headerClassName,
45
+ })}
46
+ >
47
+ {header.isPlaceholder ||
48
+ header.column.columnDef.headerIsHidden ? (
49
+ <div className="d-none" aria-hidden="true">
50
+ {flexRender(
51
+ header.column.columnDef.header,
52
+ header.getContext()
53
+ )}
54
+ </div>
55
+ ) : (
56
+ <button
57
+ type="button"
58
+ className={`btn btn-link text-decoration-none text-reset fw-bold p-0 d-flex align-items-center
59
+ ${
60
+ header.column.getCanSort()
61
+ ? "d-flex align-items-center"
62
+ : ""
63
+ }
64
+ `}
65
+ onClick={header.column.getToggleSortingHandler()}
66
+ title={getThTitle(header)}
67
+ >
68
+ {flexRender(
69
+ header.column.columnDef.header,
70
+ header.getContext()
71
+ )}
72
+ {{
73
+ asc: (
74
+ <FontAwesomeIcon
75
+ icon={faSquareCaretUp}
76
+ className="ms-1 text-primary"
77
+ />
78
+ ),
79
+ desc: (
80
+ <FontAwesomeIcon
81
+ icon={faSquareCaretDown}
82
+ className="ms-1 text-primary"
83
+ />
84
+ ),
85
+ }[header.column.getIsSorted()] ?? null}
86
+ </button>
87
+ )}
88
+ </th>
89
+ ))}
90
+ </tr>
91
+ ))}
92
+ </thead>
93
+ );
94
+ }
95
+
96
+ export default RichTableHeader;
@@ -0,0 +1,128 @@
1
+ /*
2
+ * Copyright (C) 2019-2024 CZ.NIC z.s.p.o. (https://www.nic.cz/)
3
+ *
4
+ * This is free software, licensed under the GNU General Public License v3.
5
+ * See /LICENSE for more information.
6
+ */
7
+
8
+ import React, { useMemo } from "react";
9
+
10
+ import {
11
+ faAngleLeft,
12
+ faAnglesLeft,
13
+ faAngleRight,
14
+ faAnglesRight,
15
+ } from "@fortawesome/free-solid-svg-icons";
16
+ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
17
+ import propTypes from "prop-types";
18
+
19
+ RichTablePagination.propTypes = {
20
+ table: propTypes.shape({
21
+ getState: propTypes.func.isRequired,
22
+ getCanPreviousPage: propTypes.func.isRequired,
23
+ getCanNextPage: propTypes.func.isRequired,
24
+ firstPage: propTypes.func.isRequired,
25
+ previousPage: propTypes.func.isRequired,
26
+ nextPage: propTypes.func.isRequired,
27
+ lastPage: propTypes.func.isRequired,
28
+ setPageSize: propTypes.func.isRequired,
29
+ getPageCount: propTypes.func.isRequired,
30
+ }).isRequired,
31
+ tablePageSize: propTypes.number,
32
+ allRows: propTypes.number,
33
+ };
34
+
35
+ function RichTablePagination({ table, tablePageSize, allRows }) {
36
+ const { pagination } = table.getState();
37
+ const prevPagBtnDisabled = !table.getCanPreviousPage();
38
+ const nextPagBtnDisabled = !table.getCanNextPage();
39
+
40
+ const pageSizes = useMemo(() => {
41
+ return [tablePageSize ?? 5, 10, 25].filter(
42
+ (value, index, self) => self.indexOf(value) === index
43
+ );
44
+ }, [tablePageSize]);
45
+
46
+ const renderPaginationButton = (icon, ariaLabel, onClick, disabled) => (
47
+ <li
48
+ className={`page-item ${disabled ? "disabled" : ""}`}
49
+ style={{ cursor: disabled ? "not-allowed" : "pointer" }}
50
+ >
51
+ <button
52
+ type="button"
53
+ className="page-link"
54
+ aria-label={ariaLabel}
55
+ onClick={onClick}
56
+ disabled={disabled}
57
+ >
58
+ <FontAwesomeIcon icon={icon} />
59
+ </button>
60
+ </li>
61
+ );
62
+
63
+ return (
64
+ <nav
65
+ aria-label={_("Pagination navigation bar")}
66
+ className="d-flex gap-2 justify-content-start align-items-center mx-2 mb-1 text-nowrap"
67
+ >
68
+ <ul className="pagination pagination-sm mb-0">
69
+ {renderPaginationButton(
70
+ faAnglesLeft,
71
+ _("First page"),
72
+ () => table.firstPage(),
73
+ prevPagBtnDisabled
74
+ )}
75
+ {renderPaginationButton(
76
+ faAngleLeft,
77
+ _("Previous page"),
78
+ () => table.previousPage(),
79
+ prevPagBtnDisabled
80
+ )}
81
+ {renderPaginationButton(
82
+ faAngleRight,
83
+ _("Next page"),
84
+ () => table.nextPage(),
85
+ nextPagBtnDisabled
86
+ )}
87
+ {renderPaginationButton(
88
+ faAnglesRight,
89
+ _("Last page"),
90
+ () => table.lastPage(),
91
+ nextPagBtnDisabled
92
+ )}
93
+ </ul>
94
+ <span>
95
+ {_("Page")}&nbsp;
96
+ <span className="fw-bold">
97
+ {pagination.pageIndex + 1}
98
+ &nbsp;{_("of")}&nbsp;
99
+ {table.getPageCount().toLocaleString()}
100
+ </span>
101
+ </span>
102
+ <div
103
+ className="vr mx-1 align-self-center"
104
+ style={{ height: "1.5rem" }}
105
+ />
106
+ <span>{_("Rows per page:")}</span>
107
+ <select
108
+ className="form-select form-select-sm w-auto"
109
+ aria-label={_("Select rows per page")}
110
+ value={pagination.pageSize}
111
+ onChange={(e) => {
112
+ table.setPageSize(Number(e.target.value));
113
+ }}
114
+ >
115
+ {pageSizes.map((pageSize) => (
116
+ <option key={pageSize} value={pageSize}>
117
+ {pageSize}
118
+ </option>
119
+ ))}
120
+ <option key={allRows} value={allRows}>
121
+ {_("All")}
122
+ </option>
123
+ </select>
124
+ </nav>
125
+ );
126
+ }
127
+
128
+ export default RichTablePagination;
Binary file
package/index.js CHANGED
@@ -40,9 +40,10 @@ export { Spinner, SpinnerElement } from "./bootstrap/Spinner";
40
40
  export { Modal, ModalBody, ModalFooter, ModalHeader } from "./bootstrap/Modal";
41
41
 
42
42
  // Common
43
- export { default as RebootButton } from "./common/RebootButton";
43
+ export { default as ActionButtonWithModal } from "./common/ActionButtonWithModal/ActionButtonWithModal";
44
44
  export { default as WiFiSettings } from "./common/WiFiSettings/WiFiSettings";
45
45
  export { default as ResetWiFiSettings } from "./common/WiFiSettings/ResetWiFiSettings";
46
+ export { default as RichTable } from "./common/RichTable/RichTable";
46
47
  // Form
47
48
  export { default as ForisForm } from "./form/components/ForisForm";
48
49
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "foris",
3
- "version": "6.4.0",
3
+ "version": "6.5.0",
4
4
  "description": "Foris JS library is a set of components and utils for reForis application and plugins.",
5
5
  "author": "CZ.NIC, z.s.p.o.",
6
6
  "repository": {
@@ -18,6 +18,7 @@
18
18
  "@fortawesome/free-regular-svg-icons": "^6.6.0",
19
19
  "@fortawesome/free-solid-svg-icons": "^6.6.0",
20
20
  "@fortawesome/react-fontawesome": "^0.2.2",
21
+ "@tanstack/react-table": "^8.20.5",
21
22
  "axios": "^1.7.2",
22
23
  "immutability-helper": "^3.1.1",
23
24
  "moment": "^2.30.1",