warpgate/templates/web/tabs/shares.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

139 lines
6.2 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<div x-data="{ expanded: new URLSearchParams(location.search).get('expand') || '{{ expand }}' }">
<table class="share-table">
<thead>
<tr>
<th>Name</th>
<th>Health</th>
<th>Mount</th>
<th>Cache</th>
<th>Dirty</th>
<th>Speed</th>
<th>Transfers</th>
</tr>
</thead>
<tbody>
{% for share in shares %}
<tr class="share-row" @click="expanded = expanded === '{{ share.name }}' ? '' : '{{ share.name }}'">
<td><strong>{{ share.name }}</strong></td>
<td>
{% if share.health == "OK" %}
<span class="badge badge-ok">OK</span>
{% elif share.health == "FAILED" %}
<span class="badge badge-error">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 %}
{% if share.warmup_state == "running" %}
<span class="badge badge-warmup">WARMUP {{ share.warmup_done }}/{{ share.warmup_total }}</span>
{% elif share.warmup_state == "pending" %}
<span class="badge badge-warmup">WARMUP...</span>
{% elif share.warmup_state == "complete" %}
<span class="badge badge-ok">WARMED</span>
{% endif %}
{% if share.dir_refresh_active %}
{% if share.last_dir_refresh_ago.is_empty() %}
<span class="badge badge-warn">DIR-REFRESH...</span>
{% else %}
<span class="badge badge-ok">DIR-REFRESH {{ share.last_dir_refresh_ago }}</span>
{% endif %}
{% endif %}
</td>
<td class="mono">{{ share.mount_point }}</td>
<td>{{ share.cache_display }}</td>
<td>{{ share.dirty_count }}</td>
<td>{{ share.speed_display }}</td>
<td>{{ share.transfers }}</td>
</tr>
<tr x-show="expanded === '{{ share.name }}'" x-transition {% if share.name != expand %}x-cloak{% endif %} class="detail-row">
<td colspan="7">
<div class="detail-panel">
<div class="detail-grid">
<div class="detail-card">
<div class="label">Cache Used</div>
<div class="value">{{ share.cache_display }}</div>
</div>
<div class="detail-card">
<div class="label">Dirty Files</div>
<div class="value">{{ share.dirty_count }}</div>
</div>
<div class="detail-card">
<div class="label">Transfer Speed</div>
<div class="value">{{ share.speed_display }}</div>
</div>
<div class="detail-card">
<div class="label">Active Transfers</div>
<div class="value">{{ share.transfers }}</div>
</div>
</div>
{% if share.health == "FAILED" %}
<div class="share-error-banner">
<span class="error-icon"></span>
<span class="error-msg">{{ share.health_message }}</span>
<button class="action-btn-sm"
hx-post="/api/reconnect/{{ share.name }}"
hx-target="closest .share-error-banner"
hx-swap="outerHTML">
重试
</button>
</div>
{% endif %}
<div style="margin-bottom:12px">
<button class="action-btn"
hx-post="/api/reconnect/{{ share.name }}"
hx-confirm="重新连接 {{ share.name }}"
hx-target="this"
hx-swap="outerHTML">
重新连接
</button>
</div>
<table class="info-table">
<tr><td>Health</td><td>{{ share.health }}</td></tr>
{% if share.health == "FAILED" %}
<tr><td>Probe Error</td><td class="error-text">{{ share.health_message }}</td></tr>
{% endif %}
<tr><td>Connection</td><td class="mono">{{ share.connection }}</td></tr>
<tr><td>Mount Point</td><td class="mono">{{ share.mount_point }}</td></tr>
<tr><td>Remote Path</td><td class="mono">{{ share.remote_path }}</td></tr>
<tr><td>RC Port</td><td>{{ share.rc_port }}</td></tr>
<tr><td>Errored Files</td><td>{{ share.errored_files }}</td></tr>
<tr><td>Total Errors</td><td>{{ share.errors }}</td></tr>
<tr><td>Mounted</td><td>{% if share.mounted %}Yes{% else %}No{% endif %}</td></tr>
<tr><td>Read-Only</td><td>{% if share.read_only %}Yes{% else %}No{% endif %}</td></tr>
{% if share.dir_refresh_active %}
<tr><td>Dir Refresh</td><td>{% if share.last_dir_refresh_ago.is_empty() %}pending{% else %}{{ share.last_dir_refresh_ago }}{% endif %}</td></tr>
{% endif %}
</table>
{% if !share.warmup_rules.is_empty() %}
<h4 style="margin-top:1rem;margin-bottom:0.5rem;font-size:0.95em">Warmup Rules</h4>
<table class="info-table">
<thead><tr>
<td style="font-weight:600;color:var(--text-muted)">Path</td>
<td style="font-weight:600;color:var(--text-muted)">Filter</td>
<td style="font-weight:600;color:var(--text-muted)">State</td>
<td style="font-weight:600;color:var(--text-muted)">Progress</td>
</tr></thead>
<tbody>
{% for rule in share.warmup_rules %}
<tr>
<td class="mono">{{ rule.path }}</td>
<td>{% if rule.newer_than.is_empty() %}-{% else %}{{ rule.newer_than }}{% endif %}</td>
<td><span class="badge badge-{{ rule.badge_class }}">{{ rule.state }}</span></td>
<td>{{ rule.cached + rule.skipped }}/{{ rule.total_files }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>