408 lines
26 KiB
Markdown
408 lines
26 KiB
Markdown
# 화면설계서: 결재선 관리
|
|
|
|
## 1. 기본 정보
|
|
|
|
| 항목 | 내용 |
|
|
| ---------- | -------------------------------------------- |
|
|
| 버전 | 0.3 |
|
|
| 프로세스명 | UI설계 |
|
|
| 화면명 | 결재선 관리 |
|
|
| 화면 유형 | [v] 조회 [v] 입력 [v] 수정 [v] 삭제 [ ] 출력 |
|
|
| 메뉴 경로 | 디지털행정지원 > 시스템관리 > 결재선 관리 |
|
|
|
|
---
|
|
|
|
## 2. 화면 목적
|
|
|
|
전자결재 처리에 사용할 **결재서식**(템플릿)을 등록·관리하고, 각 서식별로 **결재선**(결재구분·결재자·순서)을 구성한다. 상단의 결재서식 목록에서 하나를 선택하면 하단 영역에 해당 서식의 결재선이 표시되며, 사용자는 **그리드 인라인 폼**으로 결재자를 등록·수정한다. **행 추가 또는 한 행 수정 중에는 다른 행을 편집할 수 없다**(단일 행 편집 잠금). 드래그로 순서를 변경한 뒤 **[결재선 저장]** 으로 서버에 반영한다.
|
|
|
|
---
|
|
|
|
## 3. 화면 구성
|
|
|
|
### 3-1. 전체 레이아웃
|
|
|
|
```
|
|
┌───────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
│ 페이지 타이틀: 결재선 관리 브레드크럼: 디지털행정지원 > … > │
|
|
├───────────────────────────────────────────────────────────────────────────────────────────────┤
|
|
│ [영역 A] 전자결재선 관리 목록 [서식 등록] │
|
|
│ ┌──────────────────────────────────────────────────────────────────────┐ │
|
|
│ │ 전자결재서식아이디 | 결재서식명 | 문서구분 | 등록일시 | 관리 │ │
|
|
│ ├──────────────────────────────────────────────────────────────────────┤ │
|
|
│ │ TMPL-0001 (선택 행 강조) … [수정][삭제] │ │
|
|
│ └──────────────────────────────────────────────────────────────────────┘ │
|
|
├───────────────────────────────────────────────────────────────────────────────────────────────┤
|
|
│ [영역 B] 결재선 관리 선택된 서식: TMPL-0001 [결재선 저장] │
|
|
│ ┌─────────────────────────────────────────────────────────────────────────────────────────┐ │
|
|
│ │ [영역 B-2] 결재선 그리드 (인라인 편집 + 행 드래그 — @dnd-kit) │ │
|
|
│ │ ⋮⋮ | 결재선아이디 | 결재순서 | 결재구분 ▼ | 결재자 [선택] | 등록일시 | 관리 │ │
|
|
│ │ ⋮⋮ | APLN-0001 | [ 1 ] | [검토자 ▼] | [김민수 ][선택] | … | [저장][삭제] │ │
|
|
│ │ ⋮⋮ | (신규) | [ 2 ] | [승인자 ▼] | [ ][선택] | — | [저장][취소] │ │
|
|
│ └─────────────────────────────────────────────────────────────────────────────────────────┘ │
|
|
│ [행 추가] │
|
|
│ ※ 결재자 등록·수정은 그리드 셀에서 직접 입력. 검토인력만 [선택] 팝업/다이얼로그 │
|
|
│ ※ 행 추가·수정 중: 해당 행만 편집 가능, 나머지 행·[행 추가]·드래그 비활성 │
|
|
└───────────────────────────────────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
### 3-2. 화면 데이터 흐름
|
|
|
|
```
|
|
BEGIN
|
|
|
|
// 최초 진입
|
|
CALL GET /as-elapr-service/api/v1/elapr-tmplt
|
|
DISPLAY 결재서식 그리드 (영역 A)
|
|
DISPLAY 빈 상태 안내 (영역 B) // 서식 미선택 시 그리드·툴바 비활성
|
|
|
|
// 영역 A: 서식 행 선택
|
|
ON 영역 A 행 CLICK DO
|
|
SET 선택된 서식 = 행.elaprTmpltId
|
|
CALL GET /as-elapr-service/api/v1/elapr-apln?elaprTmpltId={id}
|
|
DISPLAY 결재선 그리드 (영역 B-2) — 조회 모드
|
|
END ON
|
|
|
|
// 영역 A: 신규 서식 등록
|
|
ON [서식 등록] 버튼 CLICK DO
|
|
OPEN 결재서식 등록 다이얼로그
|
|
ON 확인 DO
|
|
CALL POST /as-elapr-service/api/v1/elapr-tmplt
|
|
CALL GET /as-elapr-service/api/v1/elapr-tmplt
|
|
END ON
|
|
END ON
|
|
|
|
// 영역 A: 서식 수정·삭제 (다이얼로그 유지)
|
|
ON 영역 A [수정] / [삭제] DO
|
|
(기존과 동일 — PUT / DELETE elapr-tmplt)
|
|
END ON
|
|
|
|
// 영역 B: 행 추가 (인라인 신규 행)
|
|
ON [행 추가] 버튼 CLICK DO
|
|
VALIDATE 서식 선택됨
|
|
VALIDATE 편집 중인 행 없음 (editingRowKey == null)
|
|
ADD 영역 B-2 그리드 맨 아래 편집 가능 행
|
|
SET editingRowKey = rowKey (draft-{timestamp})
|
|
SET 편집상태 = 신규
|
|
SET aplnId = 미설정 (POST 저장 시 서버 fn_gen_apln_id 발급)
|
|
SET atrzSeqNo = 현재 행 수 + 1
|
|
SET atrzSeComCd, aprvrUuid = 빈 값
|
|
DISABLE 나머지 행 편집 · [행 추가] · 드래그 · [결재선 저장](정책에 따라)
|
|
END ON
|
|
|
|
// 영역 B-2: 기존 행 수정 진입
|
|
ON 행별 [수정] CLICK DO
|
|
VALIDATE 편집 중인 행 없음
|
|
SET editingRowId = 행.aplnId
|
|
SET 해당 행만 편집 모드
|
|
DISABLE 나머지 행 편집 · [행 추가] · 드래그
|
|
END ON
|
|
|
|
// 영역 B-2: 인라인 편집
|
|
ON 그리드 셀 변경 DO
|
|
VALIDATE 변경 대상 행 == editingRowId
|
|
SET 해당 행 dirty = true
|
|
END ON
|
|
|
|
ON 셀 [선택] (검토인력) CLICK DO
|
|
OPEN 검토인력 선택 다이얼로그 (단일 선택)
|
|
ON 선택 DO
|
|
SET 행.aprvrUuid = 선택인력.uuid
|
|
SET 행.aprvrNm = 선택인력.성명 // UI 표시용 (응답 DTO에 없음 — 로컬 보조 필드)
|
|
END ON
|
|
END ON
|
|
|
|
// 영역 B-2: 행별 저장
|
|
ON 행별 [저장] CLICK DO
|
|
VALIDATE atrzSeComCd, aprvrUuid, atrzSeqNo
|
|
IF 편집상태 = 신규 THEN
|
|
CALL POST /as-elapr-service/api/v1/elapr-apln
|
|
ELSE
|
|
CALL PUT /as-elapr-service/api/v1/elapr-apln/{aplnId}
|
|
END IF
|
|
CALL GET /as-elapr-service/api/v1/elapr-apln?elaprTmpltId={id}
|
|
CLEAR editingRowId
|
|
ENABLE 전체 행 조회 모드 · [행 추가] · 드래그
|
|
END ON
|
|
|
|
// 영역 B: 결재선 저장 (드래그 순서 일괄 반영)
|
|
ON [결재선 저장] 버튼 CLICK DO
|
|
VALIDATE 서식 선택됨
|
|
VALIDATE 편집 중인 행 없음
|
|
REORDER atrzSeqNo = 그리드 행 순서 (1..n)
|
|
FOR EACH dirty 또는 순서 변경된 행 DO
|
|
CALL PUT /as-elapr-service/api/v1/elapr-apln/{aplnId} // atrzSeqNo 등 반영
|
|
END FOR
|
|
FOR EACH 신규 미저장 행 DO
|
|
CALL POST /as-elapr-service/api/v1/elapr-apln
|
|
END FOR
|
|
CALL GET /as-elapr-service/api/v1/elapr-apln?elaprTmpltId={id}
|
|
TOAST "결재선이 저장되었습니다."
|
|
END ON
|
|
|
|
// 영역 B-2: 행 드래그
|
|
ON 영역 B-2 행 DRAG END DO
|
|
VALIDATE 편집 중인 행 없음
|
|
REORDER 그리드 행
|
|
SET 각 행 atrzSeqNo = 행 인덱스 + 1 (UI 즉시 반영, 서버는 [결재선 저장] 또는 행별 [저장])
|
|
END ON
|
|
|
|
// 영역 B-2: 행 삭제
|
|
ON 행별 [삭제] CLICK DO
|
|
CONFIRM "선택한 결재선을 삭제하시겠습니까?"
|
|
IF 서버 저장된 행 THEN
|
|
CALL DELETE /as-elapr-service/api/v1/elapr-apln/{aplnId}
|
|
END IF
|
|
REMOVE 그리드 행 (신규 미저장 행은 API 호출 없이 제거)
|
|
CALL GET /as-elapr-service/api/v1/elapr-apln?elaprTmpltId={id}
|
|
END ON
|
|
|
|
ON 행별 [취소] CLICK DO // 신규·수정 공통
|
|
IF 편집상태 = 신규 THEN REMOVE 임시 행
|
|
ELSE RESTORE 행 스냅샷 (수정 취소)
|
|
CLEAR editingRowId
|
|
ENABLE 전체 행 조회 모드 · [행 추가] · 드래그
|
|
END ON
|
|
|
|
END
|
|
```
|
|
|
|
---
|
|
|
|
## 4. 영역 A: 전자결재선 관리 목록
|
|
|
|
선택된 결재서식이 영역 B의 작업 대상이 된다. 행 클릭으로 선택 상태를 표시(좌측 컬러 바·배경 강조)한다.
|
|
|
|
### 4-1. 헤더 / 툴바
|
|
|
|
| 항목 | 내용 |
|
|
| ----------- | ----------------------------------------------- |
|
|
| 섹션 타이틀 | 전자결재선 관리 목록 |
|
|
| 우측 버튼 | **[서식 등록]** — 결재서식 등록 다이얼로그 오픈 |
|
|
|
|
### 4-2. 그리드 컬럼
|
|
|
|
| 컬럼명 | Field | 타입 | 비고 |
|
|
| ------------------ | -------------- | ------ | --------------------------------------- |
|
|
| 전자결재서식아이디 | `elaprTmpltId` | string | 등록 시 서버(DB 함수) 자동 발급 |
|
|
| 결재서식명 | `elaprTmpltNm` | string | |
|
|
| 문서구분 | `docSeComNm` | string | 코드 `docSeComCd`, 상위코드 `ASDOCSECD` |
|
|
| 등록일시 | `regDt` | string | `yyyy-MM-dd HH:mm:ss` |
|
|
| 관리 | — | — | 행별 **[수정] · [삭제]** 버튼 |
|
|
|
|
- 행 클릭 시: `elaprTmpltId` 선택 → 영역 B 라벨·B-2 그리드 갱신.
|
|
- 페이지네이션: Spring `Pageable` (`page`, `size`, `sort`).
|
|
|
|
### 4-3. 버튼
|
|
|
|
| 버튼명 | 위치 | 동작 |
|
|
| --------- | -------------- | ----------------------------------------------- |
|
|
| 서식 등록 | 섹션 우측 상단 | 결재서식 등록 다이얼로그 오픈 |
|
|
| 수정 | 행별 | 결재서식 수정 다이얼로그 (기존 값 초기화) |
|
|
| 삭제 | 행별 | 확인 후 삭제. 선택 중인 서식이면 영역 B 초기화. |
|
|
|
|
### 4-4. 다이얼로그(개요)
|
|
|
|
| 다이얼로그명 | 트리거 | 입력 항목 | 비고 |
|
|
| ------------------ | ----------- | ----------------------------------------------- | ----------------------------------------- |
|
|
| 결재서식 등록 | [서식 등록] | `elaprTmpltNm`, `docSeComCd` | `elaprTmpltExpln` 선택, ID는 저장 후 응답 |
|
|
| 결재서식 수정 | 행별 [수정] | `elaprTmpltNm`, `docSeComCd`, `elaprTmpltExpln` | ID는 변경 불가 |
|
|
| 결재서식 삭제 확인 | 행별 [삭제] | (확인/취소) | |
|
|
|
|
---
|
|
|
|
## 5. 영역 B: 결재선 관리
|
|
|
|
영역 A에서 선택된 `elaprTmpltId` 기준으로 결재선을 관리한다. **등록·수정은 B-2 그리드 인라인 폼**으로 수행하며, 검토인력 지정만 **[선택]** 보조 다이얼로그를 사용한다.
|
|
|
|
### 5-1. 헤더 / 툴바
|
|
|
|
| 항목 | 내용 |
|
|
| ----------- | --------------------------------------------------------------------------------------------------------------------------- |
|
|
| 섹션 타이틀 | 결재선 관리 |
|
|
| 우측 라벨 | `선택된 서식: {elaprTmpltId}` — 미선택 시 영역 B 비활성 |
|
|
| 우측 버튼 | **[행 추가]** — 편집 중인 행이 없을 때만 활성 · **[결재선 저장]** — 편집 중인 행이 없을 때만 활성(순서·미저장 행 일괄 반영) |
|
|
|
|
### 5-2. 영역 B-2: 결재선 그리드 (인라인 편집)
|
|
|
|
#### 그리드 컬럼
|
|
|
|
| 컬럼명 | Field | 입력 UI (편집 모드) | 비고 |
|
|
| ------------- | ------------- | ----------------------------------------------------------------------------------------- | ---------------------------------------------- |
|
|
| (드래그 핸들) | — | — | `useSortable` 연동 |
|
|
| 결재선아이디 | `aplnId` | 읽기 전용 | 신규 행: `—`, 저장 후 서버 `aplnId` 표시 |
|
|
| 결재순서번호 | `atrzSeqNo` | 읽기 전용 (그리드 행 순서 1부터 표시) | 저장 시 행 순서 기준 자동 채번 |
|
|
| 결재구분 | `atrzSeComCd` | Select (`ATRZSECD` 공통코드) | 표시명 `atrzSeComNm` (조회 행) |
|
|
| 결재자 | `aprvrUuid` | 읽기 전용 이름 + **[선택]** 버튼 | 응답에 성명 없음 — 선택 시 로컬 `aprvrNm` 유지 |
|
|
| 등록일시 | `regDt` | 읽기 전용 | 신규 행은 `—` |
|
|
| 관리 | — | 편집 중인 행: **[저장] [취소]** · 조회 행: **[수정] [삭제]** (다른 행 편집 중이면 비활성) |
|
|
|
|
#### 인라인 편집 정책
|
|
|
|
| 항목 | 내용 |
|
|
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
|
|
| **단일 행 편집** | **행 추가 또는 한 행 수정 중에는 다른 행을 편집할 수 없다.** `editingRowId` 로 현재 편집 행 1건만 허용. |
|
|
| 편집 잠금 시 비활성 | 다른 행: 셀·[수정]·[삭제] 비활성 · `[행 추가]` 비활성 · 행 드래그 비활성 · (선택) `[결재선 저장]` 비활성 |
|
|
| 편집 해제 | 행별 **[저장]** 성공 또는 **[취소]** 시 `editingRowId` 초기화 후 전체 조회 모드 복귀 |
|
|
| 조회 행 | 편집 중이 아닐 때 읽기 전용. **[수정]** 클릭 시 해당 행만 편집 모드 진입 |
|
|
| 신규 행 | `[행 추가]` 시 맨 아래 편집 행 1건 생성 (`editingRowId` = 임시 키) |
|
|
| 필수값 | `atrzSeComCd`, `aprvrUuid` |
|
|
| 순서 중복 | 저장 시 행 순서로 자동 채번하므로 중복 없음 |
|
|
| 결재구분 코드 | `ATRZSECD` — 예: `ATRZ01` 검토자, `ATRZ02` 승인자, `ATRZ03` 최종승인자 |
|
|
| **순서 제약** | `ATRZ01`은 최상단 블록, `ATRZ03`은 최하단 블록. 드래그 종료·저장 시 `validateAtrzOrder`로 검증, 위반 시 적용/저장 불가 (결재구분 변경 시에는 미검증) |
|
|
| 저장 단위 | 행별 **[저장]** (단건 POST/PUT) 또는 툴바 **[결재선 저장]** (일괄) |
|
|
|
|
#### 행 드래그 정렬 (`@dnd-kit` + `useSortable`)
|
|
|
|
| 항목 | 내용 |
|
|
| ---------- | ------------------------------------------------------------------------------------------------------- |
|
|
| 목적 | 결재 단계 순서를 그리드에서 직접 변경 |
|
|
| 라이브러리 | `@dnd-kit/core`, `@dnd-kit/sortable` — 테이블 행 POC 후 확정 |
|
|
| 저장 시점 | 드래그는 클라이언트 상태만 변경 → **[결재선 저장]** 또는 행별 **[저장]** 시 `atrzSeqNo` PUT |
|
|
| 편집 중 | `editingRowKey != null` 이면 드래그 **불가** |
|
|
| 순서 제약 | 드래그 종료 시 `validateAtrzOrder` — 실패하면 순서 변경 미적용 + 안내. 결재구분 미선택 행은 드래그 불가 |
|
|
|
|
### 5-3. 보조 다이얼로그 (검토인력만)
|
|
|
|
| 다이얼로그명 | 트리거 | 결과 |
|
|
| ------------- | ----------------------- | ---------------------------------- |
|
|
| 검토인력 선택 | 그리드 결재자 셀 [선택] | `aprvrUuid` 및 UI용 `aprvrNm` 반영 |
|
|
|
|
> 결재자 **등록·수정 다이얼로그는 사용하지 않음** (v0.2 변경).
|
|
|
|
---
|
|
|
|
## 6. API/DTO 명세
|
|
|
|
### 6-1. 공통
|
|
|
|
| 항목 | 내용 |
|
|
| ----------- | ------------------------------------------------------------- |
|
|
| 서비스 | `as-elapr-service` |
|
|
| Base prefix | `/as-elapr-service/api/v1` (프록시 경유) |
|
|
| 인증 | JWT (`Authorization` 헤더) |
|
|
| 페이징 | Spring `Pageable`: `page`, `size`, `sort` → `PageResponse<T>` |
|
|
| 엔티티 | `@/entities/elapr` (`elaprTmpltService`, `elaprAplnService`) |
|
|
|
|
### 6-2. 전자결재서식 (영역 A) — `elapr-tmplt`
|
|
|
|
| 기능 | Method | URL | Request / Query | Response | 클라이언트 |
|
|
| --------- | ------ | ----------------------------- | ------------------------------------------ | ------------------ | ---------------------------- |
|
|
| 목록 조회 | GET | `/elapr-tmplt` | Query: `ElaprTmpltSearchParams` + Pageable | `Page<ElaprTmplt>` | `elaprTmpltService.findPage` |
|
|
| 단건 조회 | GET | `/elapr-tmplt/{elaprTmpltId}` | — | `ElaprTmplt` | `elaprTmpltService.findById` |
|
|
| 등록 | POST | `/elapr-tmplt` | `ElaprTmpltSaveRequest` | `ElaprTmplt` (201) | `elaprTmpltService.create` |
|
|
| 수정 | PUT | `/elapr-tmplt/{elaprTmpltId}` | `ElaprTmpltUpdateRequest` | `ElaprTmplt` | `elaprTmpltService.update` |
|
|
| 삭제 | DELETE | `/elapr-tmplt/{elaprTmpltId}` | — | 204 | `elaprTmpltService.remove` |
|
|
|
|
**ElaprTmplt (응답)**
|
|
|
|
| Field | 타입 | 설명 |
|
|
| ----------------- | ------- | ------------------ |
|
|
| `elaprTmpltId` | string | 전자결재서식아이디 |
|
|
| `elaprTmpltNm` | string | 결재서식명 |
|
|
| `elaprTmpltExpln` | string? | 서식 설명 |
|
|
| `docSeComCd` | string? | 문서구분 코드 |
|
|
| `docSeComNm` | string? | 문서구분명 |
|
|
| `regDt` | string? | 등록일시 |
|
|
|
|
**ElaprTmpltSaveRequest**: `elaprTmpltNm`\_, `elaprTmpltExpln?`, `docSeComCd?`
|
|
|
|
**ElaprTmpltUpdateRequest**: `elaprTmpltNm`\*, `elaprTmpltExpln?`, `docSeComCd?`
|
|
|
|
**ElaprTmpltSearchParams**: `elaprTmpltNm?`, `docSeComCd?`, `regDtStart?`, `regDtEnd?` + `page`, `size`, `sort`
|
|
|
|
### 6-3. 결재선 (영역 B) — `elapr-apln`
|
|
|
|
| 기능 | Method | URL | Request / Query | Response | 클라이언트 |
|
|
| --------- | ------ | ---------------------- | ------------------------------- | ----------------- | --------------------------- |
|
|
| 목록 조회 | GET | `/elapr-apln` | Query: `elaprTmpltId`, Pageable | `Page<ElaprApln>` | `elaprAplnService.findPage` |
|
|
| 단건 조회 | GET | `/elapr-apln/{aplnId}` | — | `ElaprApln` | `elaprAplnService.findById` |
|
|
| 등록 | POST | `/elapr-apln` | `ElaprAplnSaveRequest` | `ElaprApln` (201) | `elaprAplnService.create` |
|
|
| 수정 | PUT | `/elapr-apln/{aplnId}` | `ElaprAplnUpdateRequest` | `ElaprApln` | `elaprAplnService.update` |
|
|
| 삭제 | DELETE | `/elapr-apln/{aplnId}` | — | 204 | `elaprAplnService.remove` |
|
|
|
|
> **일괄 저장 API 없음** — UI의 [결재선 저장]은 변경된 행에 대해 POST/PUT을 순차(또는 병렬) 호출하는 클라이언트 오케스트레이션으로 구현.
|
|
|
|
**ElaprApln (응답)**
|
|
|
|
| Field | 타입 | 설명 |
|
|
| -------------- | ------- | ------------------ |
|
|
| `aplnId` | string | 결재선아이디 |
|
|
| `elaprTmpltId` | string | 전자결재서식아이디 |
|
|
| `aprvrUuid` | string? | 결재자 UUID |
|
|
| `atrzSeComCd` | string? | 결재구분 코드 |
|
|
| `atrzSeComNm` | string? | 결재구분명 |
|
|
| `atrzSeqNo` | number? | 결재순서번호 |
|
|
| `regDt` | string? | 등록일시 |
|
|
|
|
**ElaprAplnSaveRequest**: `elaprTmpltId`\_, `aprvrUuid?`, `atrzSeComCd?`, `atrzSeqNo?`
|
|
|
|
**ElaprAplnUpdateRequest**: `elaprTmpltId`\*, `aprvrUuid?`, `atrzSeComCd?`, `atrzSeqNo?`
|
|
|
|
### 6-4. 검토인력 (보조)
|
|
|
|
| 기능 | Method | URL | 비고 |
|
|
| ------------------ | ------ | --- | --------------------------- |
|
|
| 검토인력 목록 조회 | TBD | TBD | 사용자 서비스 또는 별도 API |
|
|
|
|
### 6-5. Backend ↔ 화면 필드 매핑 (구 SPEC 대비)
|
|
|
|
| 구 SPEC 필드 | 백엔드 필드 |
|
|
| ----------------- | ---------------------------------------------------- |
|
|
| `elctAtrzTmpltId` | `elaprTmpltId` |
|
|
| `atrzTmpltNm` | `elaprTmpltNm` |
|
|
| `docSeNm` | `docSeComNm` |
|
|
| `atrzLineId` | `aplnId` |
|
|
| `atrzSeNm` | `atrzSeComNm` |
|
|
| `atrzUserNm` | (없음) `aprvrUuid` + 사용자 조회/선택 시 로컬 표시명 |
|
|
|
|
---
|
|
|
|
## 7. UI 구현 가이드
|
|
|
|
### 7-1. 기술 스택·원칙
|
|
|
|
- **공통 컴포넌트**: `@common/components`
|
|
- **테이블**: `@tanstack/react-table` + 인라인 편집 셀 (`Select`, `Input`, `Button`)
|
|
- **드래그**: `@dnd-kit` — B-2 행 정렬 (POC 필수)
|
|
- **데이터**: React Query — `@/entities/elapr` hooks
|
|
- **상태**: 선택된 `elaprTmpltId`, `editingRowId` (단일 행 편집 잠금), B-2 행 배열(dirty·신규·`aprvrNm`·수정 전 스냅샷)
|
|
- **모의 데이터**: API 연동 전 `@faker-js/faker`
|
|
|
|
### 7-2. 모듈·파일 배치(제안)
|
|
|
|
| 구분 | 경로 |
|
|
| ------ | -------------------------------------------------------------------------------------- |
|
|
| 라우트 | `apps/as/app/(with-base-layout)/approval-line-management/page.tsx` |
|
|
| 페이지 | `apps/as/src/pages/approval-line-management/` (Public API: page만 export) |
|
|
| UI | `.../ui/elapr-tmplt-list.tsx`, `elapr-tmplt-form-dialog.tsx`, `elapr-apln-grid.tsx` 등 |
|
|
| model | `.../model/columns.tsx`, `apln-row-types.ts`, `mock-reviewers.ts` |
|
|
| lib | `.../lib/use-apln-rows.ts`, `validators.ts`, `use-dnd-sensors.ts` |
|
|
| 엔티티 | `apps/as/src/entities/elapr/` |
|
|
|
|
### 7-3. 영역별 UI 매핑
|
|
|
|
| 영역 | 주요 UI |
|
|
| ------ | -------------------------------------------------------------------------------------------- |
|
|
| A | DataTable + 행 선택 + 서식 등록/수정 다이얼로그 |
|
|
| B 헤더 | 상태 라벨 + `행 추가`, `결재선 저장` |
|
|
| B-2 | 인라인 편집 DataTable + `editingRowId` 단일 행 잠금 + 드래그 핸들 + 행별 수정/저장/삭제/취소 |
|
|
| 공통 | 서식 Dialog, 검토인력 선택 Dialog만 |
|
|
|
|
### 7-4. 데이터 흐름(요약)
|
|
|
|
- **진입**: `useElaprTmpltPage` → 영역 A. B 비활성.
|
|
- **서식 선택**: `useElaprAplnPage({ elaprTmpltId })` → B-2.
|
|
- **행 추가**: `editingRowId` 없을 때만 가능 → 신규 행 1건 편집 잠금 → 저장/취소 후 해제.
|
|
- **인라인 수정**: [수정]으로 `editingRowId` 설정 → 해당 행만 편집 → `useUpdateElaprApln` 후 해제.
|
|
- **드래그**: `editingRowId == null` 일 때만 가능 → 로컬 `atrzSeqNo` 재부여 → 일괄 PUT.
|
|
- **삭제**: `useDeleteElaprApln` 또는 신규 행 로컬 제거.
|
|
|
|
### 7-5. 미확정 / 검증 필요
|
|
|
|
- 검토인력 API 경로·DTO.
|
|
- `@dnd-kit` + react-table 행 인라인 Input 동시 적용 POC.
|
|
- 결재자 성명 표시: `aprvrUuid` → 사용자명 조회 API.
|
|
- 영역 A·B 페이지네이션·검색 UI 노출 여부.
|
|
- 권한(역할별 CRUD).
|