Table.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import { IconDotsVertical, IconEdit, IconPower, IconTrash } from "@tabler/icons-react";
  2. import { createColumnHelper, getCoreRowModel, useReactTable } from "@tanstack/react-table";
  3. import { useMemo } from "react";
  4. import type { Certificate } from "src/api/backend";
  5. import { DomainsFormatter, GravatarFormatter } from "src/components";
  6. import { TableLayout } from "src/components/Table/TableLayout";
  7. import { intl, T } from "src/locale";
  8. import Empty from "./Empty";
  9. interface Props {
  10. data: Certificate[];
  11. isFetching?: boolean;
  12. }
  13. export default function Table({ data, isFetching }: Props) {
  14. const columnHelper = createColumnHelper<Certificate>();
  15. const columns = useMemo(
  16. () => [
  17. columnHelper.accessor((row: any) => row.owner, {
  18. id: "owner",
  19. cell: (info: any) => {
  20. const value = info.getValue();
  21. return <GravatarFormatter url={value.avatar} name={value.name} />;
  22. },
  23. meta: {
  24. className: "w-1",
  25. },
  26. }),
  27. columnHelper.accessor((row: any) => row, {
  28. id: "domainNames",
  29. header: intl.formatMessage({ id: "column.name" }),
  30. cell: (info: any) => {
  31. const value = info.getValue();
  32. return <DomainsFormatter domains={value.domainNames} createdOn={value.createdOn} />;
  33. },
  34. }),
  35. columnHelper.accessor((row: any) => row.provider, {
  36. id: "provider",
  37. header: intl.formatMessage({ id: "column.provider" }),
  38. cell: (info: any) => {
  39. return info.getValue();
  40. },
  41. }),
  42. columnHelper.accessor((row: any) => row.expires_on, {
  43. id: "expires_on",
  44. header: intl.formatMessage({ id: "column.expires" }),
  45. cell: (info: any) => {
  46. return info.getValue();
  47. },
  48. }),
  49. columnHelper.accessor((row: any) => row, {
  50. id: "id",
  51. header: intl.formatMessage({ id: "column.status" }),
  52. cell: (info: any) => {
  53. return info.getValue();
  54. },
  55. }),
  56. columnHelper.display({
  57. id: "id", // todo: not needed for a display?
  58. cell: (info: any) => {
  59. return (
  60. <span className="dropdown">
  61. <button
  62. type="button"
  63. className="btn dropdown-toggle btn-action btn-sm px-1"
  64. data-bs-boundary="viewport"
  65. data-bs-toggle="dropdown"
  66. >
  67. <IconDotsVertical />
  68. </button>
  69. <div className="dropdown-menu dropdown-menu-end">
  70. <span className="dropdown-header">
  71. <T id="certificates.actions-title" data={{ id: info.row.original.id }} />
  72. </span>
  73. <a className="dropdown-item" href="#">
  74. <IconEdit size={16} />
  75. <T id="action.edit" />
  76. </a>
  77. <a className="dropdown-item" href="#">
  78. <IconPower size={16} />
  79. <T id="action.disable" />
  80. </a>
  81. <div className="dropdown-divider" />
  82. <a className="dropdown-item" href="#">
  83. <IconTrash size={16} />
  84. <T id="action.delete" />
  85. </a>
  86. </div>
  87. </span>
  88. );
  89. },
  90. meta: {
  91. className: "text-end w-1",
  92. },
  93. }),
  94. ],
  95. [columnHelper],
  96. );
  97. const tableInstance = useReactTable<Certificate>({
  98. columns,
  99. data,
  100. getCoreRowModel: getCoreRowModel(),
  101. rowCount: data.length,
  102. meta: {
  103. isFetching,
  104. },
  105. enableSortingRemoval: false,
  106. });
  107. return <TableLayout tableInstance={tableInstance} emptyState={<Empty tableInstance={tableInstance} />} />;
  108. }