generated from ttipo/project-base
feat(frontend): 보내기 취소 · 예약 발송 · 외부 이미지 · 인쇄 · 보낸 사람 차단 · 보내기 · 읽기 설정 화면
쓰기 화면의 [보내기 ▾](예약 발송 창), 보내기 취소 알림(남은 시간 막대), 메일함 패널 「예약됨」 · 예약 목록, 읽기 화면의 안내 줄([이미지 보기] · [고치기] · [예약 취소] · [차단 풀기]), 인쇄 화면(새 탭 — A4 폭으로 다시 재서 빈 쪽 없이), 보낸 사람 차단 창, 설정 › 보내기 · 읽기 · 차단한 주소. 디자인 README "9단계", 계약 2절. 리뷰로 고친 것: - 붙잡힌 메일을 여러 통 처리로 지워도 예약이 그대로 나갔다 — 고르지 못하게 했다(고르기 칸 aria-disabled + 까닭, 하나 · 범위 · 모두 고르기가 건너뛴다). 읽기 화면 [삭제]는 확인(처음 초점 「취소」) 뒤 발송을 취소하고 휴지통으로 — 서버도 MAIL_015 로 막는다. - 엔진이 발송을 풀어도 상태가 바뀌지 않아 "보내는 중" · 「예약됨」이 남았다 — 보낼 시각 + 2초에 목록 · 열린 메일 · 예약 수를 다시 맞춘다(MAIL_014 때도). - 설정을 연달아 고르면 늦게 온 앞 응답이 화면과 서버를 갈랐다 — 칸마다 저장은 한 번에 하나, 끝나면 마지막으로 고른 값으로 맞춘다. - 응답을 기다리는 사이 다른 목록으로 간 사용자를 옛 목록의 다음 메일로 끌고 갔다 — 같은 목록 · 같은 메일을 보고 있을 때만 옮긴다(3 · 4단계 단추도). - 이미지를 보일 때 본문 틀의 CSP 를 우리 출처의 중계 경로로만 연다 — 'self' 면 정화를 빠져나간 CSS url() 이 다른 API 를 부를 수 있었다. - 알림 단추는 한 번만 돈다, 보내기 취소 알림의 마감은 설정한 초로 묶는다, [보내기 ▾] 메뉴는 화면 안에서 연다(쓰기 화면이 움직이지 않게), 차단 목록 · 설정 저장의 상태가 멈추던 것, 초점을 잃던 것과 알리지 않던 라이브 영역. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,14 @@
|
||||
import type { RouteRecordRaw } from 'vue-router'
|
||||
|
||||
import { CONTACTS_ROUTES } from '@/shared/constants/contacts'
|
||||
import { MAIL_PRINT_ROUTE } from '@/shared/constants/mail-print'
|
||||
import { SETTINGS_ROUTES } from '@/shared/constants/settings-menu'
|
||||
import { MAIL_SEARCH_MESSAGE_ROUTE, MAIL_SEARCH_ROUTE } from '@/shared/utils/mail-list-source'
|
||||
import {
|
||||
MAIL_SCHEDULED_MESSAGE_ROUTE,
|
||||
MAIL_SCHEDULED_ROUTE,
|
||||
MAIL_SEARCH_MESSAGE_ROUTE,
|
||||
MAIL_SEARCH_ROUTE,
|
||||
} from '@/shared/utils/mail-list-source'
|
||||
|
||||
// 앱의 라우트 표 — 라우터(index.ts)와 라우트 테스트가 함께 쓴다 (이 파일은 라우터를 만들지 않는다)
|
||||
|
||||
@@ -25,6 +31,15 @@ export const routes: RouteRecordRaw[] = [
|
||||
component: () => import('@/pages/LoginPage.vue'),
|
||||
meta: { guestOnly: true, title: '로그인' },
|
||||
},
|
||||
{
|
||||
// 인쇄 화면 (9단계 — 디자인 README "9단계 › 인쇄 화면") — 앱 틀 없이 메일 한 통. 읽기 화면 ⋯ › 인쇄 · Ctrl+P 가 새 탭으로 연다.
|
||||
// 읽기 화면에서 외부 이미지를 보이고 있었으면 ?images=show. /mail 의 하위가 아니다(메일 레이아웃 · 앱 틀을 그리지 않는다) —
|
||||
// 고정 경로라 /mail/:mailboxId/:messageId 보다 앞선다
|
||||
path: '/mail/print/:messageId',
|
||||
name: MAIL_PRINT_ROUTE,
|
||||
component: () => import('@/pages/mail/MailPrintPage.vue'),
|
||||
meta: { requiresAuth: true, title: '메일 인쇄' },
|
||||
},
|
||||
{
|
||||
path: '/mail',
|
||||
component: () => import('@/pages/mail/MailLayout.vue'),
|
||||
@@ -47,6 +62,15 @@ export const routes: RouteRecordRaw[] = [
|
||||
component: MailboxPage,
|
||||
meta: { title: '메일 검색' },
|
||||
},
|
||||
// 예약됨 /mail/scheduled · 예약됨에서 연 메일 /mail/scheduled/<메일 id> (9단계 — 계약 2절 "보내기 취소 · 예약 발송")
|
||||
// 검색과 같이 고정 경로라 :mailboxId 보다 앞에 둔다 — 같은 화면(MailboxPage)이 목록 출처만 바꿔 그린다
|
||||
{ path: 'scheduled', name: MAIL_SCHEDULED_ROUTE, component: MailboxPage, meta: { title: '예약됨' } },
|
||||
{
|
||||
path: 'scheduled/:messageId',
|
||||
name: MAIL_SCHEDULED_MESSAGE_ROUTE,
|
||||
component: MailboxPage,
|
||||
meta: { title: '예약됨' },
|
||||
},
|
||||
{ path: ':mailboxId', name: 'mail-mailbox', component: MailboxPage },
|
||||
{ path: ':mailboxId/:messageId', name: 'mail-message', component: MailboxPage },
|
||||
],
|
||||
@@ -71,7 +95,7 @@ export const routes: RouteRecordRaw[] = [
|
||||
],
|
||||
},
|
||||
{
|
||||
// 설정 — 왼쪽 메뉴(계정 › 비밀번호 / 메일 › 서명 · 부재중 자동 응답 · 필터 · 알림) + 하위 화면.
|
||||
// 설정 — 왼쪽 메뉴(계정 › 비밀번호 / 메일 › 서명 · 부재중 자동 응답 · 필터 · 보내기 · 읽기 · 차단한 주소 · 알림) + 하위 화면.
|
||||
// /settings 는 첫 메뉴(계정 › 비밀번호)로 바꿔 끼운다 (앱 레일의 "설정")
|
||||
path: '/settings',
|
||||
component: () => import('@/pages/settings/SettingsLayout.vue'),
|
||||
@@ -103,6 +127,18 @@ export const routes: RouteRecordRaw[] = [
|
||||
component: () => import('@/pages/settings/MailFilterPage.vue'),
|
||||
meta: { title: '메일 필터' },
|
||||
},
|
||||
{
|
||||
path: 'mail/send-read',
|
||||
name: SETTINGS_ROUTES.sendRead,
|
||||
component: () => import('@/pages/settings/MailSendReadPage.vue'),
|
||||
meta: { title: '보내기 · 읽기' },
|
||||
},
|
||||
{
|
||||
path: 'mail/blocks',
|
||||
name: SETTINGS_ROUTES.blocks,
|
||||
component: () => import('@/pages/settings/MailBlocksPage.vue'),
|
||||
meta: { title: '차단한 주소' },
|
||||
},
|
||||
{
|
||||
path: 'mail/notify',
|
||||
name: SETTINGS_ROUTES.notify,
|
||||
|
||||
Reference in New Issue
Block a user