mirror of
				https://gitlab.nic.cz/turris/reforis/foris-js.git
				synced 2025-11-03 23:00:31 +01:00 
			
		
		
		
	Add global fuzzy search and columns visibility to RichTable
This commit is contained in:
		
							
								
								
									
										36
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										36
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							@@ -13,6 +13,7 @@
 | 
				
			|||||||
                "@fortawesome/free-regular-svg-icons": "^6.7.2",
 | 
					                "@fortawesome/free-regular-svg-icons": "^6.7.2",
 | 
				
			||||||
                "@fortawesome/free-solid-svg-icons": "^6.7.2",
 | 
					                "@fortawesome/free-solid-svg-icons": "^6.7.2",
 | 
				
			||||||
                "@fortawesome/react-fontawesome": "^0.2.2",
 | 
					                "@fortawesome/react-fontawesome": "^0.2.2",
 | 
				
			||||||
 | 
					                "@tanstack/match-sorter-utils": "^8.19.4",
 | 
				
			||||||
                "@tanstack/react-table": "^8.21.2",
 | 
					                "@tanstack/react-table": "^8.21.2",
 | 
				
			||||||
                "axios": "^1.7.9",
 | 
					                "axios": "^1.7.9",
 | 
				
			||||||
                "immutability-helper": "^3.1.1",
 | 
					                "immutability-helper": "^3.1.1",
 | 
				
			||||||
