import { CustomerGroup, Product, ProductCollection, ProductTag, ProductType, } from "@medusajs/medusa" import React, { useCallback, useEffect, useMemo, useState } from "react" import { Column, HeaderGroup, Row, usePagination, useRowSelect, useSortBy, useTable, } from "react-table" import { useDebounce } from "../../../hooks/use-debounce" import useQueryFilters from "../../../hooks/use-query-filters" import IndeterminateCheckbox from "../../molecules/indeterminate-checkbox" import Table, { TableProps } from "../../molecules/table" import TableContainer from "../../organisms/table-container" type SelectableTableProps = { resourceName?: string label?: string isLoading?: boolean totalCount: number options: Omit< TableProps, "filteringOptions" | "searchValue" | "handleSearch" > & { filters?: Pick } data?: T[] selectedIds?: string[] columns: Column[] onChange?: (items: string[]) => void renderRow: (props: { row: Row }) => React.ReactElement renderHeaderGroup?: (props: { headerGroup: HeaderGroup }) => React.ReactElement } & ReturnType export const SelectableTable = < T extends | Product | CustomerGroup | ProductCollection | ProductTag | ProductType >({ label, resourceName = "", selectedIds = [], isLoading, totalCount = 0, data, columns, onChange, options, renderRow, renderHeaderGroup, setQuery, queryObject, paginate, }: SelectableTableProps) => { const memoizedData = useMemo(() => data || [], [data]) const table = useTable( { columns, data: memoizedData, manualPagination: true, initialState: { pageIndex: queryObject.offset / queryObject.limit, pageSize: queryObject.limit, selectedRowIds: selectedIds.reduce((prev, id) => { prev[id] = true return prev }, {} as Record), }, pageCount: Math.ceil(totalCount / queryObject.limit), autoResetSelectedRows: false, autoResetPage: false, getRowId: (row: any) => row.id, }, useSortBy, usePagination, useRowSelect, useSelectionColumn ) useEffect(() => { if (onChange) { onChange(Object.keys(table.state.selectedRowIds)) } }, [table.state.selectedRowIds]) const handleNext = () => { if (!table.canNextPage) { return } paginate(1) table.nextPage() } const handlePrev = () => { if (!table.canPreviousPage) { return } paginate(-1) table.previousPage() } const handleSearch = useCallback( (text: string) => { setQuery(text) if (text) { table.gotoPage(0) } }, [setQuery, table] ) const [searchQuery, setSearchQuery] = useState("") const debouncedSearch = useDebounce(searchQuery, 500) useEffect(() => { handleSearch(debouncedSearch) }, [debouncedSearch]) return (
{label &&
{label}
} {renderHeaderGroup && ( {table.headerGroups?.map((headerGroup) => renderHeaderGroup({ headerGroup }) )} )} {table.rows.map((row) => { table.prepareRow(row) return renderRow({ row }) })}
) } const useSelectionColumn = (hooks) => { hooks.visibleColumns.push((columns) => [ { id: "selection", Header: ({ getToggleAllRowsSelectedProps }) => { return (
e.stopPropagation()} />
) }, Cell: ({ row }) => { return (
e.stopPropagation()} />
) }, }, ...columns, ]) }