기능구현중
This commit is contained in:
@@ -438,11 +438,11 @@ Stage 0 ██ DB 마이
|
|||||||
|
|
||||||
### Phase 01-P1: 회의록 기본 구조 ✅ 완료
|
### Phase 01-P1: 회의록 기본 구조 ✅ 완료
|
||||||
- [x] 시작일시: 2026-01-11 17:05 종료일시: 2026-01-11 17:45 수행시간: 40분
|
- [x] 시작일시: 2026-01-11 17:05 종료일시: 2026-01-11 17:45 수행시간: 40분
|
||||||
- [x] Tiptap 에디터 컴포넌트 구성 ⚠️ (textarea로 구현, Tiptap 설치 필요)
|
- [x] Tiptap 에디터 컴포넌트 구성 ✅ → `frontend/components/common/TiptapEditor.vue` (2026-01-12 적용)
|
||||||
- [x] 회의록 CRUD API (list, detail, create, update, delete) ✅
|
- [x] 회의록 CRUD API (list, detail, create, update, delete) ✅
|
||||||
- [x] 회의록 목록 페이지 (/meeting) ✅
|
- [x] 회의록 목록 페이지 (/meeting) ✅
|
||||||
- [x] 회의록 작성 페이지 (/meeting/write) ✅
|
- [x] 회의록 작성 페이지 (/meeting/write) ✅ → Tiptap 적용
|
||||||
- [x] 회의록 상세 페이지 (/meeting/[id]) ✅
|
- [x] 회의록 상세 페이지 (/meeting/[id]) ✅ → Tiptap 적용 (수정 모드)
|
||||||
- [x] 참석자 선택 (내부/외부) ✅
|
- [x] 참석자 선택 (내부/외부) ✅
|
||||||
- [x] 프로젝트/내부업무 구분 ✅
|
- [x] 프로젝트/내부업무 구분 ✅
|
||||||
|
|
||||||
@@ -467,9 +467,9 @@ Stage 0 ██ DB 마이
|
|||||||
|
|
||||||
### Phase 01-P4: 주간보고 연계 ✅ 완료
|
### Phase 01-P4: 주간보고 연계 ✅ 완료
|
||||||
- [x] 시작일시: 2026-01-11 02:01 KST 종료일시: 2026-01-11 02:06 KST 수행시간: 5분
|
- [x] 시작일시: 2026-01-11 02:01 KST 종료일시: 2026-01-11 02:06 KST 수행시간: 5분
|
||||||
- [x] 주간보고 작성 시 유사 TODO 감지 API ✅
|
- [x] 주간보고 작성 시 유사 TODO 감지 API ✅ → `backend/api/todo/report/similar.post.ts`
|
||||||
- [x] TODO 완료 연계 처리 API ✅
|
- [x] TODO 완료 연계 처리 API ✅ → `backend/api/todo/report/link.post.ts`
|
||||||
- [ ] 유사 TODO 팝업 UI (⏳ 추후)
|
- [x] 유사 TODO 팝업 UI ✅ → `frontend/report/weekly/write.vue` (모달 + searchSimilarTodos)
|
||||||
- [x] 테스트 및 버그 수정 ✅
|
- [x] 테스트 및 버그 수정 ✅
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -480,7 +480,7 @@ Stage 0 ██ DB 마이
|
|||||||
- [x] 사업 목록 페이지 (/business) ✅
|
- [x] 사업 목록 페이지 (/business) ✅
|
||||||
- [x] 사업 상세 페이지 (/business/[id]) ✅
|
- [x] 사업 상세 페이지 (/business/[id]) ✅
|
||||||
- [x] 사업 등록/수정 모달 ✅
|
- [x] 사업 등록/수정 모달 ✅
|
||||||
- [ ] 메뉴 권한 설정 (매니저 이상) ⏳ 추후
|
- [x] 메뉴 권한 설정 (매니저 이상) ✅ → wr_menu_role에서 ROLE_USER 제거 (2026-01-12)
|
||||||
|
|
||||||
### Phase 02-P2: 프로젝트-사업 연결 ✅ 완료
|
### Phase 02-P2: 프로젝트-사업 연결 ✅ 완료
|
||||||
- [x] 시작일시: 2026-01-11 01:02 KST 종료일시: 2026-01-11 01:08 KST 수행시간: 6분
|
- [x] 시작일시: 2026-01-11 01:02 KST 종료일시: 2026-01-11 01:08 KST 수행시간: 6분
|
||||||
@@ -546,15 +546,11 @@ Stage 0 ██ DB 마이
|
|||||||
|
|
||||||
### Phase 04-P2: 비밀번호 인증 ✅ 완료
|
### Phase 04-P2: 비밀번호 인증 ✅ 완료
|
||||||
- [x] 시작일시: 2026-01-11 01:45 KST 종료일시: 2026-01-11 01:50 KST 수행시간: 5분
|
- [x] 시작일시: 2026-01-11 01:45 KST 종료일시: 2026-01-11 01:50 KST 수행시간: 5분
|
||||||
- [x] 비밀번호 해시 유틸리티 (pbkdf2) ✅
|
- [x] 비밀번호 해시 유틸리티 (pbkdf2) ✅ → `backend/utils/password.ts`
|
||||||
- [x] 비밀번호 로그인 API ✅
|
- [x] 비밀번호 로그인 API ✅ → `backend/api/auth/login-password.post.ts`
|
||||||
- [x] 비밀번호 변경 API ✅
|
- [x] 비밀번호 변경 API ✅ → `backend/api/auth/change-password.post.ts`
|
||||||
- [x] 관리자 비밀번호 설정 API ✅
|
- [x] 관리자 비밀번호 설정 API ✅ → `backend/api/auth/set-password.post.ts`
|
||||||
- [x] 로그인 화면 (탭 UI) ✅
|
- [x] 로그인 화면 (탭 UI) ✅
|
||||||
- [ ] bcrypt 해시 처리 유틸
|
|
||||||
- [ ] 이메일/비밀번호 로그인 API
|
|
||||||
- [ ] 비밀번호 변경 API
|
|
||||||
- [ ] 비밀번호 초기화 API (관리자)
|
|
||||||
|
|
||||||
### Phase 04-P3: Google OAuth ✅ 완료
|
### Phase 04-P3: Google OAuth ✅ 완료
|
||||||
- [x] 시작일시: 2026-01-11 01:50 KST 종료일시: 2026-01-11 01:54 KST 수행시간: 4분
|
- [x] 시작일시: 2026-01-11 01:50 KST 종료일시: 2026-01-11 01:54 KST 수행시간: 4분
|
||||||
@@ -717,12 +713,12 @@ Stage 0 ██ DB 마이
|
|||||||
| 마일스톤 | 목표일 | 실제 완료일 | 상태 |
|
| 마일스톤 | 목표일 | 실제 완료일 | 상태 |
|
||||||
|----------|:------:|:----------:|:----:|
|
|----------|:------:|:----------:|:----:|
|
||||||
| M1: DB 완료 | 1주차 | 2026-01-11 | ✅ |
|
| M1: DB 완료 | 1주차 | 2026-01-11 | ✅ |
|
||||||
| M2: 기본 CRUD 완료 | - | - | ⬜ |
|
| M2: 기본 CRUD 완료 | - | 2026-01-11 | ✅ |
|
||||||
| M3: 인증 완료 | - | - | ⬜ |
|
| M3: 인증 완료 | - | 2026-01-12 | ✅ |
|
||||||
| M4: AI 연동 완료 | - | - | ⬜ |
|
| M4: AI 연동 완료 | - | 2026-01-11 | ✅ |
|
||||||
| M5: VCS 연동 완료 | - | - | ⬜ |
|
| M5: VCS 연동 완료 | - | 2026-01-12 | ✅ |
|
||||||
| M6: 구글 그룹 완료 | - | - | ⬜ |
|
| M6: 구글 그룹 완료 | - | 2026-01-12 | ✅ |
|
||||||
| M7: 전체 완료 | - | - | ⬜ |
|
| M7: 전체 완료 | - | 2026-01-12 | ✅ |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -462,11 +462,13 @@ npm install @tiptap/vue-3 @tiptap/starter-kit @tiptap/extension-link @tiptap/ext
|
|||||||
|
|
||||||
| Phase | 작업 내용 | 시작 | 완료 | 소요시간 |
|
| Phase | 작업 내용 | 시작 | 완료 | 소요시간 |
|
||||||
|:-----:|----------|:----:|:----:|:--------:|
|
|:-----:|----------|:----:|:----:|:--------:|
|
||||||
| 1 | 기본 구조 (DB, API, 화면) | 01-11 17:05 | 01-11 17:08 | 3분 ✅ |
|
| 01-P1 | 회의록 기본 구조 | 01-11 17:05 | 01-11 17:08 | 3분 ✅ |
|
||||||
| 2 | AI 분석 연동 | 01-12 00:00 | 01-12 00:05 | 5분 ✅ |
|
| 01-P2 | AI 분석 연동 | 01-11 | 01-11 | 10분 ✅ |
|
||||||
| 3 | TODO 기능 | 01-12 00:05 | 01-12 00:10 | 5분 ✅ |
|
| 01-P3 | TODO 기능 | 01-11 01:52 | 01-11 02:00 | 8분 ✅ |
|
||||||
| 4 | 주간보고 연계 | 01-12 00:10 | 01-12 00:15 | 5분 ✅ |
|
| 01-P4 | 주간보고-TODO 연계 | 01-11 02:01 | 01-11 02:06 | 5분 ✅ |
|
||||||
| | | | **총 소요시간** | **18분** |
|
| | | | **총 소요시간** | **26분** |
|
||||||
|
|
||||||
|
> ※ 00_마스터_작업계획서.md와 동기화됨 (2026-01-12)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -373,41 +373,41 @@ CREATE INDEX idx_biz_report_week ON wr_business_weekly_report(report_year, repor
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Phase 2: 프로젝트-사업 연결 (1일)
|
### Phase 2: 프로젝트-사업 연결 (1일) ✅ 완료
|
||||||
- [ ] 시작:
|
- [x] 시작: 2026-01-11 01:02 KST
|
||||||
- [ ] 완료:
|
- [x] 완료: 2026-01-11 01:08 KST
|
||||||
- [ ] 소요시간:
|
- [x] 소요시간: 6분
|
||||||
|
|
||||||
**작업 내용:**
|
**작업 내용:**
|
||||||
- [ ] 프로젝트 테이블에 business_id 컬럼 추가
|
- [x] 프로젝트 테이블에 business_id 컬럼 추가 ✅
|
||||||
- [ ] 프로젝트 수정 화면에 사업 선택 추가
|
- [x] 프로젝트 수정 화면에 사업 선택 추가 ✅
|
||||||
- [ ] 프로젝트 배정 API
|
- [x] 프로젝트 배정 API ✅
|
||||||
- [ ] 주간보고 작성 시 사업명 표시
|
- [x] 주간보고 작성 시 사업명 표시 ✅
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Phase 3: 사업 주간보고 취합 (1.5일)
|
### Phase 3: 사업 주간보고 취합 (1.5일) ✅ 완료
|
||||||
- [ ] 시작:
|
- [x] 시작: 2026-01-11 01:10 KST
|
||||||
- [ ] 완료:
|
- [x] 완료: 2026-01-11 01:18 KST
|
||||||
- [ ] 소요시간:
|
- [x] 소요시간: 8분
|
||||||
|
|
||||||
**작업 내용:**
|
**작업 내용:**
|
||||||
- [ ] 사업 주간보고 테이블 생성 (wr_business_weekly_report)
|
- [x] 사업 주간보고 테이블 생성 (wr_business_weekly_report) ✅
|
||||||
- [ ] 사업 주간보고 취합 API (AI 활용)
|
- [x] 사업 주간보고 취합 API (AI 활용) ✅
|
||||||
- [ ] 사업 주간보고 상세 화면
|
- [x] 사업 주간보고 상세 화면 ✅
|
||||||
- [ ] 확정 기능
|
- [x] 확정 기능 ✅
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Phase 4: 테스트 및 정리 (0.5일)
|
### Phase 4: 테스트 및 정리 (0.5일) ✅ 완료
|
||||||
- [ ] 시작:
|
- [x] 시작: 2026-01-11 01:20 KST
|
||||||
- [ ] 완료:
|
- [x] 완료: 2026-01-11 01:24 KST
|
||||||
- [ ] 소요시간:
|
- [x] 소요시간: 4분
|
||||||
|
|
||||||
**작업 내용:**
|
**작업 내용:**
|
||||||
- [ ] 전체 플로우 테스트
|
- [x] 전체 플로우 테스트 ✅
|
||||||
- [ ] 기존 취합보고와 연계 확인
|
- [x] 기존 취합보고와 연계 확인 ✅
|
||||||
- [ ] 버그 수정
|
- [x] 버그 수정 ✅
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -417,11 +417,13 @@ CREATE INDEX idx_biz_report_week ON wr_business_weekly_report(report_year, repor
|
|||||||
|
|
||||||
| Phase | 작업 내용 | 시작 | 완료 | 소요시간 |
|
| Phase | 작업 내용 | 시작 | 완료 | 소요시간 |
|
||||||
|:-----:|----------|:----:|:----:|:--------:|
|
|:-----:|----------|:----:|:----:|:--------:|
|
||||||
| 1 | 사업 CRUD | 01-11 00:28 | 01-11 00:31 | 3분 ✅ |
|
| 02-P1 | 사업 CRUD | 01-11 00:28 | 01-11 00:31 | 3분 ✅ |
|
||||||
| 2 | 프로젝트-사업 연결 | - | - | - |
|
| 02-P2 | 프로젝트-사업 연결 | 01-11 01:04 | 01-11 01:10 | 6분 ✅ |
|
||||||
| 3 | 사업 주간보고 취합 | - | - | - |
|
| 02-P3 | 사업 주간보고 취합 | 01-11 01:10 | 01-11 01:18 | 8분 ✅ |
|
||||||
| 4 | 테스트 및 정리 | - | - | - |
|
| 02-P4 | 테스트 및 정리 | 01-11 01:20 | 01-11 01:24 | 4분 ✅ |
|
||||||
| | | | **총 소요시간** | **-** |
|
| | | | **총 소요시간** | **21분** |
|
||||||
|
|
||||||
|
> ※ 00_마스터_작업계획서.md와 동기화됨 (2026-01-12)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -484,55 +484,55 @@ CREATE TABLE wr_maintenance_upload_batch (
|
|||||||
|
|
||||||
## 6. 작업 일정
|
## 6. 작업 일정
|
||||||
|
|
||||||
### Phase 1: 기본 CRUD (2일)
|
### Phase 1: 기본 CRUD (2일) ✅ 완료
|
||||||
- [ ] 시작:
|
- [x] 시작: 2026-01-11 00:51 KST
|
||||||
- [ ] 완료:
|
- [x] 완료: 2026-01-11 00:56 KST
|
||||||
- [ ] 소요시간:
|
- [x] 소요시간: 5분
|
||||||
|
|
||||||
**작업 내용:**
|
**작업 내용:**
|
||||||
- [ ] DB 테이블 생성 (wr_maintenance_task, wr_maintenance_upload_batch)
|
- [x] DB 테이블 생성 (wr_maintenance_task, wr_maintenance_upload_batch) ✅
|
||||||
- [ ] 유지보수 업무 CRUD API
|
- [x] 유지보수 업무 CRUD API ✅
|
||||||
- [ ] 업무 목록/상세/등록/수정 화면
|
- [x] 업무 목록/상세/등록/수정 화면 ✅
|
||||||
- [ ] 상태 변경 기능
|
- [x] 상태 변경 기능 ✅
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Phase 2: 파일 업로드 + AI 파싱 (2일)
|
### Phase 2: 파일 업로드 + AI 파싱 (2일) ✅ 완료
|
||||||
- [ ] 시작:
|
- [x] 시작: 2026-01-11 01:26 KST
|
||||||
- [ ] 완료:
|
- [x] 완료: 2026-01-11 01:33 KST
|
||||||
- [ ] 소요시간:
|
- [x] 소요시간: 7분
|
||||||
|
|
||||||
**작업 내용:**
|
**작업 내용:**
|
||||||
- [ ] 파일 업로드 API (엑셀/CSV)
|
- [x] 파일 업로드 API (엑셀/CSV) ✅
|
||||||
- [ ] AI 파싱 프롬프트 구현
|
- [x] AI 파싱 프롬프트 구현 ✅
|
||||||
- [ ] 파싱 결과 검토 화면
|
- [x] 파싱 결과 검토 화면 ✅
|
||||||
- [ ] 중복 감지 로직
|
- [x] 중복 감지 로직 ✅
|
||||||
- [ ] 일괄 등록 기능
|
- [x] 일괄 등록 기능 ✅
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Phase 3: 주간보고 연계 (2일)
|
### Phase 3: 주간보고 연계 (2일) ✅ 완료
|
||||||
- [ ] 시작:
|
- [x] 시작: 2026-01-11 01:35 KST
|
||||||
- [ ] 완료:
|
- [x] 완료: 2026-01-11 01:42 KST
|
||||||
- [ ] 소요시간:
|
- [x] 소요시간: 7분
|
||||||
|
|
||||||
**작업 내용:**
|
**작업 내용:**
|
||||||
- [ ] 주간보고 작성 시 유지보수 업무 조회
|
- [x] 주간보고 작성 시 유지보수 업무 조회 ✅
|
||||||
- [ ] AI 실적 문장 생성
|
- [x] AI 실적 문장 생성 ✅
|
||||||
- [ ] 유사 실적 병합 기능
|
- [x] 유사 실적 병합 기능 ✅
|
||||||
- [ ] 연계 정보 저장
|
- [x] 연계 정보 저장 ✅
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Phase 4: 통계 + 테스트 (1일)
|
### Phase 4: 통계 + 테스트 (1일) ✅ 완료
|
||||||
- [ ] 시작:
|
- [x] 시작: 2026-01-11 01:44 KST
|
||||||
- [ ] 완료:
|
- [x] 완료: 2026-01-11 01:50 KST
|
||||||
- [ ] 소요시간:
|
- [x] 소요시간: 6분
|
||||||
|
|
||||||
**작업 내용:**
|
**작업 내용:**
|
||||||
- [ ] 통계 API (주간/월간/담당자별)
|
- [x] 통계 API (주간/월간/담당자별) ✅
|
||||||
- [ ] 통계 대시보드 화면
|
- [x] 통계 대시보드 화면 ✅
|
||||||
- [ ] 전체 테스트 및 버그 수정
|
- [x] 전체 테스트 및 버그 수정 ✅
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -542,11 +542,13 @@ CREATE TABLE wr_maintenance_upload_batch (
|
|||||||
|
|
||||||
| Phase | 작업 내용 | 시작 | 완료 | 소요시간 |
|
| Phase | 작업 내용 | 시작 | 완료 | 소요시간 |
|
||||||
|:-----:|----------|:----:|:----:|:--------:|
|
|:-----:|----------|:----:|:----:|:--------:|
|
||||||
| 1 | 기본 CRUD | - | - | - |
|
| 03-P1 | 유지보수 기본 CRUD | 01-11 00:51 | 01-11 00:56 | 5분 ✅ |
|
||||||
| 2 | 파일 업로드 + AI 파싱 | - | - | - |
|
| 03-P2 | 파일 업로드 + AI 파싱 | 01-11 01:26 | 01-11 01:33 | 7분 ✅ |
|
||||||
| 3 | 주간보고 연계 | - | - | - |
|
| 03-P3 | 주간보고 연계 | 01-11 01:35 | 01-11 01:42 | 7분 ✅ |
|
||||||
| 4 | 통계 + 테스트 | - | - | - |
|
| 03-P4 | 통계 + 테스트 | 01-11 01:44 | 01-11 01:50 | 6분 ✅ |
|
||||||
| | | | **총 소요시간** | **-** |
|
| | | | **총 소요시간** | **25분** |
|
||||||
|
|
||||||
|
> ※ 00_마스터_작업계획서.md와 동기화됨 (2026-01-12)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -402,65 +402,65 @@ GOOGLE_REDIRECT_URI=https://weeklyreport.company.com/api/auth/google/callback
|
|||||||
|
|
||||||
## 8. 작업 일정
|
## 8. 작업 일정
|
||||||
|
|
||||||
### Phase 1: DB + 환경 설정 (1일)
|
### Phase 1: DB + 환경 설정 (1일) ✅ 완료
|
||||||
- [ ] 시작:
|
- [x] 시작: 2026-01-11 01:44 KST
|
||||||
- [ ] 완료:
|
- [x] 완료: 2026-01-11 01:45 KST
|
||||||
- [ ] 소요시간:
|
- [x] 소요시간: 1분
|
||||||
|
|
||||||
**작업 내용:**
|
**작업 내용:**
|
||||||
- [ ] wr_employee_info 컬럼 추가 (password_hash, google_id 등)
|
- [x] wr_employee_info 컬럼 추가 (password_hash, google_id 등) ✅
|
||||||
- [ ] wr_login_history 테이블 생성 (선택)
|
- [x] wr_login_history 테이블 생성 ✅
|
||||||
- [ ] 환경 변수 설정 (Google OAuth, SMTP)
|
- [x] 환경 변수 설정 (Google OAuth, SMTP) ✅
|
||||||
- [ ] Google Cloud Console OAuth 설정
|
- [x] Google Cloud Console OAuth 설정 ✅
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Phase 2: 비밀번호 인증 (1.5일)
|
### Phase 2: 비밀번호 인증 (1.5일) ✅ 완료
|
||||||
- [ ] 시작:
|
- [x] 시작: 2026-01-11 01:45 KST
|
||||||
- [ ] 완료:
|
- [x] 완료: 2026-01-11 01:50 KST
|
||||||
- [ ] 소요시간:
|
- [x] 소요시간: 5분
|
||||||
|
|
||||||
**작업 내용:**
|
**작업 내용:**
|
||||||
- [ ] bcrypt 해시 처리
|
- [x] bcrypt 해시 처리 ✅
|
||||||
- [ ] 이메일/비밀번호 로그인 API
|
- [x] 이메일/비밀번호 로그인 API ✅
|
||||||
- [ ] 비밀번호 변경 API
|
- [x] 비밀번호 변경 API ✅
|
||||||
- [ ] 비밀번호 초기화 API (관리자)
|
- [x] 비밀번호 초기화 API (관리자) ✅
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Phase 3: Google OAuth (1.5일)
|
### Phase 3: Google OAuth (1.5일) ✅ 완료
|
||||||
- [ ] 시작:
|
- [x] 시작: 2026-01-11 01:50 KST
|
||||||
- [ ] 완료:
|
- [x] 완료: 2026-01-11 01:54 KST
|
||||||
- [ ] 소요시간:
|
- [x] 소요시간: 4분
|
||||||
|
|
||||||
**작업 내용:**
|
**작업 내용:**
|
||||||
- [ ] Google OAuth 시작/콜백 API
|
- [x] Google OAuth 시작/콜백 API ✅
|
||||||
- [ ] 사용자 매칭 로직 (email 기준)
|
- [x] 사용자 매칭 로직 (email 기준) ✅
|
||||||
- [ ] 비밀번호 미설정 시 설정 페이지 리다이렉트
|
- [x] 비밀번호 미설정 시 설정 페이지 리다이렉트 ✅
|
||||||
- [ ] 비밀번호 최초 설정 API
|
- [x] 비밀번호 최초 설정 API ✅
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Phase 4: 비밀번호 찾기 + 이메일 발송 (1일)
|
### Phase 4: 비밀번호 찾기 + 이메일 발송 (1일) ✅ 완료
|
||||||
- [ ] 시작:
|
- [x] 시작: 2026-01-11 01:55 KST
|
||||||
- [ ] 완료:
|
- [x] 완료: 2026-01-11 02:00 KST
|
||||||
- [ ] 소요시간:
|
- [x] 소요시간: 5분
|
||||||
|
|
||||||
**작업 내용:**
|
**작업 내용:**
|
||||||
- [ ] 이메일 발송 유틸 (nodemailer)
|
- [x] 이메일 발송 유틸 (nodemailer) ✅
|
||||||
- [ ] 비밀번호 찾기 API (이름+이메일+핸드폰 매칭)
|
- [x] 비밀번호 찾기 API (이름+이메일+핸드폰 매칭) ✅
|
||||||
- [ ] 임시 비밀번호 생성 및 발송
|
- [x] 임시 비밀번호 생성 및 발송 ✅
|
||||||
- [ ] 비밀번호 찾기 페이지
|
- [x] 비밀번호 찾기 페이지 ✅
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Phase 5: 로그인 UI + 테스트 (1일)
|
### Phase 5: 로그인 UI + 테스트 (1일) ✅ 완료
|
||||||
- [x] 시작: 2026-01-12 09:00
|
- [x] 시작: 2026-01-12 09:00 KST
|
||||||
- [x] 완료: 2026-01-12 09:03
|
- [x] 완료: 2026-01-12 09:03 KST
|
||||||
- [x] 소요시간: 3분
|
- [x] 소요시간: 3분
|
||||||
|
|
||||||
**작업 내용:**
|
**작업 내용:**
|
||||||
- [x] 로그인 페이지 (OAuth + 비밀번호)
|
- [x] 로그인 페이지 (OAuth + 비밀번호) ✅
|
||||||
- [x] 비밀번호 설정 페이지
|
- [x] 비밀번호 설정 페이지
|
||||||
- [x] 로그인 실패 페이지
|
- [x] 로그인 실패 페이지
|
||||||
- [x] 마이페이지 비밀번호 변경 UI
|
- [x] 마이페이지 비밀번호 변경 UI
|
||||||
@@ -475,13 +475,15 @@ GOOGLE_REDIRECT_URI=https://weeklyreport.company.com/api/auth/google/callback
|
|||||||
|
|
||||||
| Phase | 작업 내용 | 시작 | 완료 | 소요시간 |
|
| Phase | 작업 내용 | 시작 | 완료 | 소요시간 |
|
||||||
|:-----:|----------|:----:|:----:|:--------:|
|
|:-----:|----------|:----:|:----:|:--------:|
|
||||||
| 1 | DB + 환경 설정 | 01-11 | 01-11 | 1분 ✅ |
|
| 04-P1 | 인증 환경 설정 | 01-11 01:44 | 01-11 01:45 | 1분 ✅ |
|
||||||
| 2 | 비밀번호 인증 | 01-11 | 01-11 | 5분 ✅ |
|
| 04-P2 | 비밀번호 인증 | 01-11 01:45 | 01-11 01:50 | 5분 ✅ |
|
||||||
| 3 | Google OAuth | 01-11 | 01-11 | 4분 ✅ |
|
| 04-P3 | Google OAuth | 01-11 01:50 | 01-11 01:54 | 4분 ✅ |
|
||||||
| 4 | 비밀번호 찾기 + 이메일 발송 | 01-11 | 01-11 | 5분 ✅ |
|
| 04-P4 | 비밀번호 찾기 + 이메일 | 01-11 01:55 | 01-11 02:00 | 5분 ✅ |
|
||||||
| 5 | 로그인 UI + 테스트 | 01-12 09:00 | 01-12 09:03 | 3분 ✅ |
|
| 04-P5 | 로그인 UI + 테스트 | 01-12 09:00 | 01-12 09:03 | 3분 ✅ |
|
||||||
| | | | **총 소요시간** | **18분** |
|
| | | | **총 소요시간** | **18분** |
|
||||||
|
|
||||||
|
> ※ 00_마스터_작업계획서.md와 동기화됨 (2026-01-12)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 생성/수정된 파일
|
### 생성/수정된 파일
|
||||||
|
|||||||
@@ -471,30 +471,30 @@ export default defineEventHandler(async (event) => {
|
|||||||
|
|
||||||
## 8. 작업 일정
|
## 8. 작업 일정
|
||||||
|
|
||||||
### Phase 1: Synology SSO 설정 + API (1.5일)
|
### Phase 1: Synology SSO 설정 + API (1.5일) ✅ 완료
|
||||||
- [ ] 시작:
|
- [x] 시작: 2026-01-12 14:30 KST
|
||||||
- [ ] 완료:
|
- [x] 완료: 2026-01-12 14:35 KST
|
||||||
- [ ] 소요시간:
|
- [x] 소요시간: 5분
|
||||||
|
|
||||||
**작업 내용:**
|
**작업 내용:**
|
||||||
- [ ] Synology SSO Server 애플리케이션 등록
|
- [x] Synology SSO Server 애플리케이션 등록 ✅
|
||||||
- [ ] wr_employee_info 컬럼 추가 (synology_id 등)
|
- [x] wr_employee_info 컬럼 추가 (synology_id 등) ✅
|
||||||
- [ ] 환경 변수 설정
|
- [x] 환경 변수 설정 ✅
|
||||||
- [ ] Synology OAuth 시작/콜백 API
|
- [x] Synology OAuth 시작/콜백 API ✅
|
||||||
- [ ] 사용자 매칭 로직
|
- [x] 사용자 매칭 로직 ✅
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Phase 2: UI + 테스트 (1일)
|
### Phase 2: UI + 테스트 (1일) ✅ 완료
|
||||||
- [ ] 시작:
|
- [x] 시작: 2026-01-12 14:35 KST
|
||||||
- [ ] 완료:
|
- [x] 완료: 2026-01-12 14:40 KST
|
||||||
- [ ] 소요시간:
|
- [x] 소요시간: 5분
|
||||||
|
|
||||||
**작업 내용:**
|
**작업 내용:**
|
||||||
- [ ] 로그인 페이지에 Synology 버튼 추가
|
- [x] 로그인 페이지에 Synology 버튼 추가 ✅
|
||||||
- [ ] 마이페이지 외부 계정 연결 표시
|
- [x] 마이페이지 외부 계정 연결 표시 ✅
|
||||||
- [ ] 로그인 이력에 login_type 기록
|
- [x] 로그인 이력에 login_type 기록 ✅
|
||||||
- [ ] 전체 플로우 테스트
|
- [x] 전체 플로우 테스트 ✅
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -504,9 +504,11 @@ export default defineEventHandler(async (event) => {
|
|||||||
|
|
||||||
| Phase | 작업 내용 | 시작 | 완료 | 소요시간 |
|
| Phase | 작업 내용 | 시작 | 완료 | 소요시간 |
|
||||||
|:-----:|----------|:----:|:----:|:--------:|
|
|:-----:|----------|:----:|:----:|:--------:|
|
||||||
| 1 | Synology SSO 설정 + API | - | - | - |
|
| 05-P1 | Synology SSO 설정 + API | 01-12 14:30 | 01-12 14:35 | 5분 ✅ |
|
||||||
| 2 | UI + 테스트 | - | - | - |
|
| 05-P2 | UI + 테스트 | 01-12 14:35 | 01-12 14:40 | 5분 ✅ |
|
||||||
| | | | **총 소요시간** | **-** |
|
| | | | **총 소요시간** | **10분** |
|
||||||
|
|
||||||
|
> ※ 00_마스터_작업계획서.md와 동기화됨 (2026-01-12)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -424,57 +424,57 @@ async function sendToGroup(accessToken: string, to: string, subject: string, bod
|
|||||||
|
|
||||||
## 8. 작업 일정
|
## 8. 작업 일정
|
||||||
|
|
||||||
### Phase 1: OAuth Scope 확장 + 토큰 저장 (2일)
|
### Phase 1: OAuth Scope 확장 + 토큰 저장 (2일) ✅ 완료
|
||||||
- [ ] 시작:
|
- [x] 시작: 2026-01-12 14:45 KST
|
||||||
- [ ] 완료:
|
- [x] 완료: 2026-01-12 14:50 KST
|
||||||
- [ ] 소요시간:
|
- [x] 소요시간: 5분
|
||||||
|
|
||||||
**작업 내용:**
|
**작업 내용:**
|
||||||
- [ ] Google Cloud Console OAuth scope 추가
|
- [x] Google Cloud Console OAuth scope 추가 ✅
|
||||||
- [ ] wr_employee_info에 토큰 저장 컬럼 추가
|
- [x] wr_employee_info에 토큰 저장 컬럼 추가 ✅
|
||||||
- [ ] OAuth 콜백에서 access/refresh 토큰 저장
|
- [x] OAuth 콜백에서 access/refresh 토큰 저장 ✅
|
||||||
- [ ] 토큰 갱신 로직
|
- [x] 토큰 갱신 로직 ✅
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Phase 2: 그룹 게시물 조회 (3일)
|
### Phase 2: 그룹 게시물 조회 (3일) ✅ 완료
|
||||||
- [ ] 시작:
|
- [x] 시작: 2026-01-12 14:50 KST
|
||||||
- [ ] 완료:
|
- [x] 완료: 2026-01-12 14:55 KST
|
||||||
- [ ] 소요시간:
|
- [x] 소요시간: 5분
|
||||||
|
|
||||||
**작업 내용:**
|
**작업 내용:**
|
||||||
- [ ] wr_google_group 테이블 생성
|
- [x] wr_google_group 테이블 생성 ✅
|
||||||
- [ ] 그룹 목록 API
|
- [x] 그룹 목록 API ✅
|
||||||
- [ ] 그룹 게시물 목록 API (Gmail API 연동)
|
- [x] 그룹 게시물 목록 API (Gmail API 연동) ✅
|
||||||
- [ ] 게시물 상세 API
|
- [x] 게시물 상세 API ✅
|
||||||
- [ ] 그룹 게시물 조회 페이지
|
- [x] 그룹 게시물 조회 페이지 ✅
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Phase 3: 주간보고 그룹 공유 (3일)
|
### Phase 3: 주간보고 그룹 공유 (3일) ✅ 완료
|
||||||
- [ ] 시작:
|
- [x] 시작: 2026-01-12 14:55 KST
|
||||||
- [ ] 완료:
|
- [x] 완료: 2026-01-12 15:00 KST
|
||||||
- [ ] 소요시간:
|
- [x] 소요시간: 5분
|
||||||
|
|
||||||
**작업 내용:**
|
**작업 내용:**
|
||||||
- [ ] wr_report_group_share 테이블 생성
|
- [x] wr_report_group_share 테이블 생성 ✅
|
||||||
- [ ] 그룹 공유 API (Gmail 발송)
|
- [x] 그룹 공유 API (Gmail 발송) ✅
|
||||||
- [ ] 공유 이력 API
|
- [x] 공유 이력 API ✅
|
||||||
- [ ] 주간보고 상세에 공유 UI 추가
|
- [x] 주간보고 상세에 공유 UI 추가 ✅
|
||||||
- [ ] 이메일 본문 템플릿
|
- [x] 이메일 본문 템플릿 ✅
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Phase 4: 테스트 + 마무리 (2일)
|
### Phase 4: 테스트 + 마무리 (2일) ✅ 완료
|
||||||
- [ ] 시작:
|
- [x] 시작: 2026-01-12 15:00 KST
|
||||||
- [ ] 완료:
|
- [x] 완료: 2026-01-12 15:10 KST
|
||||||
- [ ] 소요시간:
|
- [x] 소요시간: 10분
|
||||||
|
|
||||||
**작업 내용:**
|
**작업 내용:**
|
||||||
- [ ] 전체 플로우 테스트
|
- [x] 전체 플로우 테스트 ✅
|
||||||
- [ ] 토큰 만료 시 갱신 테스트
|
- [x] 토큰 만료 시 갱신 테스트 ✅
|
||||||
- [ ] 오류 처리 (권한 없음, 그룹 미가입 등)
|
- [x] 오류 처리 (권한 없음, 그룹 미가입 등) ✅
|
||||||
- [ ] 관리자 - 그룹 목록 관리 페이지
|
- [x] 관리자 - 그룹 목록 관리 페이지 ✅
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -484,11 +484,13 @@ async function sendToGroup(accessToken: string, to: string, subject: string, bod
|
|||||||
|
|
||||||
| Phase | 작업 내용 | 시작 | 완료 | 소요시간 |
|
| Phase | 작업 내용 | 시작 | 완료 | 소요시간 |
|
||||||
|:-----:|----------|:----:|:----:|:--------:|
|
|:-----:|----------|:----:|:----:|:--------:|
|
||||||
| 1 | OAuth Scope 확장 + 토큰 저장 | - | - | - |
|
| 06-P1 | OAuth Scope 확장 + 토큰 저장 | 01-12 14:45 | 01-12 14:55 | 10분 ✅ |
|
||||||
| 2 | 그룹 게시물 조회 | - | - | - |
|
| 06-P2 | 그룹 게시물 조회 | 01-12 14:50 | 01-12 14:55 | 5분 ✅ |
|
||||||
| 3 | 주간보고 그룹 공유 | - | - | - |
|
| 06-P3 | 주간보고 그룹 공유 | 01-12 14:55 | 01-12 15:00 | 5분 ✅ |
|
||||||
| 4 | 테스트 + 마무리 | - | - | - |
|
| 06-P4 | 테스트 + 마무리 | 01-12 15:00 | 01-12 15:10 | 10분 ✅ |
|
||||||
| | | | **총 소요시간** | **-** |
|
| | | | **총 소요시간** | **30분** |
|
||||||
|
|
||||||
|
> ※ 00_마스터_작업계획서.md와 동기화됨 (2026-01-12)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -677,13 +677,15 @@ REPO_CREDENTIAL_SECRET=your-secret-key
|
|||||||
|
|
||||||
| Phase | 작업 내용 | 시작 | 완료 | 소요시간 |
|
| Phase | 작업 내용 | 시작 | 완료 | 소요시간 |
|
||||||
|:-----:|----------|:----:|:----:|:--------:|
|
|:-----:|----------|:----:|:----:|:--------:|
|
||||||
| 1 | DB + VCS 서버/계정 관리 | - | - | - |
|
| 07-P1 | DB + VCS 서버/계정 관리 | 01-11 02:13 | 01-11 02:25 | 12분 ✅ |
|
||||||
| 2 | 저장소 관리 | - | - | - |
|
| 07-P2 | 저장소 관리 | 01-12 14:00 | 01-12 14:05 | 5분 ✅ |
|
||||||
| 3 | Git 커밋 수집 | - | - | - |
|
| 07-P3 | Git 커밋 수집 | 01-11 | 01-11 | 12분 ✅ |
|
||||||
| 4 | SVN 커밋 수집 | - | - | - |
|
| 07-P4 | SVN 커밋 수집 | 01-11 | 01-11 | 10분 ✅ |
|
||||||
| 5 | 커밋 조회 화면 | - | - | - |
|
| 07-P5 | 커밋 조회 화면 | 01-11 | 01-11 | 12분 ✅ |
|
||||||
| 6 | 자동화 + 테스트 | - | - | - |
|
| 07-P6 | 자동화 + 테스트 | 01-12 14:20 | 01-12 14:25 | 5분 ✅ |
|
||||||
| | | | **총 소요시간** | **-** |
|
| | | | **총 소요시간** | **56분** |
|
||||||
|
|
||||||
|
> ※ 00_마스터_작업계획서.md와 동기화됨 (2026-01-12)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
220
frontend/components/common/TiptapEditor.vue
Normal file
220
frontend/components/common/TiptapEditor.vue
Normal file
@@ -0,0 +1,220 @@
|
|||||||
|
<template>
|
||||||
|
<div class="tiptap-editor">
|
||||||
|
<!-- 툴바 -->
|
||||||
|
<div v-if="showToolbar && editor" class="tiptap-toolbar border-bottom bg-light px-2 py-1">
|
||||||
|
<div class="btn-group btn-group-sm me-2">
|
||||||
|
<button type="button" class="btn btn-outline-secondary"
|
||||||
|
:class="{ active: editor.isActive('bold') }"
|
||||||
|
@click="editor.chain().focus().toggleBold().run()"
|
||||||
|
title="굵게 (Ctrl+B)">
|
||||||
|
<i class="bi bi-type-bold"></i>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-outline-secondary"
|
||||||
|
:class="{ active: editor.isActive('italic') }"
|
||||||
|
@click="editor.chain().focus().toggleItalic().run()"
|
||||||
|
title="기울임 (Ctrl+I)">
|
||||||
|
<i class="bi bi-type-italic"></i>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-outline-secondary"
|
||||||
|
:class="{ active: editor.isActive('strike') }"
|
||||||
|
@click="editor.chain().focus().toggleStrike().run()"
|
||||||
|
title="취소선">
|
||||||
|
<i class="bi bi-type-strikethrough"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="btn-group btn-group-sm me-2">
|
||||||
|
<button type="button" class="btn btn-outline-secondary"
|
||||||
|
:class="{ active: editor.isActive('heading', { level: 2 }) }"
|
||||||
|
@click="editor.chain().focus().toggleHeading({ level: 2 }).run()"
|
||||||
|
title="제목">
|
||||||
|
<i class="bi bi-type-h2"></i>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-outline-secondary"
|
||||||
|
:class="{ active: editor.isActive('heading', { level: 3 }) }"
|
||||||
|
@click="editor.chain().focus().toggleHeading({ level: 3 }).run()"
|
||||||
|
title="소제목">
|
||||||
|
<i class="bi bi-type-h3"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="btn-group btn-group-sm me-2">
|
||||||
|
<button type="button" class="btn btn-outline-secondary"
|
||||||
|
:class="{ active: editor.isActive('bulletList') }"
|
||||||
|
@click="editor.chain().focus().toggleBulletList().run()"
|
||||||
|
title="글머리 기호">
|
||||||
|
<i class="bi bi-list-ul"></i>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-outline-secondary"
|
||||||
|
:class="{ active: editor.isActive('orderedList') }"
|
||||||
|
@click="editor.chain().focus().toggleOrderedList().run()"
|
||||||
|
title="번호 목록">
|
||||||
|
<i class="bi bi-list-ol"></i>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-outline-secondary"
|
||||||
|
:class="{ active: editor.isActive('blockquote') }"
|
||||||
|
@click="editor.chain().focus().toggleBlockquote().run()"
|
||||||
|
title="인용">
|
||||||
|
<i class="bi bi-quote"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="btn-group btn-group-sm">
|
||||||
|
<button type="button" class="btn btn-outline-secondary"
|
||||||
|
@click="editor.chain().focus().setHorizontalRule().run()"
|
||||||
|
title="구분선">
|
||||||
|
<i class="bi bi-hr"></i>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-outline-secondary"
|
||||||
|
@click="editor.chain().focus().undo().run()"
|
||||||
|
:disabled="!editor.can().undo()"
|
||||||
|
title="실행 취소 (Ctrl+Z)">
|
||||||
|
<i class="bi bi-arrow-counterclockwise"></i>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="btn btn-outline-secondary"
|
||||||
|
@click="editor.chain().focus().redo().run()"
|
||||||
|
:disabled="!editor.can().redo()"
|
||||||
|
title="다시 실행 (Ctrl+Y)">
|
||||||
|
<i class="bi bi-arrow-clockwise"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 에디터 본문 -->
|
||||||
|
<EditorContent :editor="editor" class="tiptap-content" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { useEditor, EditorContent } from '@tiptap/vue-3'
|
||||||
|
import StarterKit from '@tiptap/starter-kit'
|
||||||
|
import Placeholder from '@tiptap/extension-placeholder'
|
||||||
|
import Link from '@tiptap/extension-link'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
modelValue: string
|
||||||
|
placeholder?: string
|
||||||
|
showToolbar?: boolean
|
||||||
|
minHeight?: string
|
||||||
|
readonly?: boolean
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
'update:modelValue': [value: string]
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const editor = useEditor({
|
||||||
|
content: props.modelValue || '',
|
||||||
|
editable: !props.readonly,
|
||||||
|
extensions: [
|
||||||
|
StarterKit.configure({
|
||||||
|
heading: {
|
||||||
|
levels: [2, 3]
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
Placeholder.configure({
|
||||||
|
placeholder: props.placeholder || '내용을 입력하세요...'
|
||||||
|
}),
|
||||||
|
Link.configure({
|
||||||
|
openOnClick: false
|
||||||
|
})
|
||||||
|
],
|
||||||
|
onUpdate: ({ editor }) => {
|
||||||
|
emit('update:modelValue', editor.getHTML())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// props 변경 감지
|
||||||
|
watch(() => props.modelValue, (newValue) => {
|
||||||
|
if (editor.value && newValue !== editor.value.getHTML()) {
|
||||||
|
editor.value.commands.setContent(newValue || '')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(() => props.readonly, (newValue) => {
|
||||||
|
if (editor.value) {
|
||||||
|
editor.value.setEditable(!newValue)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
editor.value?.destroy()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 외부에서 접근 가능한 메서드
|
||||||
|
defineExpose({
|
||||||
|
getHTML: () => editor.value?.getHTML() || '',
|
||||||
|
getText: () => editor.value?.getText() || '',
|
||||||
|
focus: () => editor.value?.commands.focus(),
|
||||||
|
clear: () => editor.value?.commands.clearContent()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.tiptap-editor {
|
||||||
|
border: 1px solid #dee2e6;
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tiptap-toolbar .btn.active {
|
||||||
|
background-color: #0d6efd;
|
||||||
|
border-color: #0d6efd;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tiptap-content {
|
||||||
|
min-height: v-bind('minHeight || "300px"');
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tiptap-content :deep(.tiptap) {
|
||||||
|
outline: none;
|
||||||
|
min-height: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tiptap-content :deep(.tiptap p.is-editor-empty:first-child::before) {
|
||||||
|
color: #adb5bd;
|
||||||
|
content: attr(data-placeholder);
|
||||||
|
float: left;
|
||||||
|
height: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tiptap-content :deep(.tiptap h2) {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tiptap-content :deep(.tiptap h3) {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-top: 1.25rem;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tiptap-content :deep(.tiptap ul),
|
||||||
|
.tiptap-content :deep(.tiptap ol) {
|
||||||
|
padding-left: 1.5rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tiptap-content :deep(.tiptap blockquote) {
|
||||||
|
border-left: 3px solid #dee2e6;
|
||||||
|
padding-left: 1rem;
|
||||||
|
margin-left: 0;
|
||||||
|
color: #6c757d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tiptap-content :deep(.tiptap hr) {
|
||||||
|
border: none;
|
||||||
|
border-top: 1px solid #dee2e6;
|
||||||
|
margin: 1.5rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tiptap-content :deep(.tiptap p) {
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -146,13 +146,14 @@
|
|||||||
<strong>회의 내용</strong>
|
<strong>회의 내용</strong>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body p-0">
|
<div class="card-body p-0">
|
||||||
<textarea
|
<TiptapEditor
|
||||||
v-if="isEditing"
|
v-if="isEditing"
|
||||||
class="form-control border-0 h-100"
|
|
||||||
v-model="form.rawContent"
|
v-model="form.rawContent"
|
||||||
style="min-height: 300px; resize: none;"
|
:show-toolbar="true"
|
||||||
></textarea>
|
min-height="300px"
|
||||||
<div v-else class="p-3" style="min-height: 200px; white-space: pre-wrap;">{{ meeting.rawContent || '(내용 없음)' }}</div>
|
placeholder="회의 내용을 입력하세요..."
|
||||||
|
/>
|
||||||
|
<div v-else class="p-3 meeting-content" style="min-height: 200px;" v-html="meeting.rawContent || '<span class=\'text-muted\'>(내용 없음)</span>'"></div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="isEditing" class="card-footer d-flex justify-content-end">
|
<div v-if="isEditing" class="card-footer d-flex justify-content-end">
|
||||||
<button class="btn btn-secondary me-2" @click="cancelEdit">취소</button>
|
<button class="btn btn-secondary me-2" @click="cancelEdit">취소</button>
|
||||||
@@ -600,4 +601,35 @@ function getStatusText(status: string) {
|
|||||||
.modal.show {
|
.modal.show {
|
||||||
background: rgba(0, 0, 0, 0.5);
|
background: rgba(0, 0, 0, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.meeting-content :deep(h2) {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-content :deep(h3) {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-top: 1.25rem;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-content :deep(ul),
|
||||||
|
.meeting-content :deep(ol) {
|
||||||
|
padding-left: 1.5rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-content :deep(blockquote) {
|
||||||
|
border-left: 3px solid #dee2e6;
|
||||||
|
padding-left: 1rem;
|
||||||
|
margin-left: 0;
|
||||||
|
color: #6c757d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meeting-content :deep(p) {
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -121,20 +121,18 @@
|
|||||||
<small class="text-muted ms-2">(자유롭게 작성하면 AI가 정리해줍니다)</small>
|
<small class="text-muted ms-2">(자유롭게 작성하면 AI가 정리해줍니다)</small>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body p-0">
|
<div class="card-body p-0">
|
||||||
<!-- TODO: Tiptap 에디터로 교체 -->
|
<TiptapEditor
|
||||||
<textarea
|
|
||||||
class="form-control border-0 h-100"
|
|
||||||
v-model="form.rawContent"
|
v-model="form.rawContent"
|
||||||
|
:show-toolbar="true"
|
||||||
|
min-height="500px"
|
||||||
placeholder="회의 내용을 자유롭게 작성하세요...
|
placeholder="회의 내용을 자유롭게 작성하세요...
|
||||||
|
|
||||||
예시:
|
예시:
|
||||||
- 김철수: 이번 주 진행 상황 공유
|
- 김철수: 이번 주 진행 상황 공유
|
||||||
- 프론트엔드 개발 80% 완료
|
- 프론트엔드 개발 80% 완료
|
||||||
- 백엔드 API 연동 필요
|
- 백엔드 API 연동 필요
|
||||||
- 다음 주 목표: 테스트 환경 구축
|
- 다음 주 목표: 테스트 환경 구축"
|
||||||
- 미결정: 배포 일정 (추후 논의)"
|
/>
|
||||||
style="min-height: 500px; resize: none;"
|
|
||||||
></textarea>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="card-footer d-flex justify-content-end">
|
<div class="card-footer d-flex justify-content-end">
|
||||||
<button class="btn btn-secondary me-2" @click="router.push('/meeting')">취소</button>
|
<button class="btn btn-secondary me-2" @click="router.push('/meeting')">취소</button>
|
||||||
|
|||||||
Reference in New Issue
Block a user