**Dashboard** - Adds different views for managing manual/custom gift cards (not associated with a product gift card). - Cleans up several table implementations to use new DataTable component. - Minor cleanup of translation file. **Medusa** - Adds missing query params for list endpoints in the following admin domains: /customers, /customer-groups, /collections, and /gift-cards. **UI** - Adds new sizes for Badge component. **Note for review** Since this PR contains updates to the translation keys, it touches a lot of files. For the review the parts that are relevant are: the /gift-cards domain of admin, the table overview of collections, customers, and customer groups. And the changes to the list endpoints in the core.
116 lines
2.7 KiB
TypeScript
116 lines
2.7 KiB
TypeScript
import {
|
|
ColumnDef,
|
|
OnChangeFn,
|
|
PaginationState,
|
|
Row,
|
|
getCoreRowModel,
|
|
getPaginationRowModel,
|
|
useReactTable,
|
|
} from "@tanstack/react-table"
|
|
import { useEffect, useMemo, useState } from "react"
|
|
import { useSearchParams } from "react-router-dom"
|
|
|
|
type UseDataTableProps<TData> = {
|
|
data?: TData[]
|
|
columns: ColumnDef<TData, any>[]
|
|
count?: number
|
|
pageSize?: number
|
|
enableRowSelection?: boolean | ((row: Row<TData>) => boolean)
|
|
enablePagination?: boolean
|
|
getRowId?: (original: TData, index: number) => string
|
|
meta?: Record<string, unknown>
|
|
prefix?: string
|
|
}
|
|
|
|
export const useDataTable = <TData,>({
|
|
data = [],
|
|
columns,
|
|
count = 0,
|
|
pageSize: _pageSize = 20,
|
|
enablePagination = true,
|
|
enableRowSelection = false,
|
|
getRowId,
|
|
meta,
|
|
prefix,
|
|
}: UseDataTableProps<TData>) => {
|
|
const [searchParams, setSearchParams] = useSearchParams()
|
|
const offsetKey = `${prefix ? `${prefix}_` : ""}offset`
|
|
const offset = searchParams.get(offsetKey)
|
|
|
|
const [{ pageIndex, pageSize }, setPagination] = useState<PaginationState>({
|
|
pageIndex: offset ? Math.ceil(Number(offset) / _pageSize) : 0,
|
|
pageSize: _pageSize,
|
|
})
|
|
const pagination = useMemo(
|
|
() => ({
|
|
pageIndex,
|
|
pageSize,
|
|
}),
|
|
[pageIndex, pageSize]
|
|
)
|
|
const [rowSelection, setRowSelection] = useState({})
|
|
|
|
useEffect(() => {
|
|
if (!enablePagination) {
|
|
return
|
|
}
|
|
|
|
const index = offset ? Math.ceil(Number(offset) / _pageSize) : 0
|
|
|
|
if (index === pageIndex) {
|
|
return
|
|
}
|
|
|
|
setPagination((prev) => ({
|
|
...prev,
|
|
pageIndex: index,
|
|
}))
|
|
}, [offset, enablePagination, _pageSize, pageIndex])
|
|
|
|
const onPaginationChange = (
|
|
updater: (old: PaginationState) => PaginationState
|
|
) => {
|
|
const state = updater(pagination)
|
|
const { pageIndex, pageSize } = state
|
|
|
|
setSearchParams((prev) => {
|
|
if (!pageIndex) {
|
|
prev.delete(offsetKey)
|
|
return prev
|
|
}
|
|
|
|
const newSearch = new URLSearchParams(prev)
|
|
newSearch.set(offsetKey, String(pageIndex * pageSize))
|
|
|
|
return newSearch
|
|
})
|
|
|
|
setPagination(state)
|
|
return state
|
|
}
|
|
|
|
const table = useReactTable({
|
|
data,
|
|
columns,
|
|
state: {
|
|
rowSelection,
|
|
pagination: enablePagination ? pagination : undefined,
|
|
},
|
|
pageCount: Math.ceil((count ?? 0) / pageSize),
|
|
enableRowSelection,
|
|
getRowId,
|
|
onRowSelectionChange: enableRowSelection ? setRowSelection : undefined,
|
|
onPaginationChange: enablePagination
|
|
? (onPaginationChange as OnChangeFn<PaginationState>)
|
|
: undefined,
|
|
getCoreRowModel: getCoreRowModel(),
|
|
getPaginationRowModel: enablePagination
|
|
? getPaginationRowModel()
|
|
: undefined,
|
|
manualPagination: enablePagination ? true : undefined,
|
|
meta,
|
|
})
|
|
|
|
return { table }
|
|
}
|