summaryrefslogtreecommitdiff
path: root/lib/docu-list-rule
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-09-26 09:57:24 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-09-26 09:57:24 +0000
commit8b23b471638a155fd1bfa3a8c853b26d9315b272 (patch)
tree47353e9dd342011cb2f1dcd24b09661707a8421b /lib/docu-list-rule
parentd62368d2b68d73da895977e60a18f9b1286b0545 (diff)
(대표님) 권한관리, 문서업로드, rfq첨부, SWP문서룰 등
(최겸) 입찰
Diffstat (limited to 'lib/docu-list-rule')
-rw-r--r--lib/docu-list-rule/number-type-configs/service.ts7
-rw-r--r--lib/docu-list-rule/number-type-configs/table/number-type-configs-edit-dialog.tsx277
-rw-r--r--lib/docu-list-rule/number-type-configs/table/number-type-configs-toolbar-actions.tsx251
-rw-r--r--lib/docu-list-rule/types.ts1
4 files changed, 332 insertions, 204 deletions
diff --git a/lib/docu-list-rule/number-type-configs/service.ts b/lib/docu-list-rule/number-type-configs/service.ts
index c29af464..b644c43a 100644
--- a/lib/docu-list-rule/number-type-configs/service.ts
+++ b/lib/docu-list-rule/number-type-configs/service.ts
@@ -166,12 +166,12 @@ export async function getNumberTypeConfigs(input: GetNumberTypeConfigsSchema) {
}
}
-// Number Type Config 생성
export async function createNumberTypeConfig(input: {
documentNumberTypeId: number
codeGroupId: number | null
sdq: number
description?: string
+ delimiter?: string
remark?: string
}) {
try {
@@ -198,6 +198,7 @@ export async function createNumberTypeConfig(input: {
codeGroupId: input.codeGroupId,
sdq: input.sdq,
description: input.description,
+ delimiter: input.delimiter,
remark: input.remark,
})
.returning({ id: documentNumberTypeConfigs.id })
@@ -218,12 +219,12 @@ export async function createNumberTypeConfig(input: {
}
}
-// Number Type Config 수정
export async function updateNumberTypeConfig(input: {
id: number
codeGroupId: number | null
sdq: number
description?: string
+ delimiter?: string
remark?: string
}) {
try {
@@ -263,6 +264,7 @@ export async function updateNumberTypeConfig(input: {
codeGroupId: input.codeGroupId,
sdq: input.sdq,
description: input.description,
+ delimiter: input.delimiter,
remark: input.remark,
updatedAt: new Date(),
})
@@ -284,7 +286,6 @@ export async function updateNumberTypeConfig(input: {
}
}
}
-
// Number Type Config 순서 변경 (간단한 방식)
export async function updateNumberTypeConfigOrder(input: {
id: number
diff --git a/lib/docu-list-rule/number-type-configs/table/number-type-configs-edit-dialog.tsx b/lib/docu-list-rule/number-type-configs/table/number-type-configs-edit-dialog.tsx
index cd2d6fc8..ad3478ff 100644
--- a/lib/docu-list-rule/number-type-configs/table/number-type-configs-edit-dialog.tsx
+++ b/lib/docu-list-rule/number-type-configs/table/number-type-configs-edit-dialog.tsx
@@ -2,6 +2,9 @@
import * as React from "react"
import { Loader2 } from "lucide-react"
+import { useForm } from "react-hook-form"
+import { zodResolver } from "@hookform/resolvers/zod"
+import * as z from "zod"
import { toast } from "sonner"
import { Button } from "@/components/ui/button"
@@ -14,6 +17,14 @@ import {
DialogTitle,
} from "@/components/ui/dialog"
import {
+ Form,
+ FormControl,
+ FormField,
+ FormItem,
+ FormLabel,
+ FormMessage,
+} from "@/components/ui/form"
+import {
Select,
SelectContent,
SelectItem,
@@ -21,18 +32,30 @@ import {
SelectValue,
} from "@/components/ui/select"
import { Input } from "@/components/ui/input"
-import { Label } from "@/components/ui/label"
import { Textarea } from "@/components/ui/textarea"
import { updateNumberTypeConfig, getActiveCodeGroups } from "@/lib/docu-list-rule/number-type-configs/service"
import { NumberTypeConfig } from "@/lib/docu-list-rule/types"
+const formSchema = z.object({
+ codeGroupId: z.string().min(1, "Code Group을 선택해주세요."),
+ sdq: z.string().min(1, "순서를 입력해주세요.").refine(
+ (val) => !isNaN(Number(val)) && Number(val) > 0,
+ { message: "순서는 1 이상의 숫자여야 합니다." }
+ ),
+ description: z.string().optional(),
+ delimiter: z.string().max(10).optional(),
+ remark: z.string().optional(),
+})
+
+type FormData = z.infer<typeof formSchema>
+
interface NumberTypeConfigsEditDialogProps {
open: boolean
onOpenChange: (open: boolean) => void
data: NumberTypeConfig | null
onSuccess?: () => void
- existingConfigs?: NumberTypeConfig[] // 기존 configs 목록 추가
+ existingConfigs?: NumberTypeConfig[]
selectedProjectId?: number | null
}
@@ -41,29 +64,35 @@ export function NumberTypeConfigsEditDialog({
onOpenChange,
data,
onSuccess,
- existingConfigs = [], // 기본값 추가
+ existingConfigs = [],
selectedProjectId,
}: NumberTypeConfigsEditDialogProps) {
const [isLoading, setIsLoading] = React.useState(false)
const [codeGroups, setCodeGroups] = React.useState<{ id: number; description: string }[]>([])
- const [formData, setFormData] = React.useState({
- codeGroupId: "",
- sdq: "",
- description: "",
- remark: ""
+
+ const form = useForm<FormData>({
+ resolver: zodResolver(formSchema),
+ defaultValues: {
+ codeGroupId: "",
+ sdq: "",
+ description: "",
+ delimiter: "",
+ remark: "",
+ },
})
// 데이터가 변경될 때 폼 초기화
React.useEffect(() => {
if (data) {
- setFormData({
- codeGroupId: data.codeGroupId?.toString() || "", // null 체크 추가
+ form.reset({
+ codeGroupId: data.codeGroupId?.toString() || "",
sdq: data.sdq.toString(),
description: data.description || "",
+ delimiter: data.delimiter || "",
remark: data.remark || ""
})
}
- }, [data])
+ }, [data, form])
// Code Groups 로드
React.useEffect(() => {
@@ -79,21 +108,23 @@ export function NumberTypeConfigsEditDialog({
})()
}, [selectedProjectId])
- const handleSubmit = async (e: React.FormEvent) => {
- e.preventDefault()
- if (!data || !formData.codeGroupId || !formData.sdq) {
- toast.error("필수 필드를 모두 입력해주세요.")
+ const onSubmit = async (values: FormData) => {
+ if (!data) {
+ toast.error("데이터를 찾을 수 없습니다.")
return
}
- const newSdq = parseInt(formData.sdq)
+ const newSdq = parseInt(values.sdq)
// 순서 중복 검증 (현재 수정 중인 항목 제외)
const existingSdq = existingConfigs.find(config =>
config.sdq === newSdq && config.id !== data.id
)
if (existingSdq) {
- toast.error(`순서 ${newSdq}번은 이미 사용 중입니다. 다른 순서를 입력해주세요.`)
+ form.setError("sdq", {
+ type: "manual",
+ message: `순서 ${newSdq}번은 이미 사용 중입니다. 다른 순서를 입력해주세요.`
+ })
return
}
@@ -101,11 +132,11 @@ export function NumberTypeConfigsEditDialog({
try {
const result = await updateNumberTypeConfig({
id: data.id,
- codeGroupId: parseInt(formData.codeGroupId),
-
+ codeGroupId: parseInt(values.codeGroupId),
sdq: newSdq,
- description: formData.description || undefined,
- remark: formData.remark || undefined,
+ description: values.description || undefined,
+ delimiter: values.delimiter || undefined,
+ remark: values.remark || undefined,
})
if (result.success) {
@@ -135,91 +166,127 @@ export function NumberTypeConfigsEditDialog({
<span className="text-red-500 mt-1 block text-sm">* 표시된 항목은 필수 입력사항입니다.</span>
</DialogDescription>
</DialogHeader>
- <form onSubmit={handleSubmit} className="space-y-4">
- <div className="grid gap-4 py-2">
- <div className="grid grid-cols-4 items-center gap-4">
- <Label htmlFor="codeGroup" className="text-right">
- Code Group <span className="text-red-500">*</span>
- </Label>
- <div className="col-span-3">
- <Select
- value={formData.codeGroupId}
- onValueChange={(value) => setFormData(prev => ({ ...prev, codeGroupId: value }))}
- >
- <SelectTrigger>
- <SelectValue placeholder="Code Group 선택" />
- </SelectTrigger>
- <SelectContent>
- {codeGroups.map((codeGroup) => (
- <SelectItem key={codeGroup.id} value={codeGroup.id.toString()}>
- {codeGroup.description}
- </SelectItem>
- ))}
- </SelectContent>
- </Select>
- </div>
- </div>
- <div className="grid grid-cols-4 items-center gap-4">
- <Label htmlFor="sdq" className="text-right">
- 순서 <span className="text-red-500">*</span>
- </Label>
- <div className="col-span-3">
- <Input
- id="sdq"
- type="number"
- value={formData.sdq}
- onChange={(e) => setFormData(prev => ({ ...prev, sdq: e.target.value }))}
- min="1"
- />
- </div>
- </div>
- <div className="grid grid-cols-4 items-center gap-4">
- <Label htmlFor="description" className="text-right">
- Description
- </Label>
- <div className="col-span-3">
- <Input
- id="description"
- value={formData.description}
- onChange={(e) => setFormData(prev => ({ ...prev, description: e.target.value }))}
- placeholder="예: PROJECT NO"
- />
- </div>
- </div>
- <div className="grid grid-cols-4 items-center gap-4">
- <Label htmlFor="remark" className="text-right">
- Remark
- </Label>
- <div className="col-span-3">
- <Textarea
- id="remark"
- value={formData.remark}
- onChange={(e) => setFormData(prev => ({ ...prev, remark: e.target.value }))}
- placeholder="비고 사항"
- rows={3}
- />
- </div>
+ <Form {...form}>
+ <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
+ <div className="grid gap-4 py-2">
+ <FormField
+ control={form.control}
+ name="codeGroupId"
+ render={({ field }) => (
+ <FormItem className="grid grid-cols-4 items-center gap-4 space-y-0">
+ <FormLabel className="text-right">
+ Code Group <span className="text-red-500">*</span>
+ </FormLabel>
+ <div className="col-span-3">
+ <FormControl>
+ <Select
+ value={field.value}
+ onValueChange={field.onChange}
+ >
+ <SelectTrigger>
+ <SelectValue placeholder="Code Group 선택" />
+ </SelectTrigger>
+ <SelectContent>
+ {codeGroups.map((codeGroup) => (
+ <SelectItem key={codeGroup.id} value={codeGroup.id.toString()}>
+ {codeGroup.description}
+ </SelectItem>
+ ))}
+ </SelectContent>
+ </Select>
+ </FormControl>
+ <FormMessage className="col-start-2 col-span-3" />
+ </div>
+ </FormItem>
+ )}
+ />
+
+ <FormField
+ control={form.control}
+ name="sdq"
+ render={({ field }) => (
+ <FormItem className="grid grid-cols-4 items-center gap-4 space-y-0">
+ <FormLabel className="text-right">
+ 순서 <span className="text-red-500">*</span>
+ </FormLabel>
+ <div className="col-span-3">
+ <FormControl>
+ <Input {...field} type="number" min="1" />
+ </FormControl>
+ <FormMessage className="col-start-2 col-span-3" />
+ </div>
+ </FormItem>
+ )}
+ />
+
+ <FormField
+ control={form.control}
+ name="description"
+ render={({ field }) => (
+ <FormItem className="grid grid-cols-4 items-center gap-4 space-y-0">
+ <FormLabel className="text-right">Description</FormLabel>
+ <div className="col-span-3">
+ <FormControl>
+ <Input {...field} placeholder="예: PROJECT NO" />
+ </FormControl>
+ <FormMessage className="col-start-2 col-span-3" />
+ </div>
+ </FormItem>
+ )}
+ />
+
+ <FormField
+ control={form.control}
+ name="delimiter"
+ render={({ field }) => (
+ <FormItem className="grid grid-cols-4 items-center gap-4 space-y-0">
+ <FormLabel className="text-right">Delimiter</FormLabel>
+ <div className="col-span-3">
+ <FormControl>
+ <Input {...field} placeholder="예: -, _, /" maxLength={10} />
+ </FormControl>
+ <FormMessage className="col-start-2 col-span-3" />
+ </div>
+ </FormItem>
+ )}
+ />
+
+ <FormField
+ control={form.control}
+ name="remark"
+ render={({ field }) => (
+ <FormItem className="grid grid-cols-4 items-center gap-4 space-y-0">
+ <FormLabel className="text-right">Remark</FormLabel>
+ <div className="col-span-3">
+ <FormControl>
+ <Textarea {...field} placeholder="비고 사항" rows={3} />
+ </FormControl>
+ <FormMessage className="col-start-2 col-span-3" />
+ </div>
+ </FormItem>
+ )}
+ />
</div>
- </div>
- <DialogFooter>
- <Button
- type="button"
- variant="outline"
- onClick={() => onOpenChange(false)}
- disabled={isLoading}
- >
- 취소
- </Button>
- <Button
- type="submit"
- disabled={isLoading}
- >
- {isLoading && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
- {isLoading ? "수정 중..." : "수정"}
- </Button>
- </DialogFooter>
- </form>
+ <DialogFooter>
+ <Button
+ type="button"
+ variant="outline"
+ onClick={() => onOpenChange(false)}
+ disabled={isLoading}
+ >
+ 취소
+ </Button>
+ <Button
+ type="submit"
+ disabled={isLoading}
+ >
+ {isLoading && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
+ {isLoading ? "수정 중..." : "수정"}
+ </Button>
+ </DialogFooter>
+ </form>
+ </Form>
</DialogContent>
</Dialog>
)
-} \ No newline at end of file
+} \ No newline at end of file
diff --git a/lib/docu-list-rule/number-type-configs/table/number-type-configs-toolbar-actions.tsx b/lib/docu-list-rule/number-type-configs/table/number-type-configs-toolbar-actions.tsx
index 572d05cd..243dff73 100644
--- a/lib/docu-list-rule/number-type-configs/table/number-type-configs-toolbar-actions.tsx
+++ b/lib/docu-list-rule/number-type-configs/table/number-type-configs-toolbar-actions.tsx
@@ -2,6 +2,9 @@
import * as React from "react"
import { Plus, Loader2 } from "lucide-react"
+import { useForm } from "react-hook-form"
+import { zodResolver } from "@hookform/resolvers/zod"
+import * as z from "zod"
import { Button } from "@/components/ui/button"
import {
Dialog,
@@ -13,6 +16,14 @@ import {
DialogTrigger,
} from "@/components/ui/dialog"
import {
+ Form,
+ FormControl,
+ FormField,
+ FormItem,
+ FormLabel,
+ FormMessage,
+} from "@/components/ui/form"
+import {
Select,
SelectContent,
SelectItem,
@@ -20,7 +31,6 @@ import {
SelectValue,
} from "@/components/ui/select"
import { Input } from "@/components/ui/input"
-import { Label } from "@/components/ui/label"
import { Textarea } from "@/components/ui/textarea"
import { toast } from "sonner"
@@ -28,6 +38,15 @@ import { createNumberTypeConfig, getActiveCodeGroups } from "@/lib/docu-list-rul
import { DeleteNumberTypeConfigsDialog } from "@/lib/docu-list-rule/number-type-configs/table/delete-number-type-configs-dialog"
import { NumberTypeConfig } from "@/lib/docu-list-rule/types"
+const formSchema = z.object({
+ codeGroupId: z.string().min(1, "Code Group을 선택해주세요."),
+ description: z.string().optional(),
+ delimiter: z.string().max(10).optional(),
+ remark: z.string().optional(),
+})
+
+type FormData = z.infer<typeof formSchema>
+
interface NumberTypeConfigsToolbarActionsProps {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
table: any
@@ -46,15 +65,23 @@ export function NumberTypeConfigsToolbarActions({
}: NumberTypeConfigsToolbarActionsProps) {
const [isAddDialogOpen, setIsAddDialogOpen] = React.useState(false)
const [isLoading, setIsLoading] = React.useState(false)
- const [formData, setFormData] = React.useState({ codeGroupId: "", description: "", remark: "" })
const [codeGroups, setCodeGroups] = React.useState<{ id: number; description: string }[]>([])
const [allOptions, setAllOptions] = React.useState<{ id: string; name: string }[]>([])
+ const form = useForm<FormData>({
+ resolver: zodResolver(formSchema),
+ defaultValues: {
+ codeGroupId: "",
+ description: "",
+ delimiter: "",
+ remark: "",
+ },
+ })
+
const loadCodeGroups = React.useCallback(async () => {
try {
const result = await getActiveCodeGroups(selectedProjectId || undefined)
if (result.success && result.data) {
-
// 이미 추가된 Code Group들을 제외하고 필터링
const usedCodeGroupIds = configsData.map(config => config.codeGroupId)
const availableCodeGroups = result.data.filter(codeGroup =>
@@ -86,17 +113,23 @@ export function NumberTypeConfigsToolbarActions({
combineOptions()
}, [combineOptions])
- // 다이얼로그가 열릴 때마다 Code Groups 다시 로드
+ // 다이얼로그가 열릴 때마다 Code Groups 다시 로드 및 폼 리셋
React.useEffect(() => {
if (isAddDialogOpen) {
loadCodeGroups()
+ form.reset()
}
- }, [isAddDialogOpen, loadCodeGroups, configsData])
+ }, [isAddDialogOpen, loadCodeGroups, configsData, form])
- const handleSubmit = async (e: React.FormEvent) => {
- e.preventDefault()
- if (!selectedNumberType || !formData.codeGroupId) {
- toast.error("필수 필드를 모두 입력해주세요.")
+ const getNextSdq = () => {
+ if (configsData.length === 0) return 1
+ const maxSdq = Math.max(...configsData.map(config => config.sdq))
+ return maxSdq + 1
+ }
+
+ const onSubmit = async (values: FormData) => {
+ if (!selectedNumberType) {
+ toast.error("Number Type을 선택해주세요.")
return
}
@@ -105,21 +138,21 @@ export function NumberTypeConfigsToolbarActions({
try {
// Code Group ID 추출
- const codeGroupId = parseInt(formData.codeGroupId.replace('cg_', ''))
+ const codeGroupId = parseInt(values.codeGroupId.replace('cg_', ''))
const result = await createNumberTypeConfig({
documentNumberTypeId: selectedNumberType,
codeGroupId: codeGroupId,
-
sdq: sdq,
- description: formData.description || undefined,
- remark: formData.remark || undefined,
+ description: values.description || undefined,
+ delimiter: values.delimiter || undefined,
+ remark: values.remark || undefined,
})
if (result.success) {
toast.success("Number Type Config가 성공적으로 추가되었습니다.")
setIsAddDialogOpen(false)
- setFormData({ codeGroupId: "", description: "", remark: "" })
+ form.reset()
onSuccess?.()
} else {
toast.error(result.error || "추가에 실패했습니다.")
@@ -132,12 +165,6 @@ export function NumberTypeConfigsToolbarActions({
}
}
- const getNextSdq = () => {
- if (configsData.length === 0) return 1
- const maxSdq = Math.max(...configsData.map(config => config.sdq))
- return maxSdq + 1
- }
-
return (
<div className="flex items-center gap-2">
{/** 1) 선택된 로우가 있으면 삭제 다이얼로그 */}
@@ -170,84 +197,116 @@ export function NumberTypeConfigsToolbarActions({
<span className="text-red-500 mt-1 block text-sm">* 표시된 항목은 필수 입력사항입니다.</span>
</DialogDescription>
</DialogHeader>
- <form onSubmit={handleSubmit} className="space-y-4">
- <div className="grid gap-4 py-2">
- <div className="grid grid-cols-4 items-center gap-4">
- <Label htmlFor="codeGroup" className="text-right">
- Code Group <span className="text-red-500">*</span>
- </Label>
- <div className="col-span-3">
- <Select
- value={formData.codeGroupId}
- onValueChange={(value) => setFormData(prev => ({ ...prev, codeGroupId: value }))}
- >
- <SelectTrigger>
- <SelectValue placeholder="Code Group 선택" />
- </SelectTrigger>
- <SelectContent>
- {allOptions.length > 0 ? (
- allOptions.map((option) => (
- <SelectItem key={option.id} value={option.id}>
- {option.name}
- </SelectItem>
- ))
- ) : (
- <div className="px-2 py-1.5 text-sm text-muted-foreground">
- 사용 가능한 옵션이 없습니다.
- </div>
- )}
- </SelectContent>
- </Select>
- </div>
- </div>
- <div className="grid grid-cols-4 items-center gap-4">
- <Label htmlFor="description" className="text-right">
- Description
- </Label>
- <div className="col-span-3">
- <Input
- id="description"
- value={formData.description}
- onChange={(e) => setFormData(prev => ({ ...prev, description: e.target.value }))}
- placeholder="예: PROJECT NO"
- />
- </div>
- </div>
- <div className="grid grid-cols-4 items-center gap-4">
- <Label htmlFor="remark" className="text-right">
- Remark
- </Label>
- <div className="col-span-3">
- <Textarea
- id="remark"
- value={formData.remark}
- onChange={(e) => setFormData(prev => ({ ...prev, remark: e.target.value }))}
- placeholder="비고 사항"
- rows={3}
- />
- </div>
+ <Form {...form}>
+ <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
+ <div className="grid gap-4 py-2">
+ <FormField
+ control={form.control}
+ name="codeGroupId"
+ render={({ field }) => (
+ <FormItem className="grid grid-cols-4 items-center gap-4 space-y-0">
+ <FormLabel className="text-right">
+ Code Group <span className="text-red-500">*</span>
+ </FormLabel>
+ <div className="col-span-3">
+ <FormControl>
+ <Select
+ value={field.value}
+ onValueChange={field.onChange}
+ >
+ <SelectTrigger>
+ <SelectValue placeholder="Code Group 선택" />
+ </SelectTrigger>
+ <SelectContent>
+ {allOptions.length > 0 ? (
+ allOptions.map((option) => (
+ <SelectItem key={option.id} value={option.id}>
+ {option.name}
+ </SelectItem>
+ ))
+ ) : (
+ <div className="px-2 py-1.5 text-sm text-muted-foreground">
+ 사용 가능한 옵션이 없습니다.
+ </div>
+ )}
+ </SelectContent>
+ </Select>
+ </FormControl>
+ <FormMessage className="col-start-2 col-span-3" />
+ </div>
+ </FormItem>
+ )}
+ />
+
+ <FormField
+ control={form.control}
+ name="description"
+ render={({ field }) => (
+ <FormItem className="grid grid-cols-4 items-center gap-4 space-y-0">
+ <FormLabel className="text-right">Description</FormLabel>
+ <div className="col-span-3">
+ <FormControl>
+ <Input {...field} placeholder="예: PROJECT NO" />
+ </FormControl>
+ <FormMessage className="col-start-2 col-span-3" />
+ </div>
+ </FormItem>
+ )}
+ />
+
+ <FormField
+ control={form.control}
+ name="delimiter"
+ render={({ field }) => (
+ <FormItem className="grid grid-cols-4 items-center gap-4 space-y-0">
+ <FormLabel className="text-right">Delimiter</FormLabel>
+ <div className="col-span-3">
+ <FormControl>
+ <Input {...field} placeholder="예: -, _, /" maxLength={10} />
+ </FormControl>
+ <FormMessage className="col-start-2 col-span-3" />
+ </div>
+ </FormItem>
+ )}
+ />
+
+ <FormField
+ control={form.control}
+ name="remark"
+ render={({ field }) => (
+ <FormItem className="grid grid-cols-4 items-center gap-4 space-y-0">
+ <FormLabel className="text-right">Remark</FormLabel>
+ <div className="col-span-3">
+ <FormControl>
+ <Textarea {...field} placeholder="비고 사항" rows={3} />
+ </FormControl>
+ <FormMessage className="col-start-2 col-span-3" />
+ </div>
+ </FormItem>
+ )}
+ />
</div>
- </div>
- <DialogFooter>
- <Button
- type="button"
- variant="outline"
- onClick={() => setIsAddDialogOpen(false)}
- disabled={isLoading}
- >
- 취소
- </Button>
- <Button
- type="submit"
- disabled={isLoading}
- >
- {isLoading && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
- {isLoading ? "추가 중..." : "추가"}
- </Button>
- </DialogFooter>
- </form>
+ <DialogFooter>
+ <Button
+ type="button"
+ variant="outline"
+ onClick={() => setIsAddDialogOpen(false)}
+ disabled={isLoading}
+ >
+ 취소
+ </Button>
+ <Button
+ type="submit"
+ disabled={isLoading}
+ >
+ {isLoading && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
+ {isLoading ? "추가 중..." : "추가"}
+ </Button>
+ </DialogFooter>
+ </form>
+ </Form>
</DialogContent>
</Dialog>
</div>
)
-} \ No newline at end of file
+} \ No newline at end of file
diff --git a/lib/docu-list-rule/types.ts b/lib/docu-list-rule/types.ts
index ef3f90d3..2baa72a5 100644
--- a/lib/docu-list-rule/types.ts
+++ b/lib/docu-list-rule/types.ts
@@ -6,6 +6,7 @@ export interface NumberTypeConfig {
codeGroupId: number | null
sdq: number
description: string | null
+ delimiter:string | null
remark: string | null
isActive: boolean | null
createdAt: Date