This commit is contained in:
Mateusz Gruszczyński
2026-08-25 19:05:18 +02:00
parent 3ee93b7225
commit dce9ef7270
14 changed files with 132 additions and 93 deletions
+11 -7
View File
@@ -621,7 +621,9 @@ function deviceCard(device, detailed = false) {
const responseTime = hasResponseTime ? `${Math.max(0, Math.round(Number(device.response_time_ms)))} ms` : '— ms';
const protocol = device.simulated ? tr('devices.simulator') : device.protocol_version === 2 ? 'V2 GCM' : device.protocol_version === 1 ? 'V1 ECB' : tr('devices.protocolAuto');
const networkInfo = `<div class="device-network-info"><small>${esc(device.ip)} · ${esc(responseTime)} · ${esc(protocol)}</small>${device.last_error ? `<small class="device-network-error" title="${esc(device.last_error)}">${esc(device.last_error)}</small>` : ''}</div>`;
return `<article class="device-card ${device.power ? '' : 'off'}" data-device-card="${esc(device.id)}">
const quickClass = detailed ? '' : ' quick-control-card quick-device-control';
const quickRow = detailed ? '' : ' quick-control-row';
return `<article class="device-card${quickClass} ${device.power ? '' : 'off'}" data-device-card="${esc(device.id)}">
<div class="device-head">
<div class="device-title"><h3>${esc(device.name)}</h3><p><span class="status ${device.online ? 'online' : ''}">${esc(tr(device.online ? 'status.online' : 'status.offline'))}</span> · ${esc(device.model || device.mac)}</p></div>
<button class="power-button ${device.power ? 'on' : ''}" data-action="power" data-device="${esc(device.id)}" aria-label="${esc(tr('devices.power'))}">⏻</button>
@@ -632,9 +634,9 @@ function deviceCard(device, detailed = false) {
<button data-action="temperature" data-delta="1" data-device="${esc(device.id)}">+</button>
</div>
<div class="current-line">${esc(tr('devices.currentTemperature'))}: <strong>${fmtTemp(device.current_temperature)}</strong>${device.outdoor_temperature == null ? '' : ` · ${esc(tr('devices.outdoor'))} ${fmtTemp(device.outdoor_temperature)}`}</div>
<div class="mode-row">${modes.map(mode => `<button class="${device.mode === mode ? 'active' : ''}" data-action="mode" data-value="${mode}" data-device="${esc(device.id)}">${esc(modeLabel(mode))}</button>`).join('')}</div>
<div class="fan-row">${fans.map(fan => `<button class="${Number(device.fan_speed) === fan ? 'active' : ''}" data-action="fan" data-value="${fan}" data-device="${esc(device.id)}">${esc(fanLabel(fan))}</button>`).join('')}</div>
<div class="device-toggles">
<div class="mode-row${quickRow}${detailed ? '' : ' quick-control-row-5'}">${modes.map(mode => `<button class="${device.mode === mode ? 'active' : ''}" data-action="mode" data-value="${mode}" data-device="${esc(device.id)}">${esc(modeLabel(mode))}</button>`).join('')}</div>
<div class="fan-row${quickRow}${detailed ? '' : ' quick-control-row-4'}">${fans.map(fan => `<button class="${Number(device.fan_speed) === fan ? 'active' : ''}" data-action="fan" data-value="${fan}" data-device="${esc(device.id)}">${esc(fanLabel(fan))}</button>`).join('')}</div>
<div class="device-toggles${quickRow}${detailed ? '' : ' quick-control-row-3'}">
<button class="${device.swing_vertical ? 'active' : ''}" data-action="toggle" data-field="swing_vertical" data-device="${esc(device.id)}">${esc(tr('devices.swing'))}</button>
${device.supports_quiet === false ? '' : `<button class="${device.quiet ? 'active' : ''}" data-action="toggle" data-field="quiet" data-device="${esc(device.id)}">${esc(tr('devices.quiet'))}</button>`}
${device.supports_turbo === false ? '' : `<button class="${device.turbo ? 'active' : ''}" data-action="toggle" data-field="turbo" data-device="${esc(device.id)}">${esc(tr('devices.turbo'))}</button>`}
@@ -691,13 +693,15 @@ function zoneCard(zone, detailed = true) {
const enabledControl = detailed
? `<span class="badge ${zone.enabled ? 'active' : ''}">${esc(state)}</span>`
: `<button type="button" class="zone-enable-toggle ${zone.enabled ? 'active' : ''}" data-action="zone-enabled" data-id="${esc(zone.id)}" data-value="${zone.enabled ? 'false' : 'true'}" aria-label="${esc(tr(zone.enabled ? 'zones.disable' : 'zones.enable'))}"><span>${zone.enabled ? '✓' : '○'}</span>${esc(state)}</button>`;
return `<article class="list-card zone-thermostat ${zone.demand ? 'demanding' : ''} ${zone.enabled ? '' : 'zone-disabled'}">
const quickClass = detailed ? '' : ' quick-control-card quick-thermostat-control';
const quickRow = detailed ? '' : ' quick-control-row';
return `<article class="list-card zone-thermostat${quickClass} ${zone.demand ? 'demanding' : ''} ${zone.enabled ? '' : 'zone-disabled'}">
<div class="list-card-head"><div><h3>${esc(zone.name)}</h3><p>${esc(device?.name || tr('common.noDevice'))} · ${esc(zonePresetLabel(zone.active_preset))}</p></div>${enabledControl}</div>
<div class="thermostat-main"><div><small>${esc(tr('zones.measurement'))}</small><strong>${fmtTemp(roomTemperature)}</strong></div><div class="temperature-control compact"><button data-action="zone-temperature" data-id="${esc(zone.id)}" data-delta="-0.5"></button><div class="target-temp compact">${Number.isFinite(target)?target.toFixed(1):'--'}<small>°C</small></div><button data-action="zone-temperature" data-id="${esc(zone.id)}" data-delta="0.5">+</button></div><div><small>${esc(tr('zones.deviceTarget'))}</small><strong>${fmtTemp(zone.device_setpoint)}</strong></div></div>
<div class="preset-row">
<div class="preset-row${quickRow}${detailed ? '' : ' quick-control-row-4'}">
${['auto','comfort','sleep','away'].map(preset=>`<button class="${manual===preset?'active':''}" data-action="zone-preset" data-id="${esc(zone.id)}" data-value="${preset}">${esc(preset==='sleep'?tr('zones.sleepNow'):zonePresetLabel(preset))}</button>`).join('')}
</div>
<div class="mode-row zone-mode-row"><button class="${mode==='house'?'active':''}" data-action="zone-mode" data-id="${esc(zone.id)}" data-value="house">${esc(tr('zones.followHouseShort'))}</button><button class="${mode==='heat'?'active':''}" data-action="zone-mode" data-id="${esc(zone.id)}" data-value="heat">${esc(modeLabel('heat'))}</button><button class="${mode==='cool'?'active':''}" data-action="zone-mode" data-id="${esc(zone.id)}" data-value="cool">${esc(modeLabel('cool'))}</button></div>
<div class="mode-row zone-mode-row${quickRow}${detailed ? '' : ' quick-control-row-3'}"><button class="${mode==='house'?'active':''}" data-action="zone-mode" data-id="${esc(zone.id)}" data-value="house">${esc(tr('zones.followHouseShort'))}</button><button class="${mode==='heat'?'active':''}" data-action="zone-mode" data-id="${esc(zone.id)}" data-value="heat">${esc(modeLabel('heat'))}</button><button class="${mode==='cool'?'active':''}" data-action="zone-mode" data-id="${esc(zone.id)}" data-value="cool">${esc(modeLabel('cool'))}</button></div>
<div class="zone-state-line"><span>${zone.demand ? esc(tr('zones.requesting')) : esc(tr('zones.satisfied'))}</span><span>${esc(override)}</span></div>
${detailed ? `<div class="sensor-detail">${esc(sensorDetails)}</div><div class="card-footer"><small>${esc(tr('zones.quickHintSmart'))}</small><div class="card-menu"><button data-action="edit-zone" data-id="${esc(zone.id)}">${esc(tr('actions.edit'))}</button><button class="danger" data-action="delete-zone" data-id="${esc(zone.id)}">${esc(tr('actions.delete'))}</button></div></div>` : ''}
</article>`;