verstak/frontend/src/lib/SettingsWorkspace.svelte

179 lines
4.8 KiB
Svelte

<script>
import { t } from './i18n'
export let onRefresh = null
let info = null
let errorMsg = ''
function wailsCall(method, ...args) {
try {
if (window['go'] && window['go']['main'] && window['go']['main']['App']) {
const fn = window['go']['main']['App'][method]
if (typeof fn === 'function') return fn(...args)
}
} catch (e) { console.error('Wails error:', method, e) }
return Promise.reject(new Error('Wails not connected: ' + method))
}
async function load() {
try {
info = await wailsCall('GetVaultInfo')
} catch (e) { info = null }
}
load()
async function openVaultFolder() {
try { await wailsCall('OpenVaultFolder') } catch (e) { errorMsg = String(e) }
}
async function checkIntegrity() {
try {
const result = await wailsCall('VaultCheck')
if (result.healthy) {
errorMsg = 'Vault healthy'
} else {
errorMsg = 'Issues found: ' + (result.errors || []).join('; ')
}
} catch (e) { errorMsg = String(e) }
}
async function chooseVault() {
try {
const chosen = await wailsCall('PickDirectory')
if (!chosen) return
const status = await wailsCall('OpenVault', chosen)
if (status && status.status === 'ready') {
info = await wailsCall('GetVaultInfo')
if (onRefresh) onRefresh()
}
} catch (e) { errorMsg = String(e) }
}
function formatSize(bytes) {
if (!bytes) return '—'
if (bytes < 1024) return bytes + ' B'
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB'
return (bytes / (1024 * 1024)).toFixed(1) + ' MB'
}
</script>
<div class="settings-section">
<h2>{t('settings.workspace')}</h2>
<p class="section-desc">{t('settings.workspaceDesc')}</p>
{#if errorMsg}
<div class="notice">{errorMsg}</div>
{/if}
<div class="settings-card">
{#if info}
<div class="vault-info">
<div class="info-row">
<span class="info-label">{t('settings.vaultPath')}</span>
<span class="info-value mono">{info.path}</span>
</div>
<div class="info-row">
<span class="info-label">DB</span>
<span class="info-value mono small">{info.dbPath}</span>
</div>
{#if info.nodeCount !== undefined}
<div class="info-row">
<span class="info-label">Nodes</span>
<span class="info-value">{info.nodeCount}</span>
</div>
{/if}
{#if info.fileCount !== undefined}
<div class="info-row">
<span class="info-label">Files</span>
<span class="info-value">{info.fileCount}</span>
</div>
{/if}
</div>
{:else}
<p class="no-data">{t('settings.noVaultInfo')}</p>
{/if}
</div>
<div class="workspace-actions">
<button class="btn" on:click={openVaultFolder}>{t('settings.openVault')}</button>
<button class="btn" on:click={chooseVault}>{t('settings.changeVault')}</button>
<button class="btn" on:click={checkIntegrity}>{t('settings.checkIntegrity')}</button>
</div>
</div>
<style>
.settings-section {
padding: 1.5rem;
max-width: 600px;
}
.settings-section h2 {
margin: 0 0 0.25rem 0;
font-size: 1.2rem;
color: var(--text, #e0e0e0);
}
.section-desc {
color: var(--text-dim, #888);
font-size: 0.85rem;
margin-bottom: 1.25rem;
line-height: 1.4;
}
.settings-card {
background: var(--surface-alt, #1e1e30);
border: 1px solid var(--border, #2a2a3e);
border-radius: 8px;
padding: 1rem 1.25rem;
margin-bottom: 1rem;
}
.notice {
padding: 0.5rem 0.75rem;
margin-bottom: 0.75rem;
background: rgba(255, 107, 107, 0.1);
border: 1px solid rgba(255, 107, 107, 0.3);
border-radius: 6px;
color: #ff6b6b;
font-size: 0.85rem;
}
.vault-info {}
.info-row {
display: flex;
padding: 0.4rem 0;
border-bottom: 1px solid var(--border, #2a2a3e);
font-size: 0.9rem;
}
.info-row:last-child { border-bottom: none; }
.info-label {
width: 120px;
min-width: 120px;
color: var(--text-dim, #888);
}
.info-value { color: var(--text, #e0e0e0); word-break: break-all; }
.info-value.mono { font-family: monospace; font-size: 0.85rem; }
.info-value.small { font-size: 0.8rem; }
.workspace-actions {
display: flex;
gap: 0.5rem;
flex-wrap: wrap;
margin-top: 0.5rem;
}
.btn {
padding: 0.45rem 0.8rem;
border: 1px solid var(--border, #2a2a3e);
border-radius: 6px;
background: var(--surface-light, #232338);
color: var(--text, #e0e0e0);
font-size: 0.85rem;
cursor: pointer;
}
.btn:hover {
background: var(--accent, #4a7c59);
border-color: var(--accent, #4a7c59);
}
.no-data {
color: var(--text-dim, #888);
font-style: italic;
margin: 0;
}
</style>