diff options
Diffstat (limited to 'lib/approval-template/editor')
| -rw-r--r-- | lib/approval-template/editor/approval-template-editor.tsx | 70 |
1 files changed, 59 insertions, 11 deletions
diff --git a/lib/approval-template/editor/approval-template-editor.tsx b/lib/approval-template/editor/approval-template-editor.tsx index f23ac4bd..2c4ef65e 100644 --- a/lib/approval-template/editor/approval-template-editor.tsx +++ b/lib/approval-template/editor/approval-template-editor.tsx @@ -19,18 +19,21 @@ import { getApprovalLineOptionsAction } from "@/lib/approval-line/service" import { type ApprovalTemplate } from "@/lib/approval-template/service" import { type Editor } from "@tiptap/react" import { updateApprovalTemplateAction } from "@/lib/approval-template/service" +import { getActiveApprovalTemplateCategories, type ApprovalTemplateCategory } from "@/lib/approval-template/category-service" import { useSession } from "next-auth/react" +import { useRouter, usePathname } from "next/navigation" interface ApprovalTemplateEditorProps { templateId: string initialTemplate: ApprovalTemplate staticVariables?: Array<{ variableName: string }> approvalLineOptions: Array<{ id: string; name: string }> - approvalLineCategories: string[] } -export function ApprovalTemplateEditor({ templateId, initialTemplate, staticVariables = [], approvalLineOptions, approvalLineCategories }: ApprovalTemplateEditorProps) { +export function ApprovalTemplateEditor({ templateId, initialTemplate, staticVariables = [], approvalLineOptions }: ApprovalTemplateEditorProps) { const { data: session } = useSession() + const router = useRouter() + const pathname = usePathname() const [rte, setRte] = React.useState<Editor | null>(null) const [template, setTemplate] = React.useState(initialTemplate) const [isSaving, startSaving] = React.useTransition() @@ -56,11 +59,43 @@ export function ApprovalTemplateEditor({ templateId, initialTemplate, staticVari approvalLineId: (template as { approvalLineId?: string | null }).approvalLineId ?? "", }) - const [category, setCategory] = React.useState(form.category ?? (approvalLineCategories[0] ?? "")) + const [categories, setCategories] = React.useState<ApprovalTemplateCategory[]>([]) + const [isLoadingCategories, setIsLoadingCategories] = React.useState(false) + const [category, setCategory] = React.useState(form.category ?? "") + const [isInitialLoad, setIsInitialLoad] = React.useState(true) // eslint-disable-next-line @typescript-eslint/no-explicit-any const [lineOptions, setLineOptions] = React.useState(approvalLineOptions as Array<{ id: string; name: string; aplns?: any[]; category?: string | null }>) const [isLoadingLines, setIsLoadingLines] = React.useState(false) + // 카테고리 목록 로드 (초기 한 번만) + React.useEffect(() => { + let active = true + const loadCategories = async () => { + setIsLoadingCategories(true) + try { + const data = await getActiveApprovalTemplateCategories() + if (active) { + setCategories(data) + // 초기 로드 시에만 기본 카테고리 설정 (템플릿의 카테고리가 없고 카테고리가 선택되지 않은 경우) + if (isInitialLoad && !category && data.length > 0) { + const defaultCategory = form.category || data[0].name + setCategory(defaultCategory) + } + setIsInitialLoad(false) + } + } catch (error) { + console.error('카테고리 로드 실패:', error) + } finally { + if (active) setIsLoadingCategories(false) + } + } + loadCategories() + return () => { + active = false + } + }, []) // 빈 의존성 배열로 초기 한 번만 실행 + + // 결재선 옵션 로드 React.useEffect(() => { let active = true const run = async () => { @@ -109,6 +144,12 @@ export function ApprovalTemplateEditor({ templateId, initialTemplate, staticVari setTemplate(data) toast.success("저장되었습니다") + + // 저장 후 목록 페이지로 이동 (back-button.tsx 로직 참고) + const segments = pathname.split('/').filter(Boolean) + const newSegments = segments.slice(0, -1) // 마지막 세그먼트(ID) 제거 + const targetPath = newSegments.length > 0 ? `/${newSegments.join('/')}` : '/' + router.push(targetPath) }) } @@ -161,18 +202,25 @@ export function ApprovalTemplateEditor({ templateId, initialTemplate, staticVari <div className="space-y-2"> <label className="text-sm font-medium">카테고리</label> <Select - value={category} - onValueChange={(value) => setCategory(value)} + value={category || "none"} + onValueChange={(value) => setCategory(value === "none" ? "" : value)} + disabled={isLoadingCategories} > <SelectTrigger> - <SelectValue placeholder="카테고리를 선택하세요" /> + <SelectValue placeholder={isLoadingCategories ? "카테고리 로드 중..." : "카테고리를 선택하세요"} /> </SelectTrigger> <SelectContent> - {approvalLineCategories.map((cat) => ( - <SelectItem key={cat} value={cat}> - {cat} - </SelectItem> - ))} + <SelectItem value="none">선택 안함</SelectItem> + {categories + .sort((a, b) => a.sortOrder - b.sortOrder) + .map((cat) => ( + <SelectItem key={`category-${cat.id}`} value={cat.name}> + {cat.name} + {cat.description && ( + <span className="text-muted-foreground ml-2">({cat.description})</span> + )} + </SelectItem> + ))} </SelectContent> </Select> </div> |
