feat(frontend): 주소록 화면 · 메일 연동

레일의 주소록 모듈 — 내 연락처 · 그룹 · 사내 목록(직원 · 공용 주소), 초성 찾기, 연락처 추가 · 고치기 창, 그룹 · 구성원 넣기 —
과 메일 연동(받는 사람 추천의 주소록 · 그룹, 연락처 · 그룹 · 사내의 [메일 쓰기], 읽기 화면 ⋯ 「보낸 사람을 주소록에 추가」)을 더한다.
디자인 README "8단계", 계약 3절.

리뷰로 고친 것:
- 쓰기 화면을 채우는 라우터 상태에 연 직원을 싣는다 — 같은 탭에서 다른 직원이 로그인한 뒤 뒤로 가면 앞 직원의 받는 사람이 채워졌다.
- [고치기]는 창을 열 때 새로 받고 바꾼 칸만 보낸다 — 받아 둔 값으로 다른 탭 · 휴대폰의 변경을 덮었다. 검사도 바꾼 칸만.
- [되돌리기]는 서버의 되돌리기 표로 — 다시 만들기로는 다른 프로그램의 칸 · uid 를 잃었다.
- 읽기 화면에서 연 연락처 추가 창을 메일 레이아웃으로 옮겼다 — 메일을 바꾸면 쓴 것이 확인 없이 사라졌다.
- 그룹을 이어 고르면 앞 그룹이 빠지던 것, 저장 중 창을 닫으면 거절이 묻히던 것, 구성원 넣기의 첫 쪽이 모두 구성원이면 막히던 것(excludeGroupId).
- 받는 사람 추천은 초성 · 조합 중 글자도 서버에 묻는다(서버가 같은 맞추기 — 같은 표본 표를 두 쪽 테스트에 둔다).
- 바꿀 때마다 불러온 쪽을 모두 다시 받지 않고 응답을 서버 차례로 그 자리에 넣는다.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-29 14:13:20 +09:00
parent 08cf31fbe6
commit e2c41d38bb
65 changed files with 11130 additions and 214 deletions
+24
View File
@@ -1,5 +1,6 @@
import type { RouteRecordRaw } from 'vue-router'
import { CONTACTS_ROUTES } from '@/shared/constants/contacts'
import { SETTINGS_ROUTES } from '@/shared/constants/settings-menu'
import { MAIL_SEARCH_MESSAGE_ROUTE, MAIL_SEARCH_ROUTE } from '@/shared/utils/mail-list-source'
@@ -7,6 +8,10 @@ import { MAIL_SEARCH_MESSAGE_ROUTE, MAIL_SEARCH_ROUTE } from '@/shared/utils/mai
// 목록·본문 라우트가 같은 컴포넌트를 쓰도록 한 번만 정의한다 (메일을 바꿔도 화면을 다시 만들지 않는다)
const MailboxPage = () => import('@/pages/mail/MailboxPage.vue')
// 주소록도 같다 — 목록(전체 · 그룹 · 사내)과 고른 연락처가 바뀌어도 한 화면이 주소만 다시 읽는다
const ContactsPage = () => import('@/pages/contacts/ContactsPage.vue')
/** 사내 목록 종류 — 주소의 people · shared 만 (constants/contacts.ts 의 DIRECTORY_KIND_SEGMENTS) */
const DIRECTORY_KIND_PARAM = ':kind(people|shared)'
// 코드 스플리팅 — 모든 페이지 컴포넌트는 lazy import 처리
export const routes: RouteRecordRaw[] = [
@@ -46,6 +51,25 @@ export const routes: RouteRecordRaw[] = [
{ path: ':mailboxId/:messageId', name: 'mail-message', component: MailboxPage },
],
},
{
// 주소록 (8단계 — 디자인 README "8단계 — 주소록") — 모듈 패널(내 주소록 · 그룹 · 사내) + 목록 + 상세.
// 고른 연락처 · 사내 항목은 주소에 남는다(새로 고침 · 뒤로 가기). 모두 ?q= (지금 목록 안에서 찾기)를 받는다
path: '/contacts',
component: () => import('@/pages/contacts/ContactsLayout.vue'),
meta: { requiresAuth: true, title: '주소록' },
children: [
{ path: '', name: CONTACTS_ROUTES.all, component: ContactsPage },
{ path: 'all/:contactId', name: CONTACTS_ROUTES.contact, component: ContactsPage },
{ path: 'groups/:groupId', name: CONTACTS_ROUTES.group, component: ContactsPage },
{ path: 'groups/:groupId/:contactId', name: CONTACTS_ROUTES.groupContact, component: ContactsPage },
{ path: `directory/${DIRECTORY_KIND_PARAM}`, name: CONTACTS_ROUTES.directory, component: ContactsPage },
{
path: `directory/${DIRECTORY_KIND_PARAM}/:entryId`,
name: CONTACTS_ROUTES.directoryEntry,
component: ContactsPage,
},
],
},
{
// 설정 — 왼쪽 메뉴(계정 › 비밀번호 / 메일 › 서명 · 부재중 자동 응답 · 필터 · 알림) + 하위 화면.
// /settings 는 첫 메뉴(계정 › 비밀번호)로 바꿔 끼운다 (앱 레일의 "설정")