Files
location_managemet/app/templates/devices/list.html
2026-03-30 15:49:26 +03:00

119 lines
3.5 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.
{% extends "base.html" %}
{% block title %}Devices 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-hdd-stack me-2 text-info"></i>Devices
</h2>
{% if current_user.is_admin() %}
<a href="{{ url_for('devices.add_device') }}" class="btn btn-primary">
<i class="bi bi-plus-circle me-1"></i> Add Device
</a>
{% endif %}
</div>
<p class="text-secondary mb-4">
Define named, personalized devices (lights, switches, pumps, sensors…) that map to
specific relay or input channels on your boards. Devices can be placed on Layout pages
as interactive widgets.
</p>
{% if devices %}
{# Group by area #}
{% set areas = devices | map(attribute='area') | unique | list %}
{% set no_area = devices | selectattr('area', 'none') | list
+ devices | selectattr('area', 'equalto', '') | list
+ devices | selectattr('area', 'equalto', None) | list %}
{# Collect non-empty areas #}
{% set named_areas = [] %}
{% for d in devices %}
{% if d.area and d.area != '' and d.area not in named_areas %}
{% set _ = named_areas.append(d.area) %}
{% endif %}
{% endfor %}
{# Devices with no area #}
{% set ungrouped = [] %}
{% for d in devices %}
{% if not d.area or d.area == '' %}
{% set _ = ungrouped.append(d) %}
{% endif %}
{% endfor %}
{% for area in named_areas %}
<h5 class="text-secondary fw-semibold mb-3 mt-4">
<i class="bi bi-geo-alt me-1"></i>{{ area }}
</h5>
<div class="row g-3 mb-2">
{% for device in devices %}
{% if device.area == area %}
<div class="col-md-6 col-xl-4" id="device-card-{{ device.id }}">
{% include "devices/_card.html" %}
</div>
{% endif %}
{% endfor %}
</div>
{% endfor %}
{% if ungrouped %}
{% if named_areas %}
<h5 class="text-secondary fw-semibold mb-3 mt-4">
<i class="bi bi-three-dots me-1"></i>Other
</h5>
{% endif %}
<div class="row g-3 mb-2">
{% for device in ungrouped %}
<div class="col-md-6 col-xl-4" id="device-card-{{ device.id }}">
{% include "devices/_card.html" %}
</div>
{% endfor %}
</div>
{% endif %}
{% else %}
<div class="text-center py-5 text-secondary">
<i class="bi bi-hdd-stack display-4 d-block mb-3 opacity-25"></i>
<p class="mb-1">No devices defined yet.</p>
{% if current_user.is_admin() %}
<a href="{{ url_for('devices.add_device') }}" class="btn btn-sm btn-outline-primary mt-2">
<i class="bi bi-plus-circle me-1"></i> Add your first device
</a>
{% endif %}
</div>
{% endif %}
{% endblock %}
{% block scripts %}
<script>
function deviceToggle(btn, deviceId) {
btn.disabled = true;
fetch(`/devices/${deviceId}/toggle`, {
method: "POST",
headers: {"X-Requested-With": "XMLHttpRequest"}
})
.then(r => r.json())
.then(data => {
if (!data.ok) { btn.disabled = false; return; }
const card = document.getElementById("device-card-" + deviceId);
const badge = card.querySelector(".device-state-badge");
if (badge) {
badge.className = "badge device-state-badge text-bg-" + data.state_color;
badge.textContent = data.state_label;
}
// Update toggle icon
btn.className = btn.className.replace(/btn-(outline-)?[a-z]+/, "btn-" + data.state_color);
if (data.state) {
btn.innerHTML = '<i class="bi bi-power me-1"></i>ON';
} else {
btn.innerHTML = '<i class="bi bi-power me-1"></i>OFF';
}
btn.disabled = false;
})
.catch(() => { btn.disabled = false; });
}
</script>
{% endblock %}