feat(w2): ship v1.3.0 project pack UI, preload, and E2E

Wire .novel/.novel-all export-import through modals, settings backup, and home bulk export with progress IPC.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-08 16:31:16 +08:00
parent a4412793f4
commit fe6e411d2c
19 changed files with 823 additions and 131 deletions
@@ -5,6 +5,7 @@ import { useSettingsStore } from '@renderer/stores/useSettingsStore'
import { ShortcutEditor } from '@renderer/components/settings/ShortcutEditor'
import { AiSettingsPage } from '@renderer/components/settings/AiSettingsPage'
import { TemplateSettingsTab } from '@renderer/components/settings/TemplateSettingsTab'
import { BackupSettingsTab } from '@renderer/components/settings/BackupSettingsTab'
import { SubmissionPresetTab } from '@renderer/components/settings/SubmissionPresetTab'
const THEMES: { id: ThemeId; key: string }[] = [
@@ -21,7 +22,7 @@ export function SettingsPage(): React.JSX.Element {
const { t } = useTranslation()
const settings = useSettingsStore()
const [section, setSection] = useState<
'general' | 'ai' | 'templates' | 'submission' | 'shortcuts' | 'about'
'general' | 'ai' | 'templates' | 'submission' | 'backup' | 'shortcuts' | 'about'
>('general')
return (
@@ -62,6 +63,15 @@ export function SettingsPage(): React.JSX.Element {
>
{t('settings.submission')}
</div>
<div
className={`settings-nav-item ${section === 'backup' ? 'active' : ''}`}
onClick={() => setSection('backup')}
role="button"
tabIndex={0}
data-testid="settings-nav-backup"
>
{t('settings.backup')}
</div>
<div
className={`settings-nav-item ${section === 'shortcuts' ? 'active' : ''}`}
onClick={() => setSection('shortcuts')}
@@ -249,10 +259,11 @@ export function SettingsPage(): React.JSX.Element {
{section === 'ai' && <AiSettingsPage />}
{section === 'templates' && <TemplateSettingsTab />}
{section === 'submission' && <SubmissionPresetTab />}
{section === 'backup' && <BackupSettingsTab />}
{section === 'shortcuts' && <ShortcutEditor />}
{section === 'about' && (
<p style={{ color: 'var(--text-secondary)', lineHeight: 1.8 }}>
{t('app.name')} v1.2.0
{t('app.name')} v1.3.0
<br />
{t('app.tagline')}
</p>