- Introduced new documents detailing the modifications made to the category tree modal for continuous registration mode. - Updated the functionality to allow the modal to close after saving or remain open based on user preference via a checkbox. - Enhanced the user experience by aligning the modal behavior with existing patterns in the project. - Included a checklist to track implementation progress and ensure thorough testing. These changes aim to improve the usability and consistency of the category management feature in the application.
200 lines
6.4 KiB
Markdown
200 lines
6.4 KiB
Markdown
# [계획서] 카테고리 트리 대분류 추가 모달 - 연속 등록 모드 수정
|
|
|
|
> 관련 문서: [맥락노트](./CCA[맥락]-카테고리-연속등록모드.md) | [체크리스트](./CCA[체크]-카테고리-연속등록모드.md)
|
|
|
|
## 개요
|
|
|
|
기준정보 - 옵션설정 화면에서 트리 구조 카테고리(예: 품목정보 > 재고단위)의 "대분류 추가" 모달이 저장 후 닫히지 않는 버그를 수정합니다.
|
|
평면 목록용 추가 모달(`CategoryValueAddDialog.tsx`)과 동일한 연속 입력 패턴을 적용합니다.
|
|
|
|
---
|
|
|
|
## 현재 동작
|
|
|
|
- 대분류 추가 모달에서 값 입력 후 "추가" 클릭 시 **값은 정상 저장됨**
|
|
- 저장 후 **모달이 닫히지 않고** 폼만 초기화됨 (항상 연속 입력 상태)
|
|
- "연속 입력" 체크박스 UI가 **없음** → 사용자가 모드를 끌 수 없음
|
|
- 모달을 닫으려면 "닫기" 버튼 또는 외부 클릭을 해야 함
|
|
|
|
### 현재 코드 (CategoryValueManagerTree.tsx - handleAdd, 512~530행)
|
|
|
|
```tsx
|
|
if (response.success) {
|
|
toast.success("카테고리가 추가되었습니다");
|
|
// 폼 초기화 (모달은 닫지 않고 연속 입력)
|
|
setFormData((prev) => ({
|
|
...prev,
|
|
valueCode: "",
|
|
valueLabel: "",
|
|
description: "",
|
|
color: "",
|
|
}));
|
|
setTimeout(() => addNameRef.current?.focus(), 50);
|
|
await loadTree(true);
|
|
if (parentValue) {
|
|
setExpandedNodes((prev) => new Set([...prev, parentValue.valueId]));
|
|
}
|
|
}
|
|
```
|
|
|
|
### 현재 DialogFooter (809~821행)
|
|
|
|
```tsx
|
|
<DialogFooter className="gap-2 sm:gap-0">
|
|
<Button variant="outline" onClick={() => setIsAddModalOpen(false)} ...>
|
|
닫기
|
|
</Button>
|
|
<Button onClick={handleAdd} ...>
|
|
추가
|
|
</Button>
|
|
</DialogFooter>
|
|
```
|
|
|
|
---
|
|
|
|
## 변경 후 동작
|
|
|
|
### 1. 기본 동작: 저장 후 모달 닫힘
|
|
|
|
- "추가" 클릭 → 저장 성공 → 모달 닫힘 + 트리 새로고침
|
|
- `CategoryValueAddDialog.tsx`(평면 목록 추가 모달)와 동일한 기본 동작
|
|
|
|
### 2. 연속 입력 체크박스 추가
|
|
|
|
- DialogFooter 좌측에 "연속 입력" 체크박스 표시
|
|
- 기본값: 체크 해제 (OFF)
|
|
- 체크 시: 저장 후 폼만 초기화, 모달 유지, 이름 필드에 포커스
|
|
- 체크 해제 시: 저장 후 모달 닫힘
|
|
|
|
---
|
|
|
|
## 시각적 예시
|
|
|
|
| 상태 | 연속 입력 체크 | 추가 버튼 클릭 후 |
|
|
|------|---------------|-----------------|
|
|
| 기본 (체크 해제) | [ ] 연속 입력 | 저장 → 모달 닫힘 → 트리 갱신 |
|
|
| 연속 모드 (체크) | [x] 연속 입력 | 저장 → 폼 초기화 → 모달 유지 → 이름 필드 포커스 |
|
|
|
|
### 모달 하단 레이아웃 (ScreenModal.tsx 패턴)
|
|
|
|
```
|
|
┌─────────────────────────────────────────┐
|
|
│ [닫기] [추가] │ ← DialogFooter (버튼만)
|
|
├─────────────────────────────────────────┤
|
|
│ [x] 저장 후 계속 입력 (연속 등록 모드) │ ← border-t 구분선 아래 별도 영역
|
|
└─────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## 아키텍처
|
|
|
|
```mermaid
|
|
flowchart TD
|
|
A["사용자: '추가' 클릭"] --> B["handleAdd()"]
|
|
B --> C{"API 호출 성공?"}
|
|
C -- 실패 --> D["toast.error → 모달 유지"]
|
|
C -- 성공 --> E["toast.success + loadTree"]
|
|
E --> F{"continuousAdd?"}
|
|
F -- true --> G["폼 초기화 + 이름 필드 포커스\n모달 유지"]
|
|
F -- false --> H["폼 초기화 + 모달 닫힘"]
|
|
```
|
|
|
|
---
|
|
|
|
## 변경 대상 파일
|
|
|
|
| 파일 | 역할 | 변경 내용 |
|
|
|------|------|----------|
|
|
| `frontend/components/table-category/CategoryValueManagerTree.tsx` | 트리형 카테고리 값 관리 | 상태 추가, handleAdd 분기, DialogFooter UI |
|
|
|
|
- **변경 규모**: 약 20줄 내외 소규모 변경
|
|
- **참고 파일**: `frontend/components/table-category/CategoryValueAddDialog.tsx` (동일 패턴)
|
|
|
|
---
|
|
|
|
## 코드 설계
|
|
|
|
### 1. 상태 추가 (286행 근처, 모달 상태 선언부)
|
|
|
|
```tsx
|
|
const [continuousAdd, setContinuousAdd] = useState(false);
|
|
```
|
|
|
|
### 2. handleAdd 성공 분기 수정 (512~530행 대체)
|
|
|
|
```tsx
|
|
if (response.success) {
|
|
toast.success("카테고리가 추가되었습니다");
|
|
await loadTree(true);
|
|
if (parentValue) {
|
|
setExpandedNodes((prev) => new Set([...prev, parentValue.valueId]));
|
|
}
|
|
|
|
if (continuousAdd) {
|
|
setFormData((prev) => ({
|
|
...prev,
|
|
valueCode: "",
|
|
valueLabel: "",
|
|
description: "",
|
|
color: "",
|
|
}));
|
|
setTimeout(() => addNameRef.current?.focus(), 50);
|
|
} else {
|
|
setFormData({ valueCode: "", valueLabel: "", description: "", color: "", isActive: true });
|
|
setIsAddModalOpen(false);
|
|
}
|
|
}
|
|
```
|
|
|
|
### 3. DialogFooter + 연속 등록 체크박스 수정 (809~821행 대체)
|
|
|
|
DialogFooter는 버튼만 유지하고, 그 아래에 `border-t` 구분선과 체크박스를 별도 영역으로 배치합니다.
|
|
`ScreenModal.tsx` (1287~1303행) 패턴 그대로입니다.
|
|
|
|
```tsx
|
|
<DialogFooter className="gap-2 sm:gap-0">
|
|
<Button
|
|
variant="outline"
|
|
onClick={() => setIsAddModalOpen(false)}
|
|
className="h-9 flex-1 text-sm sm:flex-none"
|
|
>
|
|
닫기
|
|
</Button>
|
|
<Button onClick={handleAdd} className="h-9 flex-1 text-sm sm:flex-none">
|
|
추가
|
|
</Button>
|
|
</DialogFooter>
|
|
|
|
{/* 연속 등록 모드 체크박스 - ScreenModal.tsx 패턴 */}
|
|
<div className="border-t px-4 py-3">
|
|
<div className="flex items-center gap-2">
|
|
<Checkbox
|
|
id="tree-continuous-add"
|
|
checked={continuousAdd}
|
|
onCheckedChange={(checked) => setContinuousAdd(checked as boolean)}
|
|
/>
|
|
<Label htmlFor="tree-continuous-add" className="cursor-pointer text-sm font-normal select-none">
|
|
저장 후 계속 입력 (연속 등록 모드)
|
|
</Label>
|
|
</div>
|
|
</div>
|
|
```
|
|
|
|
---
|
|
|
|
## 예상 문제 및 대응
|
|
|
|
`CategoryValueAddDialog.tsx`와 동일한 패턴이므로 별도 예상 문제 없음.
|
|
|
|
---
|
|
|
|
## 설계 원칙
|
|
|
|
- `CategoryValueAddDialog.tsx`(같은 폴더, 같은 목적)의 패턴을 그대로 따름
|
|
- 기존 수정/삭제 모달 동작은 변경하지 않음
|
|
- 하위 추가(중분류/소분류) 모달도 동일한 `handleAdd`를 사용하므로 자동 적용
|
|
- `Checkbox` import는 이미 존재 (24행)하므로 추가 import 불필요
|
|
- `Label` import는 이미 존재 (53행)하므로 추가 import 불필요
|
|
- 체크박스 위치/라벨/className 모두 `ScreenModal.tsx` (1287~1303행)과 동일
|