warpgate/templates/web/tabs/dashboard.html
grabbit ee9ac2ce2d feat: Web UI — offline banner, sync indicator, preset buttons, reconnect button
- Task A: Offline mode banner in layout (nas_offline field in LayoutTemplate)
- Task B: Safe-to-disconnect sync indicator on dashboard (all_synced field)
- Task C: Preset apply buttons (photographer/video/office) in config tab with POST /api/preset/{profile} endpoint
- Task D: Reconnect button and error banner in share detail panel
- Added nas_offline/all_synced fields to DaemonStatus for integration contract

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 15:44:36 +08:00

80 lines
3.1 KiB
HTML

<div id="dashboard-stats">
<div class="stat-cards">
<div class="stat-card">
<div class="label">Shares</div>
<div class="value">{{ healthy_count }} / {{ total_shares }}</div>
</div>
<div class="stat-card">
<div class="label">Cache</div>
<div class="value">{{ total_cache_display }}</div>
</div>
<div class="stat-card">
<div class="label">Speed</div>
<div class="value">{{ aggregate_speed_display }}</div>
</div>
<div class="stat-card">
<div class="label">Transfers</div>
<div class="value">{{ active_transfers }}</div>
</div>
</div>
</div>
{% if all_synced %}
<div class="sync-indicator sync-ok" id="sync-status">
<span class="sync-icon"></span>
<span class="sync-text">已全部同步 — 可以断网</span>
<span class="sync-sub">All synced — safe to disconnect</span>
</div>
{% else %}
<div class="sync-indicator sync-pending" id="sync-status">
<span class="sync-icon"></span>
<span class="sync-text">同步进行中 — 请勿断网</span>
<span class="sync-sub">Sync in progress — do not disconnect</span>
</div>
{% endif %}
<div id="share-rows">
<div class="cards">
{% for share in shares %}
<div class="card" style="cursor:pointer"
hx-get="/tabs/shares?expand={{ share.name }}" hx-target="#tab-content" hx-swap="innerHTML"
@click="activeTab = 'shares'">
<div class="card-header">
<h2>{{ share.name }}</h2>
<div>
{% if share.health == "OK" %}
<span class="badge badge-ok">OK</span>
{% elif share.health == "FAILED" %}
<span class="badge badge-error" title="{{ share.health_message }}">FAILED</span>
{% elif share.health == "PROBING" %}
<span class="badge badge-warn">PROBING</span>
{% else %}
<span class="badge badge-warn">PENDING</span>
{% endif %}
{% if share.read_only %}
<span class="badge badge-ro">RO</span>
{% endif %}
</div>
</div>
<div class="stats">
<span><span class="label">Mount:</span> <span class="value">{{ share.mount_point }}</span></span>
<span><span class="label">Cache:</span> <span class="value">{{ share.cache_display }}</span></span>
<span><span class="label">Dirty:</span> <span class="value">{{ share.dirty_count }}</span></span>
<span><span class="label">Speed:</span> <span class="value">{{ share.speed_display }}</span></span>
</div>
{% if share.health == "FAILED" %}
<div class="error-msg">{{ share.health_message }}</div>
{% endif %}
</div>
{% endfor %}
</div>
</div>
<div id="protocol-badges">
<div class="protocols">
<span class="proto-badge {% if smbd_running %}proto-on{% else %}proto-off{% endif %}">SMB: {% if smbd_running %}ON{% else %}OFF{% endif %}</span>
<span class="proto-badge {% if nfs_exported %}proto-on{% else %}proto-off{% endif %}">NFS: {% if nfs_exported %}ON{% else %}OFF{% endif %}</span>
<span class="proto-badge {% if webdav_running %}proto-on{% else %}proto-off{% endif %}">WebDAV: {% if webdav_running %}ON{% else %}OFF{% endif %}</span>
</div>
</div>