fix: show manual sync conflicts in gui

This commit is contained in:
mirivlad 2026-06-04 03:39:52 +08:00
parent e2aad19cc4
commit 3c6bc097e1
4 changed files with 45 additions and 3 deletions

View File

@ -148,6 +148,8 @@
// ===== Sync state ===== // ===== Sync state =====
let syncStatus = null let syncStatus = null
let syncLoading = false let syncLoading = false
let syncMessage = ''
let syncMessageKind = ''
const tabs = [ const tabs = [
{ id: 'overview', label: t('tab.overview') }, { id: 'overview', label: t('tab.overview') },
@ -1431,16 +1433,36 @@
showSettings = false showSettings = false
} }
function syncResultMessage(result) {
const conflicts = Array.isArray(result?.conflicts) ? result.conflicts : []
const applyErrors = Array.isArray(result?.applyErrors) ? result.applyErrors : []
const parts = []
if (conflicts.length > 0) {
parts.push(t('sync.conflictsCount', { count: conflicts.length }))
}
if (applyErrors.length > 0) {
parts.push(t('sync.applyErrorsCount', { count: applyErrors.length }))
}
return parts.join(' · ')
}
async function runSyncNow() { async function runSyncNow() {
syncLoading = true syncLoading = true
syncMessage = ''
syncMessageKind = ''
try { try {
await wailsCall('SyncNow') const result = await wailsCall('SyncNow')
await loadSyncStatus() await loadSyncStatus()
syncMessage = syncResultMessage(result)
syncMessageKind = syncMessage ? 'warning' : ''
} catch (e) { } catch (e) {
console.error('sync error:', e) console.error('sync error:', e)
} syncMessage = `${t('sync.status.error')}: ${e?.message || e}`
syncMessageKind = 'warning'
} finally {
syncLoading = false syncLoading = false
} }
}
// First run / recovery handlers // First run / recovery handlers
function onFirstRunComplete(status) { function onFirstRunComplete(status) {
@ -1521,7 +1543,7 @@
</div> </div>
</nav> </nav>
<div class="sidebar-footer"> <div class="sidebar-footer">
<SyncStatus {syncStatus} {syncLoading} onSync={runSyncNow} onOpenSettings={() => openSettings('sync')} /> <SyncStatus {syncStatus} {syncLoading} {syncMessage} {syncMessageKind} onSync={runSyncNow} onOpenSettings={() => openSettings('sync')} />
<div class="sidebar-footer-row"> <div class="sidebar-footer-row">
<button class="sidebar-settings-btn" on:click={() => openSettings()} title={t('common.settings')}> <button class="sidebar-settings-btn" on:click={() => openSettings()} title={t('common.settings')}>
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">

View File

@ -3,6 +3,8 @@
export let syncStatus = null export let syncStatus = null
export let syncLoading = false export let syncLoading = false
export let syncMessage = ''
export let syncMessageKind = ''
export let onSync = null export let onSync = null
export let onOpenSettings = null export let onOpenSettings = null
@ -41,6 +43,11 @@
</button> </button>
</div> </div>
</div> </div>
{#if syncMessage}
<div class={syncMessageKind === 'warning' ? 'sync-message sync-message-warning' : 'sync-message'}>
{syncMessage}
</div>
{/if}
{:else} {:else}
<div class="sync-status-row"> <div class="sync-status-row">
<span class="sync-dot dot-disabled"></span> <span class="sync-dot dot-disabled"></span>
@ -88,6 +95,14 @@
gap: 0.3rem; gap: 0.3rem;
margin-left: auto; margin-left: auto;
} }
.sync-message {
margin-top: 0.25rem;
color: var(--text-dim, #888);
line-height: 1.25;
}
.sync-message-warning {
color: #f59e0b;
}
.btn-xs { .btn-xs {
padding: 0.2rem 0.5rem; padding: 0.2rem 0.5rem;
font-size: 0.75rem; font-size: 0.75rem;

View File

@ -87,6 +87,9 @@ export default {
'sync.connected': 'Connected', 'sync.connected': 'Connected',
'sync.notConnected': 'Not connected', 'sync.notConnected': 'Not connected',
'sync.disabled': 'Disabled', 'sync.disabled': 'Disabled',
'sync.status.error': 'Sync error',
'sync.conflictsCount': 'Conflicts: {count}',
'sync.applyErrorsCount': 'Apply errors: {count}',
'kind.project': 'Project', 'kind.project': 'Project',
'kind.client': 'Client', 'kind.client': 'Client',

View File

@ -431,6 +431,8 @@ export default {
'sync.retry': 'Повторить', 'sync.retry': 'Повторить',
'sync.run': 'Синхронизировать', 'sync.run': 'Синхронизировать',
'sync.running': 'Синхронизация...', 'sync.running': 'Синхронизация...',
'sync.conflictsCount': 'Конфликты: {count}',
'sync.applyErrorsCount': 'Ошибки применения: {count}',
'error.generic': 'Произошла ошибка', 'error.generic': 'Произошла ошибка',
'error.invalidCredentials': 'Неверный логин или пароль', 'error.invalidCredentials': 'Неверный логин или пароль',