feat: 게시판 댓글/답글 시스템 및 대시보드 개선

주요 변경사항:
- 게시판 계층형 댓글/답글 시스템 구현
  - DB: root_idx, depth, thread_path, is_comment, reply_count 컬럼 추가
  - 트리거: 댓글 개수 자동 업데이트
  - 답글(is_comment=false)은 목록에 표시, 댓글(is_comment=true)은 뷰어에만 표시
  - ESC 키로 모달 닫기 기능

- 업무일지 개선
  - 프로젝트 선택 시 최종 설정 자동 불러오기
  - 복사 시 jobgrp, tag 포함
  - 완료(보고) 상태 프로젝트도 검색 가능하도록 수정

- 대시보드 개선
  - 할일 목록 페이징 추가 (6개씩)
  - 할일에 요청자 정보 표시 (제목 좌측에 괄호로)
This commit is contained in:
backuppc
2025-12-03 10:10:29 +09:00
parent 3d53a5c42f
commit c1c615fe1b
86 changed files with 10612 additions and 36377 deletions

View File

@@ -118,6 +118,58 @@ export function JobreportEditModal({
}
}, [isOpen, loadCommonCodes]);
// 모달 열릴 때 프로젝트가 설정되어 있으면 자동으로 최종 설정 불러오기
useEffect(() => {
const loadLastSettings = async () => {
// 신규 등록이고, 프로젝트가 설정되어 있으며, 기본값이 비어있는 경우에만 자동 로드
if (isOpen && !editingItem && formData.pidx && formData.pidx > 0) {
// 이미 설정된 값이 있으면 자동 로드하지 않음 (복사 기능 등에서 이미 값이 있을 수 있음)
const hasExistingSettings = formData.requestpart || formData.package || formData.type || formData.process;
if (hasExistingSettings) {
setPreviousProjectIdx(formData.pidx);
return;
}
try {
const lastReport = await comms.getLastJobReportByProject(formData.pidx, formData.projectName);
if (lastReport.Success && lastReport.Data) {
const updatedFormData = { ...formData };
if (lastReport.Data.requestpart) {
updatedFormData.requestpart = lastReport.Data.requestpart;
}
if (lastReport.Data.package) {
updatedFormData.package = lastReport.Data.package;
}
if (lastReport.Data.type) {
updatedFormData.type = lastReport.Data.type;
}
if (lastReport.Data.jobgrp) {
updatedFormData.jobgrp = lastReport.Data.jobgrp;
}
if (lastReport.Data.process) {
updatedFormData.process = lastReport.Data.process;
}
if (lastReport.Data.status) {
updatedFormData.status = lastReport.Data.status;
}
onFormChange(updatedFormData);
}
setPreviousProjectIdx(formData.pidx);
} catch (error) {
console.error('최종 설정 불러오기 오류:', error);
setPreviousProjectIdx(formData.pidx);
}
} else if (isOpen && !editingItem) {
// 신규 등록인데 프로젝트가 없으면 초기화
setPreviousProjectIdx(null);
}
};
loadLastSettings();
}, [isOpen, editingItem]);
if (!isOpen) return null;
const handleFieldChange = <K extends keyof JobreportFormData>(