fix: clear missing active vault paths

This commit is contained in:
lucaronin
2026-04-07 22:35:04 +02:00
parent b674d20a05
commit 63eedbdb91
4 changed files with 67 additions and 20 deletions

View File

@@ -87,6 +87,38 @@ describe('useOnboarding', () => {
})
})
it('clears the persisted active vault when the saved path no longer exists', async () => {
localStorage.setItem('laputa_welcome_dismissed', '1')
mockInvokeFn.mockImplementation(async (cmd: string) => {
if (cmd === 'get_default_vault_path') return '/mock/Documents/Getting Started'
if (cmd === 'check_vault_exists') return false
if (cmd === 'load_vault_list') {
return {
vaults: [{ label: 'Old Vault', path: '/vault/deleted' }],
active_vault: '/vault/deleted',
hidden_defaults: [],
}
}
if (cmd === 'save_vault_list') return null
return null
})
const { result } = renderHook(() => useOnboarding('/vault/deleted'))
await waitFor(() => {
expect(result.current.state.status).toBe('vault-missing')
})
expect(mockInvokeFn).toHaveBeenCalledWith('save_vault_list', {
list: {
vaults: [{ label: 'Old Vault', path: '/vault/deleted' }],
active_vault: null,
hidden_defaults: [],
},
})
})
it('handleCreateVault creates vault and transitions to ready', async () => {
mockInvokeFn.mockImplementation(async (cmd: string) => {
if (cmd === 'get_default_vault_path') return '/mock/Documents/Getting Started'

View File

@@ -15,6 +15,12 @@ function tauriCall<T>(command: string, args: Record<string, unknown>): Promise<T
const DISMISSED_KEY = 'laputa_welcome_dismissed'
interface PersistedVaultList {
vaults?: Array<{ label: string; path: string }>
active_vault?: string | null
hidden_defaults?: string[]
}
function wasDismissed(): boolean {
try {
return localStorage.getItem(DISMISSED_KEY) === '1'
@@ -31,6 +37,22 @@ function markDismissed(): void {
}
}
async function clearMissingActiveVault(missingPath: string): Promise<void> {
try {
const list = await tauriCall<PersistedVaultList>('load_vault_list', {})
if (!list || list.active_vault !== missingPath) return
await tauriCall('save_vault_list', {
list: {
vaults: list.vaults ?? [],
active_vault: null,
hidden_defaults: list.hidden_defaults ?? [],
},
})
} catch {
// Best effort only — onboarding should still proceed
}
}
export function useOnboarding(initialVaultPath: string) {
const [state, setState] = useState<OnboardingState>({ status: 'loading' })
const [creating, setCreating] = useState(false)
@@ -48,7 +70,16 @@ export function useOnboarding(initialVaultPath: string) {
if (exists) {
setState({ status: 'ready', vaultPath: initialVaultPath })
} else if (wasDismissed()) {
} else {
await clearMissingActiveVault(initialVaultPath)
if (cancelled) return
}
if (exists) {
return
}
if (wasDismissed()) {
// User previously dismissed — show vault-missing instead of welcome
setState({ status: 'vault-missing', vaultPath: initialVaultPath, defaultPath })
} else {