feat(dashboard): Refactor Users table to use the new DataTable block (#11058)
**What** - Updates the Users table to use the new DataTable - Fixes an issue where initial parsing of URL filters weren't formatted correctly.
This commit is contained in:
1 parent
0bef3202f3
commit
6346836c2d
12 files changed
+666
-1873
No files matched your search
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@medusajs/dashboard": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
feat(dashboard): Refactor Users table to use the new DataTable block
|
||||||
@@ -152,6 +152,7 @@ export const DataTable = <TData,>({
|
|||||||
const [filtering, setFiltering] = useState<DataTableFilteringState>(
|
const [filtering, setFiltering] = useState<DataTableFilteringState>(
|
||||||
parseFilterState(filterIds, filterParams)
|
parseFilterState(filterIds, filterParams)
|
||||||
)
|
)
|
||||||
|
|
||||||
const handleFilteringChange = (value: DataTableFilteringState) => {
|
const handleFilteringChange = (value: DataTableFilteringState) => {
|
||||||
setFiltering(value)
|
setFiltering(value)
|
||||||
|
|
||||||
@@ -341,10 +342,7 @@ function parseFilterState(
|
|||||||
const filterValue = value[id]
|
const filterValue = value[id]
|
||||||
|
|
||||||
if (filterValue) {
|
if (filterValue) {
|
||||||
filters[id] = {
|
filters[id] = JSON.parse(filterValue)
|
||||||
id,
|
|
||||||
value: JSON.parse(filterValue),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+95
@@ -0,0 +1,95 @@
|
|||||||
|
import { createDataTableFilterHelper } from "@medusajs/ui"
|
||||||
|
import { subDays, subMonths } from "date-fns"
|
||||||
|
import { useMemo } from "react"
|
||||||
|
import { useTranslation } from "react-i18next"
|
||||||
|
|
||||||
|
import { useDate } from "../../../../hooks/use-date"
|
||||||
|
|
||||||
|
const filterHelper = createDataTableFilterHelper<any>()
|
||||||
|
|
||||||
|
const useDateFilterOptions = () => {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
|
||||||
|
const today = useMemo(() => {
|
||||||
|
const date = new Date()
|
||||||
|
date.setHours(0, 0, 0, 0)
|
||||||
|
return date
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return useMemo(() => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: t("filters.date.today"),
|
||||||
|
value: {
|
||||||
|
$gte: today.toISOString(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t("filters.date.lastSevenDays"),
|
||||||
|
value: {
|
||||||
|
$gte: subDays(today, 7).toISOString(), // 7 days ago
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t("filters.date.lastThirtyDays"),
|
||||||
|
value: {
|
||||||
|
$gte: subDays(today, 30).toISOString(), // 30 days ago
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t("filters.date.lastNinetyDays"),
|
||||||
|
value: {
|
||||||
|
$gte: subDays(today, 90).toISOString(), // 90 days ago
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t("filters.date.lastTwelveMonths"),
|
||||||
|
value: {
|
||||||
|
$gte: subMonths(today, 12).toISOString(), // 12 months ago
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}, [today, t])
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useDataTableDateFilters = (disableRangeOption?: boolean) => {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
const { getFullDate } = useDate()
|
||||||
|
const dateFilterOptions = useDateFilterOptions()
|
||||||
|
|
||||||
|
const rangeOptions = useMemo(() => {
|
||||||
|
if (disableRangeOption) {
|
||||||
|
return {
|
||||||
|
disableRangeOption: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
rangeOptionStartLabel: t("filters.date.starting"),
|
||||||
|
rangeOptionEndLabel: t("filters.date.ending"),
|
||||||
|
rangeOptionLabel: t("filters.date.custom"),
|
||||||
|
options: dateFilterOptions,
|
||||||
|
}
|
||||||
|
}, [disableRangeOption, t, dateFilterOptions])
|
||||||
|
|
||||||
|
return useMemo(() => {
|
||||||
|
return [
|
||||||
|
filterHelper.accessor("created_at", {
|
||||||
|
type: "date",
|
||||||
|
label: t("fields.createdAt"),
|
||||||
|
format: "date",
|
||||||
|
formatDateValue: (date) => getFullDate({ date }),
|
||||||
|
options: dateFilterOptions,
|
||||||
|
...rangeOptions,
|
||||||
|
}),
|
||||||
|
filterHelper.accessor("updated_at", {
|
||||||
|
type: "date",
|
||||||
|
label: t("fields.updatedAt"),
|
||||||
|
format: "date",
|
||||||
|
formatDateValue: (date) => getFullDate({ date }),
|
||||||
|
options: dateFilterOptions,
|
||||||
|
...rangeOptions,
|
||||||
|
}),
|
||||||
|
]
|
||||||
|
}, [t, dateFilterOptions, getFullDate, rangeOptions])
|
||||||
|
}
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
import { useMemo } from "react"
|
|
||||||
import { useTranslation } from "react-i18next"
|
|
||||||
|
|
||||||
export const useDateFilterOptions = () => {
|
|
||||||
const { t } = useTranslation()
|
|
||||||
|
|
||||||
const today = useMemo(() => {
|
|
||||||
const date = new Date()
|
|
||||||
date.setHours(0, 0, 0, 0)
|
|
||||||
return date
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
return useMemo(() => {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
label: t("filters.date.today"),
|
|
||||||
value: {
|
|
||||||
$gte: today.toISOString(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: t("filters.date.lastSevenDays"),
|
|
||||||
value: {
|
|
||||||
$gte: new Date(
|
|
||||||
today.getTime() - 7 * 24 * 60 * 60 * 1000
|
|
||||||
).toISOString(), // 7 days ago
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: t("filters.date.lastThirtyDays"),
|
|
||||||
value: {
|
|
||||||
$gte: new Date(
|
|
||||||
today.getTime() - 30 * 24 * 60 * 60 * 1000
|
|
||||||
).toISOString(), // 30 days ago
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: t("filters.date.lastNinetyDays"),
|
|
||||||
value: {
|
|
||||||
$gte: new Date(
|
|
||||||
today.getTime() - 90 * 24 * 60 * 60 * 1000
|
|
||||||
).toISOString(), // 90 days ago
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: t("filters.date.lastTwelveMonths"),
|
|
||||||
value: {
|
|
||||||
$gte: new Date(
|
|
||||||
today.getTime() - 365 * 24 * 60 * 60 * 1000
|
|
||||||
).toISOString(), // 365 days ago
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}, [today, t])
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large.
Load diff
@@ -2279,6 +2279,16 @@
|
|||||||
"developer": "Developer",
|
"developer": "Developer",
|
||||||
"member": "Member"
|
"member": "Member"
|
||||||
},
|
},
|
||||||
|
"list": {
|
||||||
|
"empty": {
|
||||||
|
"heading": "No users found",
|
||||||
|
"description": "Once a user has been invited, they will appear here."
|
||||||
|
},
|
||||||
|
"filtered": {
|
||||||
|
"heading": "No results",
|
||||||
|
"description": "No users match the current filter criteria."
|
||||||
|
}
|
||||||
|
},
|
||||||
"deleteUserWarning": "You are about to delete the user {{name}}. This action cannot be undone.",
|
"deleteUserWarning": "You are about to delete the user {{name}}. This action cannot be undone.",
|
||||||
"deleteUserSuccess": "User {{name}} deleted successfully",
|
"deleteUserSuccess": "User {{name}} deleted successfully",
|
||||||
"invite": "Invite"
|
"invite": "Invite"
|
||||||
|
|||||||
+4
-30
@@ -3,7 +3,6 @@ import { HttpTypes } from "@medusajs/types"
|
|||||||
import {
|
import {
|
||||||
Container,
|
Container,
|
||||||
createDataTableColumnHelper,
|
createDataTableColumnHelper,
|
||||||
createDataTableFilterHelper,
|
|
||||||
toast,
|
toast,
|
||||||
usePrompt,
|
usePrompt,
|
||||||
} from "@medusajs/ui"
|
} from "@medusajs/ui"
|
||||||
@@ -13,13 +12,13 @@ import { useTranslation } from "react-i18next"
|
|||||||
import { useNavigate } from "react-router-dom"
|
import { useNavigate } from "react-router-dom"
|
||||||
|
|
||||||
import { DataTable } from "../../../../../components/data-table"
|
import { DataTable } from "../../../../../components/data-table"
|
||||||
|
import { useDataTableDateFilters } from "../../../../../components/data-table/hooks/general/use-data-table-date-filters"
|
||||||
import { SingleColumnPage } from "../../../../../components/layout/pages"
|
import { SingleColumnPage } from "../../../../../components/layout/pages"
|
||||||
import { useDashboardExtension } from "../../../../../extensions"
|
import { useDashboardExtension } from "../../../../../extensions"
|
||||||
import {
|
import {
|
||||||
useCustomerGroups,
|
useCustomerGroups,
|
||||||
useDeleteCustomerGroupLazy,
|
useDeleteCustomerGroupLazy,
|
||||||
} from "../../../../../hooks/api"
|
} from "../../../../../hooks/api"
|
||||||
import { useDateFilterOptions } from "../../../../../hooks/filters/use-date-filter-options"
|
|
||||||
import { useDate } from "../../../../../hooks/use-date"
|
import { useDate } from "../../../../../hooks/use-date"
|
||||||
import { useQueryParams } from "../../../../../hooks/use-query-params"
|
import { useQueryParams } from "../../../../../hooks/use-query-params"
|
||||||
|
|
||||||
@@ -215,35 +214,10 @@ const useColumns = () => {
|
|||||||
}, [t, navigate, getFullDate, handleDeleteCustomerGroup])
|
}, [t, navigate, getFullDate, handleDeleteCustomerGroup])
|
||||||
}
|
}
|
||||||
|
|
||||||
const filterHelper = createDataTableFilterHelper<HttpTypes.AdminCustomerGroup>()
|
|
||||||
|
|
||||||
const useFilters = () => {
|
const useFilters = () => {
|
||||||
const { t } = useTranslation()
|
const dateFilters = useDataTableDateFilters()
|
||||||
const { getFullDate } = useDate()
|
|
||||||
const dateFilterOptions = useDateFilterOptions()
|
|
||||||
|
|
||||||
return useMemo(() => {
|
return useMemo(() => {
|
||||||
return [
|
return dateFilters
|
||||||
filterHelper.accessor("created_at", {
|
}, [dateFilters])
|
||||||
type: "date",
|
|
||||||
label: t("fields.createdAt"),
|
|
||||||
format: "date",
|
|
||||||
formatDateValue: (date) => getFullDate({ date }),
|
|
||||||
rangeOptionStartLabel: t("filters.date.starting"),
|
|
||||||
rangeOptionEndLabel: t("filters.date.ending"),
|
|
||||||
rangeOptionLabel: t("filters.date.custom"),
|
|
||||||
options: dateFilterOptions,
|
|
||||||
}),
|
|
||||||
filterHelper.accessor("updated_at", {
|
|
||||||
type: "date",
|
|
||||||
label: t("fields.updatedAt"),
|
|
||||||
format: "date",
|
|
||||||
rangeOptionStartLabel: t("filters.date.starting"),
|
|
||||||
rangeOptionEndLabel: t("filters.date.ending"),
|
|
||||||
rangeOptionLabel: t("filters.date.custom"),
|
|
||||||
formatDateValue: (date) => getFullDate({ date }),
|
|
||||||
options: dateFilterOptions,
|
|
||||||
}),
|
|
||||||
]
|
|
||||||
}, [t, dateFilterOptions, getFullDate])
|
|
||||||
}
|
}
|
||||||
+4
-25
@@ -18,12 +18,11 @@ import { useTranslation } from "react-i18next"
|
|||||||
import { CellContext } from "@tanstack/react-table"
|
import { CellContext } from "@tanstack/react-table"
|
||||||
import { useNavigate } from "react-router-dom"
|
import { useNavigate } from "react-router-dom"
|
||||||
import { DataTable } from "../../../../../components/data-table"
|
import { DataTable } from "../../../../../components/data-table"
|
||||||
|
import { useDataTableDateFilters } from "../../../../../components/data-table/hooks/general/use-data-table-date-filters"
|
||||||
import {
|
import {
|
||||||
useDeleteVariantLazy,
|
useDeleteVariantLazy,
|
||||||
useProductVariants,
|
useProductVariants,
|
||||||
} from "../../../../../hooks/api/products"
|
} from "../../../../../hooks/api/products"
|
||||||
import { useDateFilterOptions } from "../../../../../hooks/filters/use-date-filter-options"
|
|
||||||
import { useDate } from "../../../../../hooks/use-date"
|
|
||||||
import { useQueryParams } from "../../../../../hooks/use-query-params"
|
import { useQueryParams } from "../../../../../hooks/use-query-params"
|
||||||
import { PRODUCT_VARIANT_IDS_KEY } from "../../../common/constants"
|
import { PRODUCT_VARIANT_IDS_KEY } from "../../../common/constants"
|
||||||
|
|
||||||
@@ -357,8 +356,7 @@ const filterHelper =
|
|||||||
|
|
||||||
const useFilters = () => {
|
const useFilters = () => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const { getFullDate } = useDate()
|
const dateFilters = useDataTableDateFilters()
|
||||||
const dateFilterOptions = useDateFilterOptions()
|
|
||||||
|
|
||||||
return useMemo(() => {
|
return useMemo(() => {
|
||||||
return [
|
return [
|
||||||
@@ -378,28 +376,9 @@ const useFilters = () => {
|
|||||||
{ label: t("filters.radio.no"), value: "false" },
|
{ label: t("filters.radio.no"), value: "false" },
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
filterHelper.accessor("created_at", {
|
...dateFilters,
|
||||||
type: "date",
|
|
||||||
label: t("fields.createdAt"),
|
|
||||||
format: "date",
|
|
||||||
formatDateValue: (date) => getFullDate({ date }),
|
|
||||||
rangeOptionStartLabel: t("filters.date.starting"),
|
|
||||||
rangeOptionEndLabel: t("filters.date.ending"),
|
|
||||||
rangeOptionLabel: t("filters.date.custom"),
|
|
||||||
options: dateFilterOptions,
|
|
||||||
}),
|
|
||||||
filterHelper.accessor("updated_at", {
|
|
||||||
type: "date",
|
|
||||||
label: t("fields.updatedAt"),
|
|
||||||
format: "date",
|
|
||||||
rangeOptionStartLabel: t("filters.date.starting"),
|
|
||||||
rangeOptionEndLabel: t("filters.date.ending"),
|
|
||||||
rangeOptionLabel: t("filters.date.custom"),
|
|
||||||
formatDateValue: (date) => getFullDate({ date }),
|
|
||||||
options: dateFilterOptions,
|
|
||||||
}),
|
|
||||||
]
|
]
|
||||||
}, [t, dateFilterOptions, getFullDate])
|
}, [t, dateFilters])
|
||||||
}
|
}
|
||||||
|
|
||||||
const commandHelper = createDataTableCommandHelper()
|
const commandHelper = createDataTableCommandHelper()
|
||||||
|
|||||||
-42
@@ -1,42 +0,0 @@
|
|||||||
import { UserDTO } from "@medusajs/types"
|
|
||||||
import { createColumnHelper } from "@tanstack/react-table"
|
|
||||||
import { useMemo } from "react"
|
|
||||||
import { useTranslation } from "react-i18next"
|
|
||||||
import { UserRowActions } from "./user-row-actions"
|
|
||||||
|
|
||||||
const columnHelper = createColumnHelper<UserDTO>()
|
|
||||||
|
|
||||||
export const useUserTableColumns = () => {
|
|
||||||
const { t } = useTranslation()
|
|
||||||
|
|
||||||
return useMemo(
|
|
||||||
() => [
|
|
||||||
columnHelper.accessor("email", {
|
|
||||||
header: t("fields.email"),
|
|
||||||
cell: ({ row }) => {
|
|
||||||
return row.original.email
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
columnHelper.display({
|
|
||||||
id: "name",
|
|
||||||
header: t("fields.name"),
|
|
||||||
cell: ({ row }) => {
|
|
||||||
const name = [row.original.first_name, row.original.last_name]
|
|
||||||
.filter(Boolean)
|
|
||||||
.join(" ")
|
|
||||||
|
|
||||||
if (!name) {
|
|
||||||
return <span className="text-ui-fg-muted">-</span>
|
|
||||||
}
|
|
||||||
|
|
||||||
return name
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
columnHelper.display({
|
|
||||||
id: "actions",
|
|
||||||
cell: ({ row }) => <UserRowActions user={row.original} />,
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
[t]
|
|
||||||
)
|
|
||||||
}
|
|
||||||
-24
@@ -1,24 +0,0 @@
|
|||||||
import { useQueryParams } from "../../../../../hooks/use-query-params"
|
|
||||||
|
|
||||||
export const useUserTableQuery = ({
|
|
||||||
pageSize = 20,
|
|
||||||
prefix,
|
|
||||||
}: {
|
|
||||||
pageSize?: number
|
|
||||||
prefix?: string
|
|
||||||
}) => {
|
|
||||||
const raw = useQueryParams(["q", "order", "offset"], prefix)
|
|
||||||
|
|
||||||
const { offset, ...params } = raw
|
|
||||||
|
|
||||||
const searchParams = {
|
|
||||||
limit: pageSize,
|
|
||||||
offset: offset ? parseInt(offset) : 0,
|
|
||||||
...params,
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
searchParams,
|
|
||||||
raw,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+123
-46
@@ -1,39 +1,35 @@
|
|||||||
import { Button, Container, Heading } from "@medusajs/ui"
|
import { HttpTypes } from "@medusajs/types"
|
||||||
|
import { Container, createDataTableColumnHelper } from "@medusajs/ui"
|
||||||
import { keepPreviousData } from "@tanstack/react-query"
|
import { keepPreviousData } from "@tanstack/react-query"
|
||||||
|
import { useMemo } from "react"
|
||||||
import { useTranslation } from "react-i18next"
|
import { useTranslation } from "react-i18next"
|
||||||
import { Link } from "react-router-dom"
|
import { useNavigate } from "react-router-dom"
|
||||||
import { _DataTable } from "../../../../../components/table/data-table"
|
|
||||||
|
import { PencilSquare } from "@medusajs/icons"
|
||||||
|
import { DataTable } from "../../../../../components/data-table"
|
||||||
|
import { useDataTableDateFilters } from "../../../../../components/data-table/hooks/general/use-data-table-date-filters"
|
||||||
import { useUsers } from "../../../../../hooks/api/users"
|
import { useUsers } from "../../../../../hooks/api/users"
|
||||||
import { useDataTable } from "../../../../../hooks/use-data-table"
|
import { useDate } from "../../../../../hooks/use-date"
|
||||||
import { useUserTableColumns } from "./use-user-table-columns"
|
import { useQueryParams } from "../../../../../hooks/use-query-params"
|
||||||
import { useUserTableQuery } from "./use-user-table-query"
|
|
||||||
|
|
||||||
const PAGE_SIZE = 20
|
const PAGE_SIZE = 20
|
||||||
|
|
||||||
export const UserListTable = () => {
|
export const UserListTable = () => {
|
||||||
const { raw, searchParams } = useUserTableQuery({
|
const { q, order, offset } = useQueryParams(["q", "order", "offset"])
|
||||||
pageSize: PAGE_SIZE,
|
const { users, count, isPending, isError, error } = useUsers(
|
||||||
})
|
{
|
||||||
const {
|
q,
|
||||||
users,
|
order,
|
||||||
count,
|
offset: offset ? parseInt(offset) : 0,
|
||||||
isPending: isLoading,
|
limit: PAGE_SIZE,
|
||||||
isError,
|
},
|
||||||
error,
|
{
|
||||||
} = useUsers(searchParams, {
|
|
||||||
placeholderData: keepPreviousData,
|
placeholderData: keepPreviousData,
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
const columns = useUserTableColumns()
|
const columns = useColumns()
|
||||||
|
const filters = useFilters()
|
||||||
const { table } = useDataTable({
|
|
||||||
data: users ?? [],
|
|
||||||
columns,
|
|
||||||
count,
|
|
||||||
enablePagination: true,
|
|
||||||
getRowId: (row) => row.id,
|
|
||||||
pageSize: PAGE_SIZE,
|
|
||||||
})
|
|
||||||
|
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
@@ -43,28 +39,109 @@ export const UserListTable = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Container className="divide-y p-0">
|
<Container className="divide-y p-0">
|
||||||
<div className="flex items-center justify-between px-6 py-4">
|
<DataTable
|
||||||
<Heading>{t("users.domain")}</Heading>
|
data={users}
|
||||||
<Button size="small" variant="secondary" asChild>
|
|
||||||
<Link to="invite">{t("users.invite")}</Link>
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
<_DataTable
|
|
||||||
table={table}
|
|
||||||
columns={columns}
|
columns={columns}
|
||||||
count={count}
|
filters={filters}
|
||||||
|
getRowId={(row) => row.id}
|
||||||
|
rowCount={count}
|
||||||
pageSize={PAGE_SIZE}
|
pageSize={PAGE_SIZE}
|
||||||
isLoading={isLoading}
|
heading={t("users.domain")}
|
||||||
orderBy={[
|
rowHref={(row) => `${row.id}`}
|
||||||
{ key: "email", label: t("fields.email") },
|
isLoading={isPending}
|
||||||
{ key: "first_name", label: t("fields.firstName") },
|
action={{
|
||||||
{ key: "last_name", label: t("fields.lastName") },
|
label: t("users.invite"),
|
||||||
]}
|
to: "invite",
|
||||||
navigateTo={(row) => `${row.id}`}
|
}}
|
||||||
search
|
emptyState={{
|
||||||
pagination
|
empty: {
|
||||||
queryObject={raw}
|
heading: t("users.list.empty.heading"),
|
||||||
|
description: t("users.list.empty.description"),
|
||||||
|
},
|
||||||
|
filtered: {
|
||||||
|
heading: t("users.list.filtered.heading"),
|
||||||
|
description: t("users.list.filtered.description"),
|
||||||
|
},
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Container>
|
</Container>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const columnHelper = createDataTableColumnHelper<HttpTypes.AdminUser>()
|
||||||
|
|
||||||
|
const useColumns = () => {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
const navigate = useNavigate()
|
||||||
|
const { getFullDate } = useDate()
|
||||||
|
|
||||||
|
return useMemo(
|
||||||
|
() => [
|
||||||
|
columnHelper.accessor("email", {
|
||||||
|
header: t("fields.email"),
|
||||||
|
cell: ({ row }) => {
|
||||||
|
return row.original.email
|
||||||
|
},
|
||||||
|
enableSorting: true,
|
||||||
|
sortAscLabel: t("filters.sorting.alphabeticallyAsc"),
|
||||||
|
sortDescLabel: t("filters.sorting.alphabeticallyDesc"),
|
||||||
|
}),
|
||||||
|
columnHelper.accessor("first_name", {
|
||||||
|
header: t("fields.firstName"),
|
||||||
|
cell: ({ row }) => {
|
||||||
|
return row.original.first_name || "-"
|
||||||
|
},
|
||||||
|
enableSorting: true,
|
||||||
|
sortAscLabel: t("filters.sorting.alphabeticallyAsc"),
|
||||||
|
sortDescLabel: t("filters.sorting.alphabeticallyDesc"),
|
||||||
|
}),
|
||||||
|
columnHelper.accessor("last_name", {
|
||||||
|
header: t("fields.lastName"),
|
||||||
|
cell: ({ row }) => {
|
||||||
|
return row.original.last_name || "-"
|
||||||
|
},
|
||||||
|
enableSorting: true,
|
||||||
|
sortAscLabel: t("filters.sorting.alphabeticallyAsc"),
|
||||||
|
sortDescLabel: t("filters.sorting.alphabeticallyDesc"),
|
||||||
|
}),
|
||||||
|
columnHelper.accessor("created_at", {
|
||||||
|
header: t("fields.createdAt"),
|
||||||
|
cell: ({ row }) => {
|
||||||
|
return getFullDate({ date: row.original.created_at })
|
||||||
|
},
|
||||||
|
enableSorting: true,
|
||||||
|
sortAscLabel: t("filters.sorting.dateAsc"),
|
||||||
|
sortDescLabel: t("filters.sorting.dateDesc"),
|
||||||
|
}),
|
||||||
|
columnHelper.accessor("updated_at", {
|
||||||
|
header: t("fields.updatedAt"),
|
||||||
|
cell: ({ row }) => {
|
||||||
|
return getFullDate({ date: row.original.updated_at })
|
||||||
|
},
|
||||||
|
enableSorting: true,
|
||||||
|
sortAscLabel: t("filters.sorting.dateAsc"),
|
||||||
|
sortDescLabel: t("filters.sorting.dateDesc"),
|
||||||
|
}),
|
||||||
|
columnHelper.action({
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
label: t("actions.edit"),
|
||||||
|
icon: <PencilSquare />,
|
||||||
|
onClick: (ctx) => {
|
||||||
|
navigate(`${ctx.row.original.id}/edit`)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
[t, getFullDate, navigate]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const useFilters = () => {
|
||||||
|
const dateFilters = useDataTableDateFilters()
|
||||||
|
|
||||||
|
return useMemo(() => {
|
||||||
|
return dateFilters
|
||||||
|
}, [dateFilters])
|
||||||
|
}
|
||||||
-24
@@ -1,24 +0,0 @@
|
|||||||
import { PencilSquare } from "@medusajs/icons"
|
|
||||||
import { UserDTO } from "@medusajs/types"
|
|
||||||
import { useTranslation } from "react-i18next"
|
|
||||||
import { ActionMenu } from "../../../../../components/common/action-menu"
|
|
||||||
|
|
||||||
export const UserRowActions = ({ user }: { user: UserDTO }) => {
|
|
||||||
const { t } = useTranslation()
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ActionMenu
|
|
||||||
groups={[
|
|
||||||
{
|
|
||||||
actions: [
|
|
||||||
{
|
|
||||||
icon: <PencilSquare />,
|
|
||||||
label: t("actions.edit"),
|
|
||||||
to: `${user.id}/edit`,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Reference in new issue
Block a user