From d03a3e0f4b2fb114f8a0862718c64fad98c01fb9 Mon Sep 17 00:00:00 2001
From: foyarash <11079152+foyarash@users.noreply.github.com>
Date: Mon, 20 Nov 2023 15:15:02 +0100
Subject: [PATCH 1/7] chore: :art: apply prettier to all files
---
.env => apps/example/.env | 0
.env.example => apps/example/.env.example | 0
apps/example/e2e/table.spec.ts | 8 +-
apps/example/pages/admin/[[...nextadmin]].tsx | 56 +-
apps/example/playwright.config.ts | 8 +-
apps/example/prisma/schema.prisma | 39 +-
packages/next-admin/src/components/Cell.tsx | 19 +-
.../next-admin/src/components/DataTable.tsx | 40 +-
packages/next-admin/src/components/List.tsx | 95 ++--
.../next-admin/src/components/ListHeader.tsx | 2 +-
packages/next-admin/src/components/Menu.tsx | 340 +++++------
.../next-admin/src/components/NextAdmin.tsx | 2 +-
.../src/components/inputs/SelectWidget.tsx | 4 +-
.../next-admin/src/context/ConfigContext.tsx | 35 +-
packages/next-admin/src/index.tsx | 2 +-
packages/next-admin/src/router.tsx | 531 +++++++++---------
.../next-admin/src/tests/prismaUtils.test.ts | 15 +-
.../next-admin/src/tests/serverUtils.test.ts | 22 +-
packages/next-admin/src/tests/singleton.ts | 37 +-
packages/next-admin/src/types.ts | 89 ++-
packages/next-admin/src/utils/prisma.ts | 66 ++-
packages/next-admin/src/utils/server.ts | 84 ++-
packages/next-admin/src/utils/tools.ts | 4 +-
packages/next-admin/src/utils/validator.ts | 8 +-
yarn.lock | 7 +-
25 files changed, 838 insertions(+), 675 deletions(-)
rename .env => apps/example/.env (100%)
rename .env.example => apps/example/.env.example (100%)
diff --git a/.env b/apps/example/.env
similarity index 100%
rename from .env
rename to apps/example/.env
diff --git a/.env.example b/apps/example/.env.example
similarity index 100%
rename from .env.example
rename to apps/example/.env.example
diff --git a/apps/example/e2e/table.spec.ts b/apps/example/e2e/table.spec.ts
index cc41028b..ec4fecb1 100644
--- a/apps/example/e2e/table.spec.ts
+++ b/apps/example/e2e/table.spec.ts
@@ -1,7 +1,7 @@
-import { test } from '@playwright/test';
-import { pagination, search, sort } from './utils';
+import { test } from "@playwright/test";
+import { pagination, search, sort } from "./utils";
-test.describe.serial('table test', () => {
+test.describe.serial("table test", () => {
test(`search (on user)`, async ({ page }) => {
await search(page);
});
@@ -13,4 +13,4 @@ test.describe.serial('table test', () => {
test(`pagination (on user)`, async ({ page }) => {
await pagination(page);
});
-});
\ No newline at end of file
+});
diff --git a/apps/example/pages/admin/[[...nextadmin]].tsx b/apps/example/pages/admin/[[...nextadmin]].tsx
index 6bfdae99..4b649227 100644
--- a/apps/example/pages/admin/[[...nextadmin]].tsx
+++ b/apps/example/pages/admin/[[...nextadmin]].tsx
@@ -25,9 +25,11 @@ const options: NextAdminOptions = {
},
birthDate: {
formatter: (date) => {
- return new Date(date as unknown as string)?.toLocaleString().split(" ")[0];
- }
- }
+ return new Date(date as unknown as string)
+ ?.toLocaleString()
+ .split(" ")[0];
+ },
+ },
},
},
edit: {
@@ -37,22 +39,23 @@ const options: NextAdminOptions = {
validate: (email) => email.includes("@") || "Invalid email",
},
birthDate: {
- format: "date",
- handler: {
- //This getter is used to format the date in the form and match with the format of the input
- get: (value) => {
- return value?.toISOString().split("T")[0];
- },
- }
- }
+ format: "date-time",
+ },
},
},
},
Post: {
toString: (post) => `${post.title}`,
list: {
- display: ['id', 'title', 'content', 'published', 'author', 'categories'],
- search: ['title', 'content'],
+ display: [
+ "id",
+ "title",
+ "content",
+ "published",
+ "author",
+ "categories",
+ ],
+ search: ["title", "content"],
fields: {
author: {
formatter: (author) => {
@@ -62,30 +65,31 @@ const options: NextAdminOptions = {
},
},
edit: {
- display: ['id', 'title', 'content', 'published', 'authorId', 'categories'],
- }
+ display: [
+ "id",
+ "title",
+ "content",
+ "published",
+ "authorId",
+ "categories",
+ ],
+ },
},
Category: {
toString: (category) => `${category.name}`,
list: {
- display: ['name', 'posts'],
- search: ['name'],
+ display: ["name", "posts"],
+ search: ["name"],
},
edit: {
- display: ['name', 'posts'],
- }
+ display: ["name", "posts"],
+ },
},
},
};
export default function Admin(props: AdminComponentProps) {
- return (
-
- );
+ return ;
}
export const getServerSideProps: GetServerSideProps = async ({ req, res }) => {
diff --git a/apps/example/playwright.config.ts b/apps/example/playwright.config.ts
index 76944939..f7109804 100644
--- a/apps/example/playwright.config.ts
+++ b/apps/example/playwright.config.ts
@@ -1,6 +1,6 @@
-import { defineConfig } from '@playwright/test';
+import { defineConfig } from "@playwright/test";
export default defineConfig({
- testDir: 'e2e',
- workers: 1,
-});
\ No newline at end of file
+ testDir: "e2e",
+ workers: 1,
+});
diff --git a/apps/example/prisma/schema.prisma b/apps/example/prisma/schema.prisma
index 70b1f118..a6d665d4 100644
--- a/apps/example/prisma/schema.prisma
+++ b/apps/example/prisma/schema.prisma
@@ -6,7 +6,7 @@ generator client {
}
generator jsonSchema {
- provider = "prisma-json-schema-generator"
+ provider = "prisma-json-schema-generator"
includeRequiredFields = "true"
}
@@ -20,27 +20,28 @@ enum Role {
USER
ADMIN
}
+
model User {
- id Int @id @default(autoincrement())
- email String @unique
+ id Int @id @default(autoincrement())
+ email String @unique
name String?
- posts Post[] @relation("author") // One-to-many relation
- profile Profile? @relation("profile") // One-to-one relation
+ posts Post[] @relation("author") // One-to-many relation
+ profile Profile? @relation("profile") // One-to-one relation
birthDate DateTime?
- createdAt DateTime @default(now())
- updatedAt DateTime @default(now()) @updatedAt
- role Role @default(USER)
+ createdAt DateTime @default(now())
+ updatedAt DateTime @default(now()) @updatedAt
+ role Role @default(USER)
}
model Post {
- id Int @id @default(autoincrement())
- title String
- content String?
- published Boolean @default(false)
- author User @relation("author", fields: [authorId], references: [id])
- authorId Int
- categories Category[] @relation("category") // implicit Many-to-many relation
- comments post_comment[] @relation("comments") // One-to-many relation
+ id Int @id @default(autoincrement())
+ title String
+ content String?
+ published Boolean @default(false)
+ author User @relation("author", fields: [authorId], references: [id])
+ authorId Int
+ categories Category[] @relation("category") // implicit Many-to-many relation
+ comments post_comment[] @relation("comments") // One-to-many relation
}
model Profile {
@@ -53,15 +54,15 @@ model Profile {
}
model Category {
- id Int @id @default(autoincrement())
+ id Int @id @default(autoincrement())
name String
- posts Post[] @relation("category") // implicit Many-to-many relation
+ posts Post[] @relation("category") // implicit Many-to-many relation
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
}
model post_comment {
- id String @id @default(uuid())
+ id String @id @default(uuid())
content String
post Post @relation("comments", fields: [postId], references: [id])
postId Int
diff --git a/packages/next-admin/src/components/Cell.tsx b/packages/next-admin/src/components/Cell.tsx
index 97fef2f0..44d78461 100644
--- a/packages/next-admin/src/components/Cell.tsx
+++ b/packages/next-admin/src/components/Cell.tsx
@@ -6,16 +6,18 @@ import clsx from "clsx";
import { useConfig } from "../context/ConfigContext";
type Props = {
- cell: ListDataFieldValue | ReactNode
- formatter: (cell: any) => ReactNode
+ cell: ListDataFieldValue | ReactNode;
+ formatter: (cell: any) => ReactNode;
};
export default function Cell({ cell, formatter }: Props) {
- const { basePath } = useConfig()
+ const { basePath } = useConfig();
- const isReactNode = (cell: ListDataFieldValue | ReactNode): cell is ReactNode => {
- return React.isValidElement(cell)
- }
+ const isReactNode = (
+ cell: ListDataFieldValue | ReactNode
+ ): cell is ReactNode => {
+ return React.isValidElement(cell);
+ };
if (cell && cell !== null) {
if (React.isValidElement(cell)) {
return cell;
@@ -60,8 +62,9 @@ export default function Cell({ cell, formatter }: Props) {
{formatter(cell.toString())}
diff --git a/packages/next-admin/src/components/DataTable.tsx b/packages/next-admin/src/components/DataTable.tsx
index 28b52647..46ec1c39 100644
--- a/packages/next-admin/src/components/DataTable.tsx
+++ b/packages/next-admin/src/components/DataTable.tsx
@@ -15,26 +15,40 @@ import {
TableRow,
} from "./radix/Table";
import { useRouter } from "next/compat/router";
-import { ListData, ListDataItem, ModelName, Field, NextAdminOptions } from "../types";
+import {
+ ListData,
+ ListDataItem,
+ ModelName,
+ Field,
+ NextAdminOptions,
+} from "../types";
import { useConfig } from "../context/ConfigContext";
interface DataTableProps {
columns: ColumnDef
>[];
data: ListData;
resource: ModelName;
- options: (Required)['model'][ModelName]
+ options: Required["model"][ModelName];
}
-export function DataTable({ columns, data, resource, options }: DataTableProps) {
+export function DataTable({
+ columns,
+ data,
+ resource,
+ options,
+}: DataTableProps) {
const router = useRouter();
- const { basePath } = useConfig()
+ const { basePath } = useConfig();
const hasDisplayField = options?.list?.display?.length ? true : false;
- const columnsVisibility = columns.reduce((acc, column) => {
- // @ts-expect-error
- const key = column.accessorKey as Field;
- acc[key] = options?.list?.display?.includes(key) ? true : false;
- return acc;
- }, {} as Record, boolean>)
+ const columnsVisibility = columns.reduce(
+ (acc, column) => {
+ // @ts-expect-error
+ const key = column.accessorKey as Field;
+ acc[key] = options?.list?.display?.includes(key) ? true : false;
+ return acc;
+ },
+ {} as Record, boolean>
+ );
const table = useReactTable({
data,
@@ -58,9 +72,9 @@ export function DataTable({ columns, data, resource, options }: DataTableProps)
{header.isPlaceholder
? null
: flexRender(
- header.column.columnDef.header,
- header.getContext()
- )}
+ header.column.columnDef.header,
+ header.getContext()
+ )}
);
})}
diff --git a/packages/next-admin/src/components/List.tsx b/packages/next-admin/src/components/List.tsx
index 4d36214c..9e21b285 100644
--- a/packages/next-admin/src/components/List.tsx
+++ b/packages/next-admin/src/components/List.tsx
@@ -3,7 +3,13 @@ import debounce from "lodash/debounce";
import { useRouter } from "next/compat/router";
import { ChangeEvent, useTransition } from "react";
import { ITEMS_PER_PAGE } from "../config";
-import { ListData, ListDataItem, ListFieldsOptions, ModelName, NextAdminOptions } from "../types";
+import {
+ ListData,
+ ListDataItem,
+ ListFieldsOptions,
+ ModelName,
+ NextAdminOptions,
+} from "../types";
import Cell from "./Cell";
import { DataTable } from "./DataTable";
import ListHeader from "./ListHeader";
@@ -22,7 +28,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) {
@@ -47,47 +53,50 @@ function List({ resource, data, total, options }: ListProps) {
const columns: ColumnDef>[] =
data && data?.length > 0
? Object.keys(data[0]).map((property) => {
- return {
- accessorKey: property,
- header: () => {
- return (
- {
- router?.push({
- pathname: location.pathname,
- query: {
- ...router?.query,
- sortColumn: property,
- sortDirection:
- router?.query.sortDirection === "asc"
- ? "desc"
- : "asc",
- },
- });
- }}
- />
- );
- },
- cell: ({ row }) => {
- const modelData = row.original;
- const cellData = modelData[property as keyof ListFieldsOptions];
- const dataFormatter = options?.list?.fields?.[property as keyof ListFieldsOptions]?.formatter || ((cell: any) => {
- if (typeof cell === "object") {
- return cell.id
- } else {
- return cell
- }
- })
+ return {
+ accessorKey: property,
+ header: () => {
+ return (
+ {
+ router?.push({
+ pathname: location.pathname,
+ query: {
+ ...router?.query,
+ sortColumn: property,
+ sortDirection:
+ router?.query.sortDirection === "asc"
+ ? "desc"
+ : "asc",
+ },
+ });
+ }}
+ />
+ );
+ },
+ cell: ({ row }) => {
+ const modelData = row.original;
+ const cellData =
+ modelData[property as keyof ListFieldsOptions];
+ const dataFormatter =
+ options?.list?.fields?.[
+ property as keyof ListFieldsOptions
+ ]?.formatter ||
+ ((cell: any) => {
+ if (typeof cell === "object") {
+ return cell.id;
+ } else {
+ return cell;
+ }
+ });
- return (
- |
- );
- },
- };
- })
+ return | ;
+ },
+ };
+ })
: [];
return (
@@ -113,7 +122,7 @@ function List({ resource, data, total, options }: ListProps) {
/>
{data.length ? (
-
+
diff --git a/packages/next-admin/src/components/Menu.tsx b/packages/next-admin/src/components/Menu.tsx
index 2b05fb3e..8ff818f6 100644
--- a/packages/next-admin/src/components/Menu.tsx
+++ b/packages/next-admin/src/components/Menu.tsx
@@ -8,183 +8,189 @@ import { ModelName } from "../types";
import { useConfig } from "../context/ConfigContext";
export type MenuProps = {
- resource: ModelName;
- resources?: ModelName[];
+ resource: ModelName;
+ resources?: ModelName[];
};
-export default function Menu({ resources, resource: currentResource }: MenuProps) {
- const [sidebarOpen, setSidebarOpen] = useState(false);
- const { basePath } = useConfig()
- const navigation: Array<{
- name: string;
- href: string;
- current: boolean;
- icon?: React.ElementType;
- }> =
- resources?.map((resource) => ({
- name: resource,
- href: `${basePath}/${resource}`,
- current: resource === currentResource,
- })) || [];
+export default function Menu({
+ resources,
+ resource: currentResource,
+}: MenuProps) {
+ const [sidebarOpen, setSidebarOpen] = useState(false);
+ const { basePath } = useConfig();
+ const navigation: Array<{
+ name: string;
+ href: string;
+ current: boolean;
+ icon?: React.ElementType;
+ }> =
+ resources?.map((resource) => ({
+ name: resource,
+ href: `${basePath}/${resource}`,
+ current: resource === currentResource,
+ })) || [];
- return <>
-
-