- buttonActions.ts: formData가 배열인 경우 일반 저장 건너뜀
- SelectedItemsDetailInput이 UPSERT를 완료한 후 일반 저장이 실행되어 null 레코드가 삽입되던 문제 해결
- ScreenModal에서 그룹 레코드를 배열로 전달하는 경우 감지하여 처리
- skipDefaultSave 플래그가 제대로 작동하지 않던 문제 근본 해결
- SelectedItemsDetailInput 컴포넌트 수정 모드 지원
- 그룹화된 데이터 UPSERT API 추가 (/api/data/upsert-grouped)
- 부모 키 기준으로 기존 레코드 조회 후 INSERT/UPDATE/DELETE
- 각 레코드의 모든 필드 조합을 고유 키로 사용
- created_date 보존 (UPDATE 시)
- 수정 모드에서 groupByColumns 기준으로 관련 레코드 조회
- 날짜 타입 ISO 형식 자동 감지 및 포맷팅 (YYYY.MM.DD)
주요 변경사항:
- backend: dataService.upsertGroupedRecords() 메서드 구현
- backend: dataRoutes POST /api/data/upsert-grouped 엔드포인트 추가
- frontend: ScreenModal에서 groupByColumns 파라미터 전달
- frontend: SelectedItemsDetailInput 수정 모드 로직 추가
- frontend: 날짜 필드 타임존 제거 및 포맷팅 개선
- 여러 테이블(거래처, 품목 등)에서 데이터를 가져와 자동 매핑 가능
- 각 매핑마다 소스 테이블, 원본 필드, 저장 필드를 독립적으로 설정
- 검색 가능한 Combobox로 테이블 및 컬럼 선택 UX 개선
- 소스 테이블 선택 시 해당 테이블의 컬럼 자동 로드
- 라벨, 컬럼명, 데이터 타입으로 검색 가능
- 세로 레이아웃으로 가독성 향상
기술적 변경사항:
- ParentDataMapping 인터페이스 추가 (sourceTable, sourceField, targetField)
- buttonActions.ts의 handleBatchSave에서 소스 테이블 기반 데이터 소스 자동 판단
- tableManagementApi.getColumnList() 사용하여 테이블 컬럼 동적 로드
- Command + Popover 조합으로 검색 가능한 Select 구현
- 각 매핑별 독립적인 컬럼 상태 관리 (mappingSourceColumns)
- 선택항목 상세입력 컴포넌트 확장
- 실시간 가격 계산 기능 추가 (할인율/할인금액, 반올림 방식)
- 카테고리 값 기반 연산 매핑 시스템
- 3단계 드릴다운 방식 설정 UI (메뉴 → 카테고리 → 값 매핑)
- 설정 가능한 계산 로직
- autoCalculation 설정으로 계산 필드명 동적 지정
- valueMapping으로 카테고리 코드와 연산 타입 매핑
- 할인 방식: none/rate/amount
- 반올림 방식: none/round/floor/ceil
- 반올림 단위: 1/10/100/1000
- UI 개선
- 입력 필드 가로 배치 (반응형 Grid)
- 카테고리 타입 필드 옵션 로딩 개선
- 계산 결과 필드 자동 표시 및 읽기 전용 처리
- 날짜 입력 필드 네이티브 피커 지원
- API 연동
- 2레벨 메뉴 목록 조회
- 메뉴별 카테고리 컬럼 조회
- 카테고리별 값 목록 조회
- 문서화
- 기간별 단가 설정 가이드 작성
- FieldGroup에 displayItems 추가 (그룹별 독립적인 표시 설정)
- SelectedItemsDetailInputConfig에서 전역 displayItems 제거
- renderDisplayItems에 groupId 파라미터 추가하여 그룹별 설정 사용
- 설정 패널에서 그룹별로 displayItems 관리
- 각 그룹마다 다른 표시 형식 가능 (예: 거래처 정보 vs 단가 정보)
- 그룹의 필드만 선택 가능하도록 필터링
- DisplayItem 타입 추가 (icon, field, text, badge)
- 필드별 표시 형식 지원 (text, currency, number, date, badge)
- 빈 값 처리 옵션 추가 (hide, default, blank)
- 기본값 설정 기능 추가
- 스타일 옵션 추가 (굵게, 밑줄, 기울임, 색상)
- renderDisplayItems 헬퍼 함수로 유연한 표시 렌더링
- SelectedItemsDetailInputConfigPanel에 항목 표시 설정 UI 추가
- displayItems가 없으면 기존 방식(모든 필드 나열)으로 폴백
- handleAddGroupEntry: + 추가 버튼 클릭 시 미리 빈 entry를 배열에 추가
- handleFieldChange: 기존 entry 업데이트만 수행 (새로운 entry 추가 로직 제거)
- 이제 첫 글자 입력 시에도 배열 길이가 변하지 않아 포커스가 유지됨
- 입력 중 onFormDataChange 호출 제거하여 불필요한 리렌더링 방지
- 저장 버튼 클릭 시에만 데이터 전달하도록 변경 (beforeFormSave 이벤트)
- handleSave에서 beforeFormSave 이벤트 발생 및 100ms 대기
- 원본 데이터 표시 버그 수정 (modalData 중첩 구조 처리)
- fieldGroups 구조 감지 로직 수정 (details → fieldGroups)
이제 사용자가 타이핑할 때 포커스가 유지됩니다.
- 데이터 구조 변경: ItemData.details → ItemData.fieldGroups (그룹별 관리)
- 각 필드 그룹마다 독립적으로 여러 항목 추가/수정/삭제 가능
- renderFieldsByGroup: 그룹별 입력 항목 목록 + 편집 + 추가 버튼 구현
- renderGridLayout/renderCardLayout: 품목별 그룹 카드 표시로 단순화
- handleFieldChange: groupId 파라미터 추가 (itemId, groupId, entryId, fieldName, value)
- handleAddGroupEntry, handleRemoveGroupEntry, handleEditGroupEntry 핸들러 추가
- buttonActions handleBatchSave: fieldGroups 구조 처리하도록 수정
- 원본 데이터 표시 버그 수정: modalData의 중첩 구조 처리
사용 예:
- 품목 1
- 그룹 1 (거래처 정보): 3개 항목 입력 가능
- 그룹 2 (단가 정보): 5개 항목 입력 가능
- 각 항목 클릭 → 수정 가능
- 저장 시 모든 입력 항목이 개별 레코드로 저장됨
- Select 컴포넌트에서 빈 문자열 value를 가진 SelectItem 제거
- category/code 타입 필드의 옵션 로딩 디버깅 로그 추가
- 빈 값 필터링으로 'SelectItem must not have empty value' 에러 해결
- codeCategory 자동 감지 로직 디버깅 강화