diff options
| author | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-07-28 09:19:42 +0000 |
|---|---|---|
| committer | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-07-28 09:19:42 +0000 |
| commit | 50ae0b8f02c034e60d4cbb504620dfa1575a836f (patch) | |
| tree | 24c661a0c7354e15ad56e2bded4d300bd7fd2b41 /lib/docu-list-rule/code-groups/table/code-groups-add-dialog.tsx | |
| parent | 738f956aa61264ffa761e30398eca23393929f8c (diff) | |
(박서영) 설계 document Numbering Rule 개발-최겸 업로드
Diffstat (limited to 'lib/docu-list-rule/code-groups/table/code-groups-add-dialog.tsx')
| -rw-r--r-- | lib/docu-list-rule/code-groups/table/code-groups-add-dialog.tsx | 236 |
1 files changed, 236 insertions, 0 deletions
diff --git a/lib/docu-list-rule/code-groups/table/code-groups-add-dialog.tsx b/lib/docu-list-rule/code-groups/table/code-groups-add-dialog.tsx new file mode 100644 index 00000000..660adfed --- /dev/null +++ b/lib/docu-list-rule/code-groups/table/code-groups-add-dialog.tsx @@ -0,0 +1,236 @@ +"use client" + +import * as React from "react" +import { useForm } from "react-hook-form" +import { zodResolver } from "@hookform/resolvers/zod" +import { toast } from "sonner" +import { Plus, Loader2 } from "lucide-react" + +import { Button } from "@/components/ui/button" +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog" +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form" +import { Input } from "@/components/ui/input" +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select" +import { createCodeGroup } from "../service" +import { z } from "zod" + +const createCodeGroupSchema = z.object({ + description: z.string().min(1, "Description은 필수입니다."), + codeFormat: z.string().optional().refine((val) => { + if (!val) return true; // 빈 값은 허용 + return /^[AN]*$/.test(val); + }, "Code Format은 A(영어 대문자) 또는 N(숫자)만 입력 가능합니다."), + controlType: z.string().min(1, "Control Type은 필수입니다."), +}) + +type CreateCodeGroupFormValues = z.infer<typeof createCodeGroupSchema> + +interface CodeGroupsAddDialogProps { + onSuccess?: () => void +} + +export function CodeGroupsAddDialog({ onSuccess }: CodeGroupsAddDialogProps) { + const [open, setOpen] = React.useState(false) + const [isLoading, setIsLoading] = React.useState(false) + + const form = useForm<CreateCodeGroupFormValues>({ + resolver: zodResolver(createCodeGroupSchema), + defaultValues: { + description: "", + codeFormat: "", + controlType: "", + }, + }) + + // Code Format을 기반으로 정규식 자동 생성 함수 + const generateExpression = (codeFormat: string): string => { + if (!codeFormat) return '' + + let expression = '^' + let currentChar = codeFormat[0] + let count = 1 + + for (let i = 1; i < codeFormat.length; i++) { + if (codeFormat[i] === currentChar) { + count++ + } else { + // 이전 문자에 대한 정규식 추가 + if (currentChar === 'A') { + expression += `[A-Z]{${count}}` + } else if (currentChar === 'N') { + expression += `[0-9]{${count}}` + } + currentChar = codeFormat[i] + count = 1 + } + } + + // 마지막 문자 처리 + if (currentChar === 'A') { + expression += `[A-Z]{${count}}` + } else if (currentChar === 'N') { + expression += `[0-9]{${count}}` + } + + expression += '$' + return expression + } + + const handleOpenChange = (newOpen: boolean) => { + setOpen(newOpen) + if (!newOpen) { + form.reset() + } + } + + const handleCancel = () => { + form.reset() + setOpen(false) + } + + const onSubmit = async (data: CreateCodeGroupFormValues) => { + setIsLoading(true) + try { + // Expression 자동 생성 + const expressions = generateExpression(data.codeFormat || "") + + const result = await createCodeGroup({ + description: data.description, + codeFormat: data.codeFormat, + expressions: expressions, + controlType: data.controlType, + }) + + if (result.success) { + toast.success("Code Group이 성공적으로 생성되었습니다.") + form.reset() + setOpen(false) + onSuccess?.() + } else { + toast.error(result.error || "생성 중 오류가 발생했습니다.") + } + } catch (error) { + console.error("Code Group 생성 오류:", error) + toast.error("Code Group 생성에 실패했습니다.") + } finally { + setIsLoading(false) + } + } + + return ( + <Dialog open={open} onOpenChange={handleOpenChange}> + <DialogTrigger asChild> + <Button variant="outline" size="sm"> + <Plus className="mr-2 h-4 w-4" /> + Add + </Button> + </DialogTrigger> + <DialogContent className="w-[400px] sm:w-[540px]"> + <DialogHeader> + <DialogTitle>Code Group 생성</DialogTitle> + <DialogDescription> + 새로운 Code Group을 생성합니다. + </DialogDescription> + </DialogHeader> + + <Form {...form}> + <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4"> + <FormField + control={form.control} + name="description" + render={({ field }) => ( + <FormItem> + <FormLabel>Description</FormLabel> + <FormControl> + <Input placeholder="예: PROJECT NO" {...field} /> + </FormControl> + <FormMessage /> + </FormItem> + )} + /> + <FormField + control={form.control} + name="codeFormat" + render={({ field }) => ( + <FormItem> + <FormLabel>Code Format</FormLabel> + <FormControl> + <Input + placeholder="예: AANNN (A:영어대문자, N:숫자)" + {...field} + onBlur={() => form.trigger('codeFormat')} + /> + </FormControl> + <FormMessage /> + </FormItem> + )} + /> + <FormField + control={form.control} + name="controlType" + render={({ field }) => ( + <FormItem> + <FormLabel>Control Type</FormLabel> + <Select onValueChange={field.onChange} defaultValue={field.value}> + <FormControl> + <SelectTrigger> + <SelectValue placeholder="Control Type을 선택하세요" /> + </SelectTrigger> + </FormControl> + <SelectContent> + <SelectItem value="textbox">Textbox</SelectItem> + <SelectItem value="combobox">Combobox</SelectItem> + </SelectContent> + </Select> + <FormMessage /> + </FormItem> + )} + /> + + + </form> + </Form> + + <DialogFooter> + <Button + type="button" + variant="outline" + onClick={handleCancel} + disabled={isLoading} + > + 취소 + </Button> + <Button + type="submit" + onClick={form.handleSubmit(onSubmit)} + disabled={isLoading} + > + {isLoading && <Loader2 className="mr-2 h-4 w-4 animate-spin" />} + {isLoading ? "생성 중..." : "생성"} + </Button> + </DialogFooter> + </DialogContent> + </Dialog> + ) +}
\ No newline at end of file |
