Source

adminjs/src/frontend/components/app/records-table/records-table.tsx

  1. import React from 'react'
  2. import { Table, TableBody, Loader } from '@adminjs/design-system'
  3. import RecordInList from './record-in-list'
  4. import RecordsTableHeader from './records-table-header'
  5. import NoRecords from './no-records'
  6. import { RecordJSON, ResourceJSON } from '../../../interfaces'
  7. import SelectedRecords from './selected-records'
  8. import { ActionResponse } from '../../../../backend/actions/action.interface'
  9. /**
  10. * @alias RecordsTableProps
  11. * @memberof RecordsTable
  12. */
  13. export type RecordsTableProps = {
  14. /**
  15. * Resource which type records are rendered. Base on that we define which columns should be seen.
  16. */
  17. resource: ResourceJSON;
  18. /**
  19. * Array of records seen in the table
  20. */
  21. records: Array<RecordJSON>;
  22. /**
  23. * Handler function invoked when someone performs action without component on a given record.
  24. * Action without component is a `delete` action - you might want to refresh the list after that
  25. */
  26. actionPerformed?: (response: ActionResponse) => any;
  27. /** default sort by column */
  28. sortBy?: string;
  29. /** sort direction */
  30. direction?: 'asc' | 'desc';
  31. /** indicates if the table should be in loading state */
  32. isLoading?: boolean;
  33. /** list of selected records */
  34. selectedRecords?: Array<RecordJSON>;
  35. /** handler function triggered when record is selected */
  36. onSelect?: (record: RecordJSON) => any;
  37. /** handler function triggered when all items are selected */
  38. onSelectAll?: () => any;
  39. }
  40. /**
  41. * @classdesc
  42. * Renders an entire records table. To fill the data you might need:
  43. *
  44. * - {@link useRecords} and
  45. * - {@link useSelectedRecords} hooks
  46. *
  47. * so make sure to see at the documentation pages for both of them
  48. *
  49. * @component
  50. * @class
  51. * @hideconstructor
  52. * @subcategory Application
  53. * @new in version 3.3
  54. */
  55. export const RecordsTable: React.FC<RecordsTableProps> = (props) => {
  56. const {
  57. resource, records,
  58. actionPerformed, sortBy,
  59. direction, isLoading,
  60. onSelect, selectedRecords,
  61. onSelectAll,
  62. } = props
  63. if (!records.length) {
  64. if (isLoading) {
  65. return (<Loader />)
  66. }
  67. return (<NoRecords resource={resource} />)
  68. }
  69. const selectedAll = selectedRecords && !!records.find(record => (
  70. selectedRecords.find(selected => selected.id === record.id)
  71. ))
  72. const recordsHaveBulkAction = !!records.find(record => record.bulkActions.length)
  73. return (
  74. <Table>
  75. <SelectedRecords
  76. resource={resource}
  77. selectedRecords={selectedRecords}
  78. />
  79. <RecordsTableHeader
  80. properties={resource.listProperties}
  81. titleProperty={resource.titleProperty}
  82. direction={direction}
  83. sortBy={sortBy}
  84. onSelectAll={recordsHaveBulkAction ? onSelectAll : undefined}
  85. selectedAll={selectedAll}
  86. />
  87. <TableBody>
  88. {records.map(record => (
  89. <RecordInList
  90. record={record}
  91. resource={resource}
  92. key={record.id}
  93. actionPerformed={actionPerformed}
  94. isLoading={isLoading}
  95. onSelect={onSelect}
  96. isSelected={
  97. selectedRecords && !!selectedRecords.find(selected => selected.id === record.id)
  98. }
  99. />
  100. ))}
  101. </TableBody>
  102. </Table>
  103. )
  104. }
  105. export default RecordsTable