- Move board cards from dashboard to top of boards list page - Fix Werkzeug duplicate polling (WERKZEUG_RUN_MAIN guard) - Smart offline polling: fast loop for online boards, slow recheck for offline - Add manual ping endpoint POST /api/boards/<id>/ping - Add spin animation CSS for ping button Layouts module (new): - app/models/layout.py: Layout model (canvas_json, thumbnail_b64) - app/routes/layouts.py: 5 routes (list, create, builder, save, delete) - app/templates/layouts/: list and builder templates - app/static/js/layout_builder.js: full Konva.js builder engine - app/static/vendor/konva/: vendored Konva.js 9 - Structure mode: wall, room, door, window, fence, text shapes - Devices mode: drag relay/input/Sonoff channels onto canvas - Live view mode: click relays/Sonoff to toggle, socket.io state updates - Device selection: click to select, remove individual device, Delete key - Fix door/Arc size persistence across save/reload (outerRadius, scaleX/Y) - Fix Sonoff devices missing from palette (add makeSonoffChip function)
52 lines
2.0 KiB
HTML
52 lines
2.0 KiB
HTML
{% extends "base.html" %}
|
||
{% block title %}Dashboard – Location Management{% endblock %}
|
||
|
||
{% block content %}
|
||
<div class="d-flex align-items-center justify-content-between mb-4">
|
||
<h2 class="fw-bold mb-0"><i class="bi bi-grid-1x2-fill me-2 text-primary"></i>Dashboard</h2>
|
||
{% if current_user.is_admin() %}
|
||
<a href="{{ url_for('boards.add_board') }}" class="btn btn-primary">
|
||
<i class="bi bi-plus-circle me-1"></i> Add Board
|
||
</a>
|
||
{% endif %}
|
||
</div>
|
||
|
||
<!-- ── Summary cards ─────────────────────────────────────────────────────── -->
|
||
<div class="row g-3 mb-4">
|
||
<div class="col-sm-4">
|
||
<div class="card stat-card border-0 rounded-4 bg-primary bg-opacity-10">
|
||
<div class="card-body d-flex align-items-center gap-3">
|
||
<i class="bi bi-motherboard display-5 text-primary"></i>
|
||
<div>
|
||
<div class="display-6 fw-bold">{{ boards | length }}</div>
|
||
<div class="text-secondary small">Total Boards</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-sm-4">
|
||
<div class="card stat-card border-0 rounded-4 bg-success bg-opacity-10">
|
||
<div class="card-body d-flex align-items-center gap-3">
|
||
<i class="bi bi-wifi display-5 text-success"></i>
|
||
<div>
|
||
<div class="display-6 fw-bold">{{ boards | selectattr('is_online') | list | length }}</div>
|
||
<div class="text-secondary small">Online</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-sm-4">
|
||
<div class="card stat-card border-0 rounded-4 bg-warning bg-opacity-10">
|
||
<div class="card-body d-flex align-items-center gap-3">
|
||
<i class="bi bi-diagram-3 display-5 text-warning"></i>
|
||
<div>
|
||
<div class="display-6 fw-bold">{{ active_workflows }}</div>
|
||
<div class="text-secondary small">Active Workflows</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{% endblock %}
|