From 03b873eee1114d3394a5a89e8cc74dcebc448566 Mon Sep 17 00:00:00 2001 From: Colin Regourd Date: Mon, 16 Oct 2023 18:44:46 +0200 Subject: [PATCH] centralize option for next admin --- apps/example/pages/admin/[[...nextadmin]].tsx | 189 ++++++++---------- .../next-admin/src/components/DataTable.tsx | 19 +- packages/next-admin/src/components/List.tsx | 5 +- packages/next-admin/src/types.ts | 20 +- packages/next-admin/src/utils/prisma.ts | 11 - 5 files changed, 106 insertions(+), 138 deletions(-) diff --git a/apps/example/pages/admin/[[...nextadmin]].tsx b/apps/example/pages/admin/[[...nextadmin]].tsx index 1c487b08..e4b1a31b 100644 --- a/apps/example/pages/admin/[[...nextadmin]].tsx +++ b/apps/example/pages/admin/[[...nextadmin]].tsx @@ -10,26 +10,98 @@ import { } from "@premieroctet/next-admin"; import Dashboard from "../../components/Dashboard"; +const options: NextAdminOptions = { + basePath: "/admin", + model: { + User: { + toString: (user) => `${user.name} (${user.email})`, + list: { + fields: { + name: { + search: true, + display: true, + }, + email: { + search: true, + display: true, + }, + role: { + search: true, + display: true, + formatter: (user) => { + return {user.role as string}; + }, + }, + posts: { + search: true, + display: true, + }, + }, + }, + edit: { + fields: { + id: { + display: true, + }, + name: { + display: true, + }, + email: { + display: true, + validate: (email) => email.includes("@") || "Invalid email", + }, + role: { + display: true, + }, + posts: { + display: true, + }, + profile: { + display: true, + }, + }, + }, + }, + Post: { + toString: (post) => `${post.title}`, + list: { + fields: { + id: { + search: true, + display: true, + }, + title: { + search: true, + display: true, + }, + content: { + search: true, + display: true, + }, + published: { + display: true, + }, + authorId: { + display: true, + }, + categories: { + display: true, + }, + }, + }, + }, + Category: { + toString: (category) => `${category.name}`, + }, + }, +}; + export default function Admin(props: AdminComponentProps) { return ( { - return {user.role as string}; - }, - }, - }, - }, - }, - }, - }} + options={options} /> ); } @@ -39,93 +111,6 @@ export const getServerSideProps: GetServerSideProps = async ({ req, res }) => { "@premieroctet/next-admin/dist/router" ); - const options: NextAdminOptions = { - basePath: "/admin", - model: { - User: { - toString: (user) => `${user.name} (${user.email})`, - list: { - fields: { - id: { - search: true, - display: true, - }, - name: { - search: true, - display: true, - }, - email: { - search: true, - display: true, - }, - role: { - search: true, - display: true, - }, - posts: { - search: true, - display: true, - }, - }, - }, - edit: { - fields: { - id: { - display: true, - }, - name: { - display: true, - }, - email: { - display: true, - validate: (email) => email.includes("@") || "Invalid email", - }, - role: { - display: true, - }, - posts: { - display: true, - }, - profile: { - display: true, - }, - }, - }, - }, - Post: { - toString: (post) => `${post.title}`, - list: { - fields: { - id: { - search: true, - display: true, - }, - title: { - search: true, - display: true, - }, - content: { - search: true, - display: true, - }, - published: { - display: true, - }, - authorId: { - display: true, - }, - categories: { - display: true, - }, - }, - }, - }, - Category: { - toString: (category) => `${category.name}`, - }, - }, - }; - const adminRouter = await nextAdminRouter(prisma, schema, options); return adminRouter.run(req, res) as Promise< GetServerSidePropsResult<{ [key: string]: any }> diff --git a/packages/next-admin/src/components/DataTable.tsx b/packages/next-admin/src/components/DataTable.tsx index 0e1a6cf7..5da7c050 100644 --- a/packages/next-admin/src/components/DataTable.tsx +++ b/packages/next-admin/src/components/DataTable.tsx @@ -15,25 +15,34 @@ import { TableRow, } from "./radix/Table"; import { useRouter } from "next/compat/router"; -import { ListData, ListDataItem, ModelName } from "../types"; +import { ListData, ListDataItem, ModelName, Field, NextAdminOptions } from "../types"; import { useConfig } from "../context/ConfigContext"; interface DataTableProps { - columns: ColumnDef, { id: string }>[]; + columns: ColumnDef>[]; data: ListData; resource: ModelName; + options: (Required)['model'][ModelName] } -export function DataTable({ columns, data, resource }: DataTableProps) { +export function DataTable({ columns, data, resource, options }: DataTableProps) { const router = useRouter(); const { basePath } = useConfig() + const hasDisplayField = options?.list?.fields && Object.values(options?.list?.fields).some(field => field.display) + const columnsVisibility = columns.reduce((acc, column) => { + // @ts-expect-error + const key = column.accessorKey as Field; + acc[key] = options?.list?.fields[key]?.display ? true : false; + return acc; + }, {} as Record, boolean>) + const table = useReactTable({ data, manualSorting: true, columns, getCoreRowModel: getCoreRowModel(), initialState: { - columnVisibility: { _accessorKey: false }, + columnVisibility: !hasDisplayField ? {} : columnsVisibility, }, }); @@ -67,7 +76,7 @@ export function DataTable({ columns, data, resource }: DataTableProps) { className="cursor-pointer hover:bg-indigo-50" onClick={() => { router?.push({ - pathname: `${basePath}/${resource}/${row.original._accessorKey}`, + pathname: `${basePath}/${resource}/${row.original.id}`, }); }} > diff --git a/packages/next-admin/src/components/List.tsx b/packages/next-admin/src/components/List.tsx index ff624121..145e0ee7 100644 --- a/packages/next-admin/src/components/List.tsx +++ b/packages/next-admin/src/components/List.tsx @@ -4,7 +4,7 @@ import { useRouter } from "next/compat/router"; import { ChangeEvent, useTransition } from "react"; import { ITEMS_PER_PAGE } from "../config"; -import { AdminComponentOptions, ListData, ListDataItem, ListFieldsOptions, ModelName } from "../types"; +import { ListData, ListDataItem, ListFieldsOptions, ModelName, NextAdminOptions } from "../types"; import Cell from "./Cell"; import { DataTable } from "./DataTable"; import ListHeader from "./ListHeader"; @@ -23,7 +23,7 @@ export type ListProps = { resource: ModelName; data: ListData; total: number; - options?: (Required>)['model'][ModelName] + options?: (Required)['model'][ModelName] }; function List({ resource, data, total, options }: ListProps) { @@ -103,6 +103,7 @@ function List({ resource, data, total, options }: ListProps) { resource={resource} data={data} columns={columns} + options={options} /> {data.length ? (
diff --git a/packages/next-admin/src/types.ts b/packages/next-admin/src/types.ts index 946373c6..fff2283b 100644 --- a/packages/next-admin/src/types.ts +++ b/packages/next-admin/src/types.ts @@ -30,6 +30,7 @@ export type ListFieldsOptions = { [P in Field]?: { display?: true; search?: true; + formatter?: (item: ListDataItem) => ReactNode; }; }; @@ -140,23 +141,6 @@ export type ListDataFieldValue = value: Date; }; -export type ListComponentFieldsOptions = { - [P in Field]?: { - formatter?: (item: ListDataItem) => ReactNode; - }; -}; - -export type AdminComponentOptions = { - model?: { - [P in T]?: { - toString?: (item: Model

) => string; - list?: { - fields: ListComponentFieldsOptions

; - }; - }; - }; -}; - export type AdminComponentProps = { basePath: string; schema: Schema; @@ -171,7 +155,7 @@ export type AdminComponentProps = { resources?: ModelName[]; total?: number; dmmfSchema: Prisma.DMMF.Field[]; - options?: AdminComponentOptions; + options?: NextAdminOptions; }; export type CustomUIProps = { diff --git a/packages/next-admin/src/utils/prisma.ts b/packages/next-admin/src/utils/prisma.ts index 3d74e8de..38b99ce4 100644 --- a/packages/next-admin/src/utils/prisma.ts +++ b/packages/next-admin/src/utils/prisma.ts @@ -127,17 +127,6 @@ export const getMappedDataList = async (prisma: PrismaClient, resource: ModelNam data = await findRelationInData(data, dmmfSchema?.fields); - - const isIdDisplayed = options?.model?.[resource]?.list?.fields.id?.display; - - data.forEach((item) => { - const id = item.id; - if (!isIdDisplayed) { - delete item.id; - } - item._accessorKey = id; - }); - return { data, total,