@@ -3384,6 +3385,22 @@
 | 
				
			|||||||
                "@sinonjs/commons": "^3.0.0"
 | 
					                "@sinonjs/commons": "^3.0.0"
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					        "node_modules/@tanstack/match-sorter-utils": {
 | 
				
			||||||
 | 
					            "version": "8.19.4",
 | 
				
			||||||
 | 
					            "resolved": "https://registry.npmjs.org/@tanstack/match-sorter-utils/-/match-sorter-utils-8.19.4.tgz",
 | 
				
			||||||
 | 
					            "integrity": "sha512-Wo1iKt2b9OT7d+YGhvEPD3DXvPv2etTusIMhMUoG7fbhmxcXCtIjJDEygy91Y2JFlwGyjqiBPRozme7UD8hoqg==",
 | 
				
			||||||
 | 
					            "license": "MIT",
 | 
				
			||||||
 | 
					            "dependencies": {
 | 
				
			||||||
 | 
					                "remove-accents": "0.5.0"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "engines": {
 | 
				
			||||||
 | 
					                "node": ">=12"
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "funding": {
 | 
				
			||||||
 | 
					                "type": "github",
 | 
				
			||||||
 | 
					                "url": "https://github.com/sponsors/tannerlinsley"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        "node_modules/@tanstack/react-table": {
 | 
					        "node_modules/@tanstack/react-table": {
 | 
				
			||||||
            "version": "8.21.2",
 | 
					            "version": "8.21.2",
 | 
				
			||||||
            "resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.21.2.tgz",
 | 
					            "resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.21.2.tgz",
 | 
				
			||||||
@@ -15865,6 +15882,12 @@
 | 
				
			|||||||
                "url": "https://opencollective.com/unified"
 | 
					                "url": "https://opencollective.com/unified"
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					        "node_modules/remove-accents": {
 | 
				
			||||||
 | 
					            "version": "0.5.0",
 | 
				
			||||||
 | 
					            "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.5.0.tgz",
 | 
				
			||||||
 | 
					            "integrity": "sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A==",
 | 
				
			||||||
 | 
					            "license": "MIT"
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        "node_modules/repeat-string": {
 | 
					        "node_modules/repeat-string": {
 | 
				
			||||||
            "version": "1.6.1",
 | 
					            "version": "1.6.1",
 | 
				
			||||||
            "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
 | 
					            "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
 | 
				
			||||||
@@ -20893,6 +20916,14 @@
 | 
				
			|||||||
                "@sinonjs/commons": "^3.0.0"
 | 
					                "@sinonjs/commons": "^3.0.0"
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					        "@tanstack/match-sorter-utils": {
 | 
				
			||||||
 | 
					            "version": "8.19.4",
 | 
				
			||||||
 | 
					            "resolved": "https://registry.npmjs.org/@tanstack/match-sorter-utils/-/match-sorter-utils-8.19.4.tgz",
 | 
				
			||||||
 | 
					            "integrity": "sha512-Wo1iKt2b9OT7d+YGhvEPD3DXvPv2etTusIMhMUoG7fbhmxcXCtIjJDEygy91Y2JFlwGyjqiBPRozme7UD8hoqg==",
 | 
				
			||||||
 | 
					            "requires": {
 | 
				
			||||||
 | 
					                "remove-accents": "0.5.0"
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        "@tanstack/react-table": {
 | 
					        "@tanstack/react-table": {
 | 
				
			||||||
            "version": "8.21.2",
 | 
					            "version": "8.21.2",
 | 
				
			||||||
            "resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.21.2.tgz",
 | 
					            "resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.21.2.tgz",
 | 
				
			||||||
@@ -30193,6 +30224,11 @@
 | 
				
			|||||||
                "mdast-util-to-markdown": "^0.6.0"
 | 
					                "mdast-util-to-markdown": "^0.6.0"
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					        "remove-accents": {
 | 
				
			||||||
 | 
					            "version": "0.5.0",
 | 
				
			||||||
 | 
					            "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.5.0.tgz",
 | 
				
			||||||
 | 
					            "integrity": "sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A=="
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        "repeat-string": {
 | 
					        "repeat-string": {
 | 
				
			||||||
            "version": "1.6.1",
 | 
					            "version": "1.6.1",
 | 
				
			||||||
            "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
 | 
					            "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,6 +18,7 @@
 | 
				
			|||||||
        "@fortawesome/free-regular-svg-icons": "^6.7.2",
 | 
					        "@fortawesome/free-regular-svg-icons": "^6.7.2",
 | 
				
			||||||
        "@fortawesome/free-solid-svg-icons": "^6.7.2",
 | 
					        "@fortawesome/free-solid-svg-icons": "^6.7.2",
 | 
				
			||||||
        "@fortawesome/react-fontawesome": "^0.2.2",
 | 
					        "@fortawesome/react-fontawesome": "^0.2.2",
 | 
				
			||||||
 | 
					        "@tanstack/match-sorter-utils": "^8.19.4",
 | 
				
			||||||
        "@tanstack/react-table": "^8.21.2",
 | 
					        "@tanstack/react-table": "^8.21.2",
 | 
				
			||||||
        "axios": "^1.7.9",
 | 
					        "axios": "^1.7.9",
 | 
				
			||||||
        "immutability-helper": "^3.1.1",
 | 
					        "immutability-helper": "^3.1.1",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -34,12 +34,14 @@ const Input = forwardRef(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        return (
 | 
					        return (
 | 
				
			||||||
            <div className="mb-3">
 | 
					            <div className="mb-3">
 | 
				
			||||||
                <label
 | 
					                {label && (
 | 
				
			||||||
                    className={`form-label ${labelClassName || ""}`.trim()}
 | 
					                    <label
 | 
				
			||||||
                    htmlFor={uid}
 | 
					                        className={`form-label ${labelClassName || ""}`.trim()}
 | 
				
			||||||
                >
 | 
					                        htmlFor={uid}
 | 
				
			||||||
                    {label}
 | 
					                    >
 | 
				
			||||||
                </label>
 | 
					                        {label}
 | 
				
			||||||
 | 
					                    </label>
 | 
				
			||||||
 | 
					                )}
 | 
				
			||||||
                <div className={`input-group ${groupClassName || ""}`.trim()}>
 | 
					                <div className={`input-group ${groupClassName || ""}`.trim()}>
 | 
				
			||||||
                    <input
 | 
					                    <input
 | 
				
			||||||
                        className={`form-control ${inputClassName}`.trim()}
 | 
					                        className={`form-control ${inputClassName}`.trim()}
 | 
				
			||||||
@@ -65,7 +67,7 @@ Input.displayName = "Input";
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
Input.propTypes = {
 | 
					Input.propTypes = {
 | 
				
			||||||
    type: PropTypes.string.isRequired,
 | 
					    type: PropTypes.string.isRequired,
 | 
				
			||||||
    label: PropTypes.string.isRequired,
 | 
					    label: PropTypes.string,
 | 
				
			||||||
    helpText: PropTypes.string,
 | 
					    helpText: PropTypes.string,
 | 
				
			||||||
    error: PropTypes.string,
 | 
					    error: PropTypes.string,
 | 
				
			||||||
    className: PropTypes.string,
 | 
					    className: PropTypes.string,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,18 +7,22 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import React, { useMemo, useState } from "react";
 | 
					import React, { useMemo, useState } from "react";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { rankItem } from "@tanstack/match-sorter-utils";
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
    flexRender,
 | 
					    flexRender,
 | 
				
			||||||
    getCoreRowModel,
 | 
					    getCoreRowModel,
 | 
				
			||||||
    getSortedRowModel,
 | 
					    getSortedRowModel,
 | 
				
			||||||
 | 
					    getFilteredRowModel,
 | 
				
			||||||
    getPaginationRowModel,
 | 
					    getPaginationRowModel,
 | 
				
			||||||
    useReactTable,
 | 
					    useReactTable,
 | 
				
			||||||
} from "@tanstack/react-table";
 | 
					} from "@tanstack/react-table";
 | 
				
			||||||
import PropTypes from "prop-types";
 | 
					import PropTypes from "prop-types";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import RichTableBody from "./RichTableBody";
 | 
					import RichTableBody from "./RichTableBody";
 | 
				
			||||||
 | 
					import RichTableColumnsDropdown from "./RichTableColumnsDropdown";
 | 
				
			||||||
import RichTableHeader from "./RichTableHeader";
 | 
					import RichTableHeader from "./RichTableHeader";
 | 
				
			||||||
import RichTablePagination from "./RichTablePagination";
 | 
					import RichTablePagination from "./RichTablePagination";
 | 
				
			||||||
 | 
					import Input from "../../bootstrap/Input";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RichTable.propTypes = {
 | 
					RichTable.propTypes = {
 | 
				
			||||||
    /** Columns to be displayed in the table */
 | 
					    /** Columns to be displayed in the table */
 | 
				
			||||||
@@ -46,36 +50,69 @@ export default function RichTable({
 | 
				
			|||||||
        pageIndex,
 | 
					        pageIndex,
 | 
				
			||||||
        pageSize,
 | 
					        pageSize,
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					    const [globalFilter, setGlobalFilter] = useState("");
 | 
				
			||||||
 | 
					    const [columnVisibility, setColumnVisibility] = useState({});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const table = useReactTable({
 | 
					    const table = useReactTable({
 | 
				
			||||||
        data,
 | 
					        data,
 | 
				
			||||||
        columns: tableColumns,
 | 
					        columns: tableColumns,
 | 
				
			||||||
 | 
					        filterFns: {
 | 
				
			||||||
 | 
					            fuzzy: fuzzyFilter,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        globalFilterFn: "fuzzy",
 | 
				
			||||||
        getCoreRowModel: getCoreRowModel(),
 | 
					        getCoreRowModel: getCoreRowModel(),
 | 
				
			||||||
        getSortedRowModel: getSortedRowModel(),
 | 
					        getSortedRowModel: getSortedRowModel(),
 | 
				
			||||||
        getPaginationRowModel: getPaginationRowModel(),
 | 
					        getPaginationRowModel: getPaginationRowModel(),
 | 
				
			||||||
        onPaginationChange: setPagination,
 | 
					        getFilteredRowModel: getFilteredRowModel(),
 | 
				
			||||||
        onSortingChange: setSorting,
 | 
					        onSortingChange: setSorting,
 | 
				
			||||||
 | 
					        onPaginationChange: setPagination,
 | 
				
			||||||
 | 
					        onGlobalFilterChange: setGlobalFilter,
 | 
				
			||||||
 | 
					        onColumnVisibilityChange: setColumnVisibility,
 | 
				
			||||||
        state: {
 | 
					        state: {
 | 
				
			||||||
            sorting,
 | 
					            sorting,
 | 
				
			||||||
            pagination,
 | 
					            pagination,
 | 
				
			||||||
 | 
					            globalFilter,
 | 
				
			||||||
 | 
					            columnVisibility,
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const paginationIsNeeded = data.length > pageSize && withPagination;
 | 
					    const paginationIsNeeded = data.length > pageSize && withPagination;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
        <div className="table-responsive">
 | 
					        <div>
 | 
				
			||||||
            <table className="table table-hover text-nowrap">
 | 
					            <div className="d-flex justify-content-between align-items-center">
 | 
				
			||||||
                <RichTableHeader table={table} flexRender={flexRender} />
 | 
					                <Input
 | 
				
			||||||
                <RichTableBody table={table} flexRender={flexRender} />
 | 
					                    className="me-3"
 | 
				
			||||||
            </table>
 | 
					                    type="text"
 | 
				
			||||||
            {paginationIsNeeded && (
 | 
					                    placeholder={_("Search…")}
 | 
				
			||||||
                <RichTablePagination
 | 
					                    value={globalFilter ?? ""}
 | 
				
			||||||
                    table={table}
 | 
					                    onChange={(e) => setGlobalFilter(String(e.target.value))}
 | 
				
			||||||
                    tablePageSize={pageSize}
 | 
					 | 
				
			||||||
                    allRows={data.length}
 | 
					 | 
				
			||||||
                />
 | 
					                />
 | 
				
			||||||
            )}
 | 
					                <RichTableColumnsDropdown columns={table.getAllLeafColumns()} />
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div className="table-responsive">
 | 
				
			||||||
 | 
					                <table className="table table-hover text-nowrap">
 | 
				
			||||||
 | 
					                    <RichTableHeader table={table} flexRender={flexRender} />
 | 
				
			||||||
 | 
					                    <RichTableBody
 | 
				
			||||||
 | 
					                        table={table}
 | 
				
			||||||
 | 
					                        columns={tableColumns}
 | 
				
			||||||
 | 
					                        flexRender={flexRender}
 | 
				
			||||||
 | 
					                    />
 | 
				
			||||||
 | 
					                </table>
 | 
				
			||||||
 | 
					                {paginationIsNeeded && (
 | 
				
			||||||
 | 
					                    <RichTablePagination
 | 
				
			||||||
 | 
					                        table={table}
 | 
				
			||||||
 | 
					                        tablePageSize={pageSize}
 | 
				
			||||||
 | 
					                        allRows={data.length}
 | 
				
			||||||
 | 
					                    />
 | 
				
			||||||
 | 
					                )}
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function fuzzyFilter(row, columnId, value, addMeta) {
 | 
				
			||||||
 | 
					    const itemRank = rankItem(row.getValue(columnId), value);
 | 
				
			||||||
 | 
					    addMeta({ itemRank });
 | 
				
			||||||
 | 
					    return itemRank.passed;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,34 +13,44 @@ RichTableBody.propTypes = {
 | 
				
			|||||||
    table: propTypes.shape({
 | 
					    table: propTypes.shape({
 | 
				
			||||||
        getRowModel: propTypes.func.isRequired,
 | 
					        getRowModel: propTypes.func.isRequired,
 | 
				
			||||||
    }).isRequired,
 | 
					    }).isRequired,
 | 
				
			||||||
 | 
					    columns: propTypes.array.isRequired,
 | 
				
			||||||
    flexRender: propTypes.func.isRequired,
 | 
					    flexRender: propTypes.func.isRequired,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function RichTableBody({ table, flexRender }) {
 | 
					function RichTableBody({ table, columns, flexRender }) {
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
        <tbody>
 | 
					        <tbody>
 | 
				
			||||||
            {table.getRowModel().rows.map((row) => {
 | 
					            {table.getRowModel().rows?.length ? (
 | 
				
			||||||
                return (
 | 
					                table.getRowModel().rows.map((row) => {
 | 
				
			||||||
                    <tr key={row.id} className="align-middle">
 | 
					                    return (
 | 
				
			||||||
                        {row.getVisibleCells().map((cell) => {
 | 
					                        <tr key={row.id} className="align-middle">
 | 
				
			||||||
                            return (
 | 
					                            {row.getVisibleCells().map((cell) => {
 | 
				
			||||||
                                <td
 | 
					                                return (
 | 
				
			||||||
                                    key={cell.id}
 | 
					                                    <td
 | 
				
			||||||
                                    {...(cell.column.columnDef.className && {
 | 
					                                        key={cell.id}
 | 
				
			||||||
                                        className:
 | 
					                                        {...(cell.column.columnDef
 | 
				
			||||||
                                            cell.column.columnDef.className,
 | 
					                                            .className && {
 | 
				
			||||||
                                    })}
 | 
					                                            className:
 | 
				
			||||||
                                >
 | 
					                                                cell.column.columnDef.className,
 | 
				
			||||||
                                    {flexRender(
 | 
					                                        })}
 | 
				
			||||||
                                        cell.column.columnDef.cell,
 | 
					                                    >
 | 
				
			||||||
                                        cell.getContext()
 | 
					                                        {flexRender(
 | 
				
			||||||
                                    )}
 | 
					                                            cell.column.columnDef.cell,
 | 
				
			||||||
                                </td>
 | 
					                                            cell.getContext()
 | 
				
			||||||
                            );
 | 
					                                        )}
 | 
				
			||||||
                        })}
 | 
					                                    </td>
 | 
				
			||||||
                    </tr>
 | 
					                                );
 | 
				
			||||||
                );
 | 
					                            })}
 | 
				
			||||||
            })}
 | 
					                        </tr>
 | 
				
			||||||
 | 
					                    );
 | 
				
			||||||
 | 
					                })
 | 
				
			||||||
 | 
					            ) : (
 | 
				
			||||||
 | 
					                <tr>
 | 
				
			||||||
 | 
					                    <td colSpan={columns.length} className="text-center py-4">
 | 
				
			||||||
 | 
					                        <span>{_("No results.")}</span>
 | 
				
			||||||
 | 
					                    </td>
 | 
				
			||||||
 | 
					                </tr>
 | 
				
			||||||
 | 
					            )}
 | 
				
			||||||
        </tbody>
 | 
					        </tbody>
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										90
									
								
								src/common/RichTable/RichTableColumnsDropdown.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								src/common/RichTable/RichTableColumnsDropdown.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,90 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (C) 2019-2025 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 { faCheck, faRotateLeft } from "@fortawesome/free-solid-svg-icons";
 | 
				
			||||||
 | 
					import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 | 
				
			||||||
 | 
					import PropTypes from "prop-types";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import Button from "../../bootstrap/Button";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RichTableColumnsDropdown.propTypes = {
 | 
				
			||||||
 | 
					    columns: PropTypes.array.isRequired,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function RichTableColumnsDropdown({ columns }) {
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					        <div className="dropdown mb-3">
 | 
				
			||||||
 | 
					            <Button
 | 
				
			||||||
 | 
					                className="btn btn-outline-secondary dropdown-toggle"
 | 
				
			||||||
 | 
					                data-bs-toggle="dropdown"
 | 
				
			||||||
 | 
					            >
 | 
				
			||||||
 | 
					                {_("Columns")}
 | 
				
			||||||
 | 
					            </Button>
 | 
				
			||||||
 | 
					            <ul className="dropdown-menu dropdown-menu-end">
 | 
				
			||||||
 | 
					                {columns.map((column) => {
 | 
				
			||||||
 | 
					                    return (
 | 
				
			||||||
 | 
					                        <li key={column.id}>
 | 
				
			||||||
 | 
					                            <button
 | 
				
			||||||
 | 
					                                type="button"
 | 
				
			||||||
 | 
					                                className="dropdown-item d-flex align-items-center"
 | 
				
			||||||
 | 
					                                onClick={column.getToggleVisibilityHandler()}
 | 
				
			||||||
 | 
					                                style={{ paddingLeft: "2rem" }}
 | 
				
			||||||
 | 
					                                disabled={
 | 
				
			||||||
 | 
					                                    column.columnDef?.enableHiding === false
 | 
				
			||||||
 | 
					                                }
 | 
				
			||||||
 | 
					                            >
 | 
				
			||||||
 | 
					                                {column.getIsVisible() && (
 | 
				
			||||||
 | 
					                                    <FontAwesomeIcon
 | 
				
			||||||
 | 
					                                        icon={faCheck}
 | 
				
			||||||
 | 
					                                        className="position-absolute text-secondary me-2"
 | 
				
			||||||
 | 
					                                        style={{ left: "0.6rem" }}
 | 
				
			||||||
 | 
					                                        width="1rem"
 | 
				
			||||||
 | 
					                                    />
 | 
				
			||||||
 | 
					                                )}
 | 
				
			||||||
 | 
					                                <span>{column.columnDef.header}</span>
 | 
				
			||||||
 | 
					                            </button>
 | 
				
			||||||
 | 
					                        </li>
 | 
				
			||||||
 | 
					                    );
 | 
				
			||||||
 | 
					                })}
 | 
				
			||||||
 | 
					                {columns.some((column) => !column.getIsVisible()) && (
 | 
				
			||||||
 | 
					                    <>
 | 
				
			||||||
 | 
					                        <li>
 | 
				
			||||||
 | 
					                            <hr className="dropdown-divider" />
 | 
				
			||||||
 | 
					                        </li>
 | 
				
			||||||
 | 
					                        <li>
 | 
				
			||||||
 | 
					                            <button
 | 
				
			||||||
 | 
					                                type="button"
 | 
				
			||||||
 | 
					                                className="dropdown-item d-flex align-items-center"
 | 
				
			||||||
 | 
					                                style={{ paddingLeft: "2rem" }}
 | 
				
			||||||
 | 
					                                onClick={() => {
 | 
				
			||||||
 | 
					                                    // toggleVisibility for columns that are hidden
 | 
				
			||||||
 | 
					                                    columns.forEach((column) => {
 | 
				
			||||||
 | 
					                                        if (!column.getIsVisible()) {
 | 
				
			||||||
 | 
					                                            column.toggleVisibility();
 | 
				
			||||||
 | 
					                                        }
 | 
				
			||||||
 | 
					                                    });
 | 
				
			||||||
 | 
					                                }}
 | 
				
			||||||
 | 
					                            >
 | 
				
			||||||
 | 
					                                <FontAwesomeIcon
 | 
				
			||||||
 | 
					                                    icon={faRotateLeft}
 | 
				
			||||||
 | 
					                                    className="position-absolute text-secondary me-2"
 | 
				
			||||||
 | 
					                                    width="1rem"
 | 
				
			||||||
 | 
					                                    style={{ left: "0.6rem" }}
 | 
				
			||||||
 | 
					                                />
 | 
				
			||||||
 | 
					                                {_("Reset")}
 | 
				
			||||||
 | 
					                            </button>
 | 
				
			||||||
 | 
					                        </li>
 | 
				
			||||||
 | 
					                    </>
 | 
				
			||||||
 | 
					                )}
 | 
				
			||||||
 | 
					            </ul>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default RichTableColumnsDropdown;
 | 
				
			||||||
@@ -55,6 +55,12 @@ function RichTableHeader({ table, flexRender }) {
 | 
				
			|||||||
                            ) : (
 | 
					                            ) : (
 | 
				
			||||||
                                <button
 | 
					                                <button
 | 
				
			||||||
                                    type="button"
 | 
					                                    type="button"
 | 
				
			||||||
 | 
					                                    style={
 | 
				
			||||||
 | 
					                                        header.column.columnDef
 | 
				
			||||||
 | 
					                                            .headerClassName === "text-center"
 | 
				
			||||||
 | 
					                                            ? { justifySelf: "center" }
 | 
				
			||||||
 | 
					                                            : {}
 | 
				
			||||||
 | 
					                                    }
 | 
				
			||||||
                                    className={`btn btn-link text-decoration-none text-reset fw-bold p-0 d-flex align-items-center
 | 
					                                    className={`btn btn-link text-decoration-none text-reset fw-bold p-0 d-flex align-items-center
 | 
				
			||||||
                                                    ${
 | 
					                                                    ${
 | 
				
			||||||
                                                        header.column.getCanSort()
 | 
					                                                        header.column.getCanSort()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright (C) 2019-2024 CZ.NIC z.s.p.o. (https://www.nic.cz/)
 | 
					 * Copyright (C) 2019-2025 CZ.NIC z.s.p.o. (https://www.nic.cz/)
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * This is free software, licensed under the GNU General Public License v3.
 | 
					 * This is free software, licensed under the GNU General Public License v3.
 | 
				
			||||||
 * See /LICENSE for more information.
 | 
					 * See /LICENSE for more information.
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user