From e616169c412dd822cd95dfc633fe64b13e8b878c Mon Sep 17 00:00:00 2001 From: mlogclub Date: Thu, 23 Apr 2026 14:05:13 +0800 Subject: [PATCH] feat(role): add CreateRoleDrawer component and integrate role creation functionality --- Makefile | 6 +- .../(dashboard)/roles/_components/create.tsx | 208 ++++++++++++++++++ dashboard/app/(dashboard)/roles/page.tsx | 49 +++++ dashboard/lib/api/admin.ts | 14 ++ 4 files changed, 274 insertions(+), 3 deletions(-) create mode 100644 dashboard/app/(dashboard)/roles/_components/create.tsx diff --git a/Makefile b/Makefile index 6202d11..856a903 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ .PHONY: help install run run-server run-dashboard run-widget build build-all build-assets build-dashboard build-widget \ - package-current package-platform build-server-linux-amd64 clean-dist clean-temp generator enums migration testdata + package-current package-platform build-linux-amd64 clean-dist clean-temp generator enums migration testdata DIST_DIR ?= dist TMP_DIR := $(DIST_DIR)/.tmp @@ -28,7 +28,7 @@ help: @echo " make build-widget Build widget sdk and app" @echo " make package-current Package current platform" @echo " make package-platform Package specified PLATFORM" - @echo " make build-server-linux-amd64 Build linux amd64 server binary" + @echo " make build-linux-amd64 Build and package linux amd64 release" @echo " make clean-dist Remove dist directory" @echo " make clean-temp Remove temporary packaging files" @echo " make generator Run code generator" @@ -103,7 +103,7 @@ package-current: build-linux-amd64: clean-dist build-assets @$(MAKE) package-platform PLATFORM=linux-amd64 @$(MAKE) clean-temp - @echo "[build-server-linux-amd64] done" + @echo "[build-linux-amd64] done" package-platform: @platform="$(PLATFORM)"; \ diff --git a/dashboard/app/(dashboard)/roles/_components/create.tsx b/dashboard/app/(dashboard)/roles/_components/create.tsx new file mode 100644 index 0000000..4f9a333 --- /dev/null +++ b/dashboard/app/(dashboard)/roles/_components/create.tsx @@ -0,0 +1,208 @@ +"use client" + +import { Resolver, useForm } from "react-hook-form" +import { zodResolver } from "@hookform/resolvers/zod" +import { z } from "zod/v4" + +import { type CreateAdminRolePayload } from "@/lib/api/admin" +import { Button } from "@/components/ui/button" +import { + Drawer, + DrawerContent, + DrawerDescription, + DrawerFooter, + DrawerHeader, + DrawerTitle, +} from "@/components/ui/drawer" +import { + Field, + FieldContent, + FieldError, + FieldLabel, +} from "@/components/ui/field" +import { Input } from "@/components/ui/input" +import { Textarea } from "@/components/ui/textarea" + +type CreateRoleDrawerProps = { + open: boolean + saving: boolean + defaultSortNo: number + onOpenChange: (open: boolean) => void + onSubmit: (payload: CreateAdminRolePayload) => Promise +} + +const createFormSchema = z.object({ + name: z.string().trim().min(1, "角色名称不能为空"), + code: z + .string() + .trim() + .min(1, "角色编码不能为空") + .regex(/^[A-Za-z][A-Za-z0-9:_-]*$/, "角色编码需以字母开头,仅支持字母、数字、冒号、下划线和短横线"), + sortNo: z + .string() + .trim() + .min(1, "排序不能为空") + .regex(/^\d+$/, "排序值必须是大于等于 0 的整数"), + remark: z.string().trim(), +}) + +type CreateForm = z.infer + +const createFormResolver = zodResolver(createFormSchema as never) as Resolver< + z.input, + undefined, + z.output +> + +function buildEmptyForm(defaultSortNo: number): CreateForm { + return { + name: "", + code: "", + sortNo: String(defaultSortNo), + remark: "", + } +} + +function buildPayload(form: CreateForm): CreateAdminRolePayload { + return { + name: form.name.trim(), + code: form.code.trim(), + sortNo: Number(form.sortNo), + remark: form.remark.trim(), + } +} + +export function CreateRoleDrawer({ + open, + saving, + defaultSortNo, + onOpenChange, + onSubmit, +}: CreateRoleDrawerProps) { + return ( + + {open ? ( + + ) : null} + + ) +} + +type CreateRoleDrawerBodyProps = { + saving: boolean + defaultSortNo: number + onOpenChange: (open: boolean) => void + onSubmit: (payload: CreateAdminRolePayload) => Promise +} + +function CreateRoleDrawerBody({ + saving, + defaultSortNo, + onOpenChange, + onSubmit, +}: CreateRoleDrawerBodyProps) { + const form = useForm< + z.input, + undefined, + z.output + >({ + resolver: createFormResolver, + defaultValues: buildEmptyForm(defaultSortNo), + }) + const { + handleSubmit, + register, + reset, + formState: { errors }, + } = form + + async function onFormSubmit(values: CreateForm) { + await onSubmit(buildPayload(values)) + reset(buildEmptyForm(defaultSortNo)) + } + + return ( + + + 添加角色 + 创建后可在列表中分配权限和调整排序。 + +
+
+ + 角色名称 + + + + + + + 角色编码 + + + + + + + 排序 + + + + + + + 备注 + +