gui: add sync settings panel in Svelte
This commit is contained in:
parent
1abe8c4fa0
commit
a1a50863c5
|
|
@ -98,6 +98,14 @@
|
|||
let renameValue = ''
|
||||
let renameError = ''
|
||||
|
||||
// ===== Sync state =====
|
||||
let showSettings = false
|
||||
let syncStatus = null
|
||||
let syncLoading = false
|
||||
let syncServerUrl = ''
|
||||
let syncApiKey = ''
|
||||
let syncResult = ''
|
||||
|
||||
const tabs = [
|
||||
{ id: 'overview', label: 'Обзор' },
|
||||
{ id: 'notes', label: 'Заметки' },
|
||||
|
|
@ -138,6 +146,7 @@
|
|||
window.addEventListener('keydown', handleKeydown)
|
||||
|
||||
loading = false
|
||||
loadSyncStatus()
|
||||
})
|
||||
|
||||
onDestroy(() => {
|
||||
|
|
@ -882,6 +891,53 @@
|
|||
error = String(e)
|
||||
}
|
||||
}
|
||||
|
||||
// ===== Sync =====
|
||||
async function loadSyncStatus() {
|
||||
try {
|
||||
syncStatus = await wailsCall('SyncStatus')
|
||||
} catch (e) {
|
||||
syncStatus = { configured: false, serverUrl: '', deviceId: '', unpushedOps: 0, lastSyncAt: '' }
|
||||
}
|
||||
}
|
||||
|
||||
function openSettings() {
|
||||
showSettings = true
|
||||
syncServerUrl = syncStatus?.serverUrl || ''
|
||||
syncApiKey = ''
|
||||
syncResult = ''
|
||||
}
|
||||
|
||||
function closeSettings() {
|
||||
showSettings = false
|
||||
syncResult = ''
|
||||
}
|
||||
|
||||
async function saveSyncConfig() {
|
||||
syncLoading = true
|
||||
syncResult = ''
|
||||
try {
|
||||
await wailsCall('SyncConfigure', syncServerUrl, syncApiKey)
|
||||
syncResult = 'ok'
|
||||
await loadSyncStatus()
|
||||
} catch (e) {
|
||||
syncResult = 'err: ' + String(e)
|
||||
}
|
||||
syncLoading = false
|
||||
}
|
||||
|
||||
async function runSyncNow() {
|
||||
syncLoading = true
|
||||
syncResult = ''
|
||||
try {
|
||||
const r = await wailsCall('SyncNow')
|
||||
syncResult = 'pushed ' + r.pushed + ', pulled ' + r.pulled + ' (rev ' + r.serverRevision + ')'
|
||||
await loadSyncStatus()
|
||||
} catch (e) {
|
||||
syncResult = 'err: ' + String(e)
|
||||
}
|
||||
syncLoading = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="app">
|
||||
|
|
@ -914,7 +970,12 @@
|
|||
</div>
|
||||
{/if}
|
||||
</nav>
|
||||
<div class="sidebar-footer"><span class="version">{version}</span></div>
|
||||
<div class="sidebar-footer">
|
||||
<span class="version">{version}</span>
|
||||
<button class="settings-btn" on:click={openSettings} title="Настройки">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"/><path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<!-- Main -->
|
||||
|
|
@ -1425,6 +1486,39 @@
|
|||
on:cancel={handleCancel}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
{#if showSettings}
|
||||
<div class="modal-overlay" on:click|self={closeSettings}>
|
||||
<div class="modal modal-sync">
|
||||
<h3>Настройки синхронизации</h3>
|
||||
{#if syncStatus}
|
||||
<div class="sync-status">
|
||||
<div class="sync-row"><span class="sync-label">Статус</span><span class="sync-value">{syncStatus.configured ? 'Включена' : 'Отключена'}</span></div>
|
||||
<div class="sync-row"><span class="sync-label">Сервер</span><span class="sync-value mono">{syncStatus.serverUrl || '—'}</span></div>
|
||||
<div class="sync-row"><span class="sync-label">Устройство</span><span class="sync-value mono">{syncStatus.deviceId || '—'}</span></div>
|
||||
<div class="sync-row"><span class="sync-label">Неотправлено</span><span class="sync-value">{syncStatus.unpushedOps}</span></div>
|
||||
<div class="sync-row"><span class="sync-label">Последняя синх.</span><span class="sync-value">{syncStatus.lastSyncAt || '—'}</span></div>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="form-group">
|
||||
<label>URL сервера</label>
|
||||
<input type="text" placeholder="https://example.com:8443" bind:value={syncServerUrl} />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>API-ключ</label>
|
||||
<input type="password" placeholder="ключ из админ-панели" bind:value={syncApiKey} />
|
||||
</div>
|
||||
{#if syncResult}
|
||||
<div class="sync-result">{syncResult}</div>
|
||||
{/if}
|
||||
<div class="modal-actions">
|
||||
<button class="btn btn-primary" on:click={saveSyncConfig} disabled={syncLoading}>Сохранить</button>
|
||||
<button class="btn" on:click={runSyncNow} disabled={syncLoading || !syncStatus?.configured}>Синхронизировать</button>
|
||||
<button class="btn" on:click={closeSettings}>Закрыть</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</main>
|
||||
</div>
|
||||
|
||||
|
|
@ -1636,4 +1730,15 @@
|
|||
.activity-feed-type { font-size: 11px; color: #666; }
|
||||
.activity-feed-target { font-size: 10px; color: #555; background: #1e1e2e; padding: 1px 6px; border-radius: 8px; }
|
||||
.activity-feed-time { font-size: 11px; color: #555; }
|
||||
|
||||
/* Sync */
|
||||
.settings-btn { background: none; border: none; color: #555; cursor: pointer; padding: 4px; display: inline-flex; align-items: center; border-radius: 4px; margin-left: auto; }
|
||||
.settings-btn:hover { color: #ccc; background: #222233; }
|
||||
.modal-sync { width: 460px; }
|
||||
.sync-status { background: #13131f; border-radius: 8px; padding: 12px; margin-bottom: 16px; }
|
||||
.sync-row { display: flex; justify-content: space-between; padding: 4px 0; font-size: 13px; }
|
||||
.sync-label { color: #666; }
|
||||
.sync-value { color: #e4e4ef; }
|
||||
.sync-value.mono { font-family: 'SF Mono', 'Fira Code', monospace; font-size: 12px; }
|
||||
.sync-result { font-size: 12px; color: #6366f1; padding: 4px 0; }
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Reference in New Issue