From 40c65e2f2f7fc019457ae0d98d8e263449856595 Mon Sep 17 00:00:00 2001
From: Ingmar Stein <490610+IngmarStein@users.noreply.github.com>
Date: Fri, 14 Nov 2025 15:39:29 +0100
Subject: [PATCH] feat(ui): Improve device card with collapsible device info
and table layout
Refactored the device information section in `device_card.html` to use a table for better alignment and readability. Implemented a collapsible section for device details, controlled by a new toggle button and JavaScript function. Enhanced visual hierarchy by bolding the labels within the device info table. Also, updated German translations to include the new "Device Info" string.
---
tronbyt_server/static/css/manager.css | 47 ++++
tronbyt_server/static/js/manager.js | 31 +++
.../templates/partials/device_card.html | 43 ++--
.../translations/de/LC_MESSAGES/messages.mo | Bin 24727 -> 24956 bytes
.../translations/de/LC_MESSAGES/messages.po | 205 +++++++++---------
5 files changed, 211 insertions(+), 115 deletions(-)
diff --git a/tronbyt_server/static/css/manager.css b/tronbyt_server/static/css/manager.css
index 89a0da35..0fe7091e 100644
--- a/tronbyt_server/static/css/manager.css
+++ b/tronbyt_server/static/css/manager.css
@@ -1086,3 +1086,50 @@ button.action.w3-button {
box-sizing: border-box;
}
}
+
+.device-info-toggle {
+ background-color: #f1f1f1;
+ color: #333;
+ cursor: pointer;
+ padding: 10px;
+ width: 100%;
+ border: none;
+ text-align: left;
+ font-size: 0.9375rem;
+ transition: 0.4s;
+}
+
+.device-info-toggle:focus-visible {
+ box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.5);
+}
+
+.device-info-toggle:hover {
+ background-color: #ddd;
+}
+
+.device-info-content {
+ padding: 0 15px;
+ overflow: hidden;
+ transition: max-height 0.2s ease-out, padding-top 0.2s ease-out, padding-bottom 0.2s ease-out;
+ max-height: 0;
+}
+
+.device-info-content.is-expanded {
+ padding-top: 5px;
+ padding-bottom: 5px;
+}
+
+.device-info-table {
+ width: 100%;
+ border-collapse: collapse;
+}
+
+.device-info-table td:first-child {
+ font-weight: bold;
+}
+
+.device-info-table td {
+ padding: 4px;
+ text-align: left;
+ font-size: 0.9em;
+}
diff --git a/tronbyt_server/static/js/manager.js b/tronbyt_server/static/js/manager.js
index e6a8cea5..9fcbc39d 100644
--- a/tronbyt_server/static/js/manager.js
+++ b/tronbyt_server/static/js/manager.js
@@ -403,6 +403,7 @@ let draggedIname = null;
document.addEventListener('DOMContentLoaded', function() {
initializeDragAndDrop();
initializeViewToggles();
+ initializeDeviceInfoToggles();
const webpImages = document.querySelectorAll('[id^="currentWebp-"]');
webpImages.forEach(image => {
@@ -426,6 +427,12 @@ function initializeViewToggles() {
});
}
+function initializeDeviceInfoToggles() {
+ document.querySelectorAll('.device-info-toggle').forEach(button => {
+ button.addEventListener('click', () => toggleDeviceInfo(button));
+ });
+}
+
function restoreDevicePreferences(deviceId) {
const prefs = loadDevicePreferences(deviceId);
const appsList = document.getElementById(`appsList-${deviceId}`);
@@ -903,3 +910,27 @@ function handleDropZoneDrop(e) {
// Clean up
zone.classList.remove('active');
}
+
+function toggleDeviceInfo(button) {
+ const content = document.getElementById(button.getAttribute('aria-controls'));
+ if (!content) {
+ return;
+ }
+ const icon = button.querySelector('i');
+ const isExpanded = button.getAttribute('aria-expanded') === 'true';
+
+ button.setAttribute('aria-expanded', !isExpanded);
+ content.classList.toggle('is-expanded');
+
+ if (!isExpanded) {
+ content.style.maxHeight = content.scrollHeight + "px";
+ if (icon) {
+ icon.classList.replace('fa-chevron-down', 'fa-chevron-up');
+ }
+ } else {
+ content.style.maxHeight = '0px';
+ if (icon) {
+ icon.classList.replace('fa-chevron-up', 'fa-chevron-down');
+ }
+ }
+}
diff --git a/tronbyt_server/templates/partials/device_card.html b/tronbyt_server/templates/partials/device_card.html
index ab18713f..cd407b06 100644
--- a/tronbyt_server/templates/partials/device_card.html
+++ b/tronbyt_server/templates/partials/device_card.html
@@ -30,24 +30,31 @@
{{ _('Currently Displaying App') }}
- {% if device.info.firmware_version %}
-
{{ _('Firmware Version:') }} {{ device.info.firmware_version }}
- {% endif %}
- {% if device.info.firmware_type %}
-
{{ _('Firmware Type:') }} {{ device.info.firmware_type }}
- {% endif %}
- {% if device.info.protocol_version %}
-
{{ _('Protocol Version:') }} {{ device.info.protocol_version }}
- {% endif %}
- {% if device.info.mac_address %}
-
{{ _('MAC Address:') }} {{ device.info.mac_address }}
- {% endif %}
- {% if device.info.protocol_type %}
-
{{ _('Protocol Type:') }} {{ device.info.protocol_type.value }}
- {% endif %}
- {% if device.last_seen %}
-
{{ _('Last Seen:') }} {{ device.last_seen.astimezone().strftime('%Y-%m-%d %H:%M:%S') }}
- {% endif %}
+
+
+
+ {% if device.info.firmware_version %}
+ | {{ _('Firmware Version:') }} | {{ device.info.firmware_version }} |
+ {% endif %}
+ {% if device.info.firmware_type %}
+ | {{ _('Firmware Type:') }} | {{ device.info.firmware_type }} |
+ {% endif %}
+ {% if device.info.protocol_version %}
+ | {{ _('Protocol Version:') }} | {{ device.info.protocol_version }} |
+ {% endif %}
+ {% if device.info.mac_address %}
+ | {{ _('MAC Address:') }} | {{ device.info.mac_address }} |
+ {% endif %}
+ {% if device.info.protocol_type %}
+ | {{ _('Protocol Type:') }} | {{ device.info.protocol_type.value }} |
+ {% endif %}
+ {% if device.last_seen %}
+ | {{ _('Last Seen:') }} | {{ device.last_seen.astimezone().strftime('%Y-%m-%d %H:%M:%S') }} |
+ {% endif %}
+
+
diff --git a/tronbyt_server/translations/de/LC_MESSAGES/messages.mo b/tronbyt_server/translations/de/LC_MESSAGES/messages.mo
index 8c628564eeae13f725eada5fd2838570b173361a..48e1fb99225661619b4731ae0ce9a1e51411d577 100644
GIT binary patch
delta 6014
zcmYM&32;@_9mnwt3E3bk5JU{Q5VkBJ!6d{GBp_i6Z4wY!gFKQKco0HNo~?p#1qx`X
zf>0Jk8nhsG6qq5(2*YZ`fm+dODgqTN6gn0RSP?}8`~Bsd85t&@bIv`>|NPInHw+t(
zw)*LvR^GXU(De>~Dq1owcny0dv6iBXQ{IB^ts=5#?tnq@nT!ok#wF&3XiO}GUW*lx_mLzscrQ5ooV
zw|Sn93M3CT|4`KPDX5K9U|ZIAYANi+#i#(XyO;$>TPLG36Tn`$0=3{yRHn|L7Wx_$
z;B{2S!Wa~X38;Q4sK9ej0TrUBj?*b9m2*%NEWvKL4kPd_Y=ehTsec!hkrT*Y=QKas
z;SJP$AxUN|=KIrhPNRHVmIDLaK)=u6ZDcdSue
zO(2P=_FkwA4Zt*LHShop+Uapr%KnbZ$a&PQziEx(RVbvM
zf=XckHEt=Y-zwBbw&FnCZ`=Qe+DN!-7LG?{va?4)6Ldud(i=7LeW;X;#V8z)TySSP
zYA3%z1@bgLOhdJ2q9z=HgRv4d?>1B*`%w!wqQ;*xbQ1Df
zE?pTa6XmEB&aw3%DuoMC6F!Ana3kt+?ZhFtAJy+i)cBuKmp8J9*7G<63QAErD#CmW
z#S+w|n}FIuE$V0%q9*zyDzHDHGO!(a^PK&-5~IqE1jU}x5M-lCw6
zAEG9{g4)py?1j<%AnQ&R>T*4ddY@}h8C!;ZaXo5*M$}O>p~hXuP)zJ?GTjArr_#`C
zLm``jIu61aScYmpgc|rRDzFo%)O~`=$OY7;ynq%5V=TJMpfC}_G
z<4||5JeB;bP)mc(b_wbZyl6Y_LQQZOUHljo*tf`E=N3Q6uG5pRjpiAPT3{-=ScMAs
zStLo$T2#RMu^x|jwqZuPiLes2gL%kD&RKviZnDq!VFdLfsM~%5L+}e!U>B^Hv4Hxw
zww{$?0?bEct_aoNE2E&x;+)DJdR3X6PDmv`#gi2r|-iE)LrmlJA49*
zaRrv+r&xh`{mgvzNI%bc-4vX+F@_GuP$_CcrSc3apv$OKUbpp|sK8p^YXXZw?W`ke
zTyNW+i?P&)pq>|_=JR38@BcY11;=>|V|nltDm80RJKluaQN69dfl7S?Du5HH*YzLh
z;uS2#=>BH>Bd85kq86^gN_-4MxPQ(+Da7KxPzzr}UB(|U8sjs~1j!gly(cQLdr{+Z
zPyviU1yp9A2QZ#`4eBl}MQvm^Fx%;wc=WpdEdLTU$BKCCsJ1@;)=*2r7^dun(R^
zed$88%y+{@wGTt>a4s^16GYAXDr#c~P?>laHQ!&eIDZvBqd_~ngxc9PjKS}*2Zm*v
z_d6Y3>cyx_TZ7u!8tX39>-sm;xGzxihvt}h6OdmwPG{6z%FiMHO5so%^0Cx*d=3@q
zdh2G?Eq@t{@Br$zM+`Izxu|*}t|o(JsPDtqq>+2-bmBK!JdQwRViGFA86E|l*>dai
zsDQSh7Tk&2(Q)fp>`c8GH7WGzEwpb~W#f>?wrQAhL%YKP6J0F#E9Bg;Z%
zU~xu@@dkyPXMN`z3Od`a)6IVxrK8@0a#SjpqIURu)P(D-FWdIr
zsPS)GkD(U$81)6bjryRaJYv3>BQc5kZ1j>Tte~JBy^1=DeW-=bp)zs>````Kha`E1
z$yg60b|)KkRO_rSqFZ@owCK)9@YagvmaWk%2z;r-lk&Ltf(R;i03eE9Wr+jwB6zqYP?cC9}U^atGvpADk#SQEssKrrZct9%vy
yYIi(?{efzCZWTZMwf;JHSfHxHojt#NcEj?KHEm-vTmo|ER}f@NM0du$5dD8r|F*mU
delta 5806
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\n"
"Language: de\n"
@@ -22,23 +22,23 @@ msgstr ""
msgid "Never"
msgstr "Nie"
-#: tronbyt_server/utils.py:131
+#: tronbyt_server/utils.py:133
msgid "Repo Cloned"
msgstr "Repo geklont"
-#: tronbyt_server/utils.py:132
+#: tronbyt_server/utils.py:134
msgid "Repo Updated"
msgstr "Repo aktualisiert"
-#: tronbyt_server/utils.py:133
+#: tronbyt_server/utils.py:135
msgid "Repo removed"
msgstr "Repo entfernt"
-#: tronbyt_server/utils.py:134
+#: tronbyt_server/utils.py:136
msgid "Error Cloning or Updating Repo"
msgstr "Fehler beim Klonen oder Aktualisieren des Repos"
-#: tronbyt_server/utils.py:135
+#: tronbyt_server/utils.py:137
msgid "No Changes to Repo"
msgstr "Keine Änderungen am Repo"
@@ -108,201 +108,201 @@ msgstr "Neuer API-Schlüssel erfolgreich generiert."
msgid "Failed to generate new API key."
msgstr "Neuer API-Schlüssel konnte nicht generiert werden."
-#: tronbyt_server/routers/manager.py:468
+#: tronbyt_server/routers/manager.py:448
msgid "Unique name is required."
msgstr "Ein eindeutiger Name ist erforderlich."
-#: tronbyt_server/routers/manager.py:484
+#: tronbyt_server/routers/manager.py:464
msgid "Could not generate a unique device ID."
msgstr "Konnte keine eindeutige Geräte-ID generieren."
-#: tronbyt_server/routers/manager.py:531 tronbyt_server/routers/manager.py:777
+#: tronbyt_server/routers/manager.py:511 tronbyt_server/routers/manager.py:750
msgid "Invalid location"
msgstr "Ungültiger Standort"
-#: tronbyt_server/routers/manager.py:533 tronbyt_server/routers/manager.py:779
+#: tronbyt_server/routers/manager.py:513 tronbyt_server/routers/manager.py:752
#, python-brace-format
msgid "Location JSON error {error}"
msgstr "Standort JSON-Fehler {error}"
-#: tronbyt_server/routers/manager.py:701
+#: tronbyt_server/routers/manager.py:674
msgid "Id and Name is required."
msgstr "ID und Name sind erforderlich."
-#: tronbyt_server/routers/manager.py:733
+#: tronbyt_server/routers/manager.py:706
#, python-brace-format
msgid "Invalid night start time: {error}"
msgstr "Ungültige Nacht-Startzeit: {error}"
-#: tronbyt_server/routers/manager.py:739
+#: tronbyt_server/routers/manager.py:712
#, python-brace-format
msgid "Invalid night end time: {error}"
msgstr "Ungültige Nacht-Endzeit: {error}"
-#: tronbyt_server/routers/manager.py:747
+#: tronbyt_server/routers/manager.py:720
#, python-brace-format
msgid "Invalid dim time: {error}"
msgstr "Ungültige Dimm-Zeit: {error}"
-#: tronbyt_server/routers/manager.py:863
+#: tronbyt_server/routers/manager.py:836
msgid "App name required."
msgstr "App-Name erforderlich."
-#: tronbyt_server/routers/manager.py:874 tronbyt_server/routers/manager.py:1100
+#: tronbyt_server/routers/manager.py:847 tronbyt_server/routers/manager.py:1092
msgid "Could not generate a unique installation ID."
msgstr "Konnte keine eindeutige Installations-ID generieren."
-#: tronbyt_server/routers/manager.py:881 tronbyt_server/routers/manager.py:1353
+#: tronbyt_server/routers/manager.py:854 tronbyt_server/routers/manager.py:1345
msgid "App not found."
msgstr "App nicht gefunden."
-#: tronbyt_server/routers/manager.py:934
+#: tronbyt_server/routers/manager.py:925
msgid "No file"
msgstr "Keine Datei"
-#: tronbyt_server/routers/manager.py:948
+#: tronbyt_server/routers/manager.py:939
msgid "Invalid file path"
msgstr "Ungültiger Dateipfad"
-#: tronbyt_server/routers/manager.py:957
+#: tronbyt_server/routers/manager.py:948
msgid "File type not allowed"
msgstr "Dateityp nicht erlaubt"
-#: tronbyt_server/routers/manager.py:965
+#: tronbyt_server/routers/manager.py:956
msgid "Upload Successful"
msgstr "Upload erfolgreich"
-#: tronbyt_server/routers/manager.py:1015
+#: tronbyt_server/routers/manager.py:1007
#, python-brace-format
msgid "Cannot delete {filename} because it is installed on a device."
msgstr "Kann {filename} nicht löschen, da es auf einem Gerät installiert ist."
-#: tronbyt_server/routers/manager.py:1069
+#: tronbyt_server/routers/manager.py:1061
msgid "App pinned."
msgstr "App angeheftet."
-#: tronbyt_server/routers/manager.py:1071
+#: tronbyt_server/routers/manager.py:1063
msgid "App unpinned."
msgstr "App entpinnt."
-#: tronbyt_server/routers/manager.py:1074
+#: tronbyt_server/routers/manager.py:1066
msgid "Error updating pin status."
msgstr "Fehler beim Aktualisieren des Pin-Status."
-#: tronbyt_server/routers/manager.py:1167
+#: tronbyt_server/routers/manager.py:1159
msgid "App duplicated successfully."
msgstr "App erfolgreich dupliziert."
-#: tronbyt_server/routers/manager.py:1279
+#: tronbyt_server/routers/manager.py:1271
msgid "Name is required."
msgstr "Name ist erforderlich."
-#: tronbyt_server/routers/manager.py:1322
+#: tronbyt_server/routers/manager.py:1314
msgid "Changes saved."
msgstr "Änderungen gespeichert."
-#: tronbyt_server/routers/manager.py:1325
+#: tronbyt_server/routers/manager.py:1317
msgid "Error saving changes."
msgstr "Fehler beim Speichern der Änderungen"
-#: tronbyt_server/routers/manager.py:1339
+#: tronbyt_server/routers/manager.py:1331
msgid "Invalid direction."
msgstr "Ungültige Richtung."
-#: tronbyt_server/routers/manager.py:1402
+#: tronbyt_server/routers/manager.py:1394
msgid "Error saving app, please try again."
msgstr "Fehler beim Speichern der App, bitte erneut versuchen."
-#: tronbyt_server/routers/manager.py:1456
+#: tronbyt_server/routers/manager.py:1449
msgid "Error Rendering App"
msgstr "Fehler beim Rendern der App"
-#: tronbyt_server/routers/manager.py:1633
+#: tronbyt_server/routers/manager.py:1679
msgid "API Key cannot be empty."
msgstr "API-Schlüssel darf nicht leer sein."
-#: tronbyt_server/routers/manager.py:1677
+#: tronbyt_server/routers/manager.py:1723
msgid "System repo updated successfully"
msgstr "System-Repo erfolgreich aktualisiert"
-#: tronbyt_server/routers/manager.py:1833
+#: tronbyt_server/routers/manager.py:1879
#, python-brace-format
msgid "✅ {result['message']}"
msgstr "✅ {result['message']}"
-#: tronbyt_server/routers/manager.py:1835
+#: tronbyt_server/routers/manager.py:1881
#, python-brace-format
msgid "ℹ️ {result['message']}"
msgstr "ℹ️ {result['message']}"
-#: tronbyt_server/routers/manager.py:1837
+#: tronbyt_server/routers/manager.py:1883
#, python-brace-format
msgid "❌ {result['message']}"
msgstr "❌ {result['message']}"
-#: tronbyt_server/routers/manager.py:1840
+#: tronbyt_server/routers/manager.py:1886
#, python-brace-format
msgid "❌ Firmware update failed: {str(e)}"
msgstr "❌ Firmware-Update fehlgeschlagen: {str(e)}"
-#: tronbyt_server/routers/manager.py:1921
-#: tronbyt_server/routers/manager.py:1992
-#: tronbyt_server/routers/manager.py:2066
+#: tronbyt_server/routers/manager.py:1967
+#: tronbyt_server/routers/manager.py:2038
+#: tronbyt_server/routers/manager.py:2112
msgid "No selected file"
msgstr "Keine Datei ausgewählt"
-#: tronbyt_server/routers/manager.py:1927
-#: tronbyt_server/routers/manager.py:1995
-#: tronbyt_server/routers/manager.py:2069
+#: tronbyt_server/routers/manager.py:1973
+#: tronbyt_server/routers/manager.py:2041
+#: tronbyt_server/routers/manager.py:2115
msgid "Invalid file type. Please upload a JSON file."
msgstr "Ungültiger Dateityp. Bitte eine JSON-Datei hochladen."
-#: tronbyt_server/routers/manager.py:1937
-#: tronbyt_server/routers/manager.py:2002
-#: tronbyt_server/routers/manager.py:2076
+#: tronbyt_server/routers/manager.py:1983
+#: tronbyt_server/routers/manager.py:2048
+#: tronbyt_server/routers/manager.py:2122
msgid "Invalid JSON structure"
msgstr "Ungültige JSON-Struktur"
-#: tronbyt_server/routers/manager.py:1943
+#: tronbyt_server/routers/manager.py:1989
msgid "Invalid config file: missing device ID"
msgstr "Ungültige Konfigurationsdatei: Geräte-ID fehlt"
-#: tronbyt_server/routers/manager.py:1949
+#: tronbyt_server/routers/manager.py:1995
msgid "Not the same device id. Import skipped."
msgstr "Nicht die gleiche Geräte-ID. Import übersprungen."
-#: tronbyt_server/routers/manager.py:1959
-#: tronbyt_server/routers/manager.py:2099
+#: tronbyt_server/routers/manager.py:2005
+#: tronbyt_server/routers/manager.py:2145
msgid "Invalid device configuration file"
msgstr "Ungültige Gerätekonfigurationsdatei"
-#: tronbyt_server/routers/manager.py:1967
-#: tronbyt_server/routers/manager.py:2107
+#: tronbyt_server/routers/manager.py:2013
+#: tronbyt_server/routers/manager.py:2153
msgid "Device configuration imported successfully"
msgstr "Gerätekonfiguration erfolgreich importiert"
-#: tronbyt_server/routers/manager.py:1970
-#: tronbyt_server/routers/manager.py:2041
-#: tronbyt_server/routers/manager.py:2110
+#: tronbyt_server/routers/manager.py:2016
+#: tronbyt_server/routers/manager.py:2087
+#: tronbyt_server/routers/manager.py:2156
#, python-brace-format
msgid "Error parsing JSON file: {error}"
msgstr "Fehler beim Parsen der JSON-Datei: {error}"
-#: tronbyt_server/routers/manager.py:1976
-#: tronbyt_server/routers/manager.py:2045
+#: tronbyt_server/routers/manager.py:2022
+#: tronbyt_server/routers/manager.py:2091
#, python-brace-format
msgid "Error importing config: {error}"
msgstr "Fehler beim Importieren der Konfiguration: {error}"
-#: tronbyt_server/routers/manager.py:2037
+#: tronbyt_server/routers/manager.py:2083
msgid "User configuration imported successfully"
msgstr "Benutzerkonfiguration erfolgreich importiert"
-#: tronbyt_server/routers/manager.py:2084
+#: tronbyt_server/routers/manager.py:2130
msgid "Device ID missing in config."
msgstr "Geräte-ID fehlt in der Konfiguration."
-#: tronbyt_server/routers/manager.py:2089
+#: tronbyt_server/routers/manager.py:2135
msgid "Device already exists. Import skipped."
msgstr "Gerät existiert bereits. Import übersprungen."
@@ -429,7 +429,7 @@ msgstr "Repository-URL"
#: tronbyt_server/templates/auth/edit.html:166
#: tronbyt_server/templates/auth/edit.html:179
#: tronbyt_server/templates/manager/configapp.html:24
-#: tronbyt_server/templates/manager/configapp.html:743
+#: tronbyt_server/templates/manager/configapp.html:756
#: tronbyt_server/templates/manager/create.html:114
#: tronbyt_server/templates/manager/update.html:55
#: tronbyt_server/templates/manager/update.html:478
@@ -673,7 +673,7 @@ msgstr "Benutzer anlegen"
#: tronbyt_server/templates/manager/addapp.html:4
#: tronbyt_server/templates/manager/adminindex.html:34
-#: tronbyt_server/templates/partials/device_card.html:89
+#: tronbyt_server/templates/partials/device_card.html:94
msgid "Add App"
msgstr "App hinzufügen"
@@ -744,7 +744,7 @@ msgstr "Hochgeladene App löschen?"
#: tronbyt_server/templates/manager/updateapp.html:26
#: tronbyt_server/templates/manager/updateapp.html:370
#: tronbyt_server/templates/manager/uploadapp.html:14
-#: tronbyt_server/templates/partials/app_card.html:61
+#: tronbyt_server/templates/partials/app_card.html:63
msgid "Delete"
msgstr "Löschen"
@@ -838,9 +838,10 @@ msgstr "Anzeigedauer (Sekunden):"
#: tronbyt_server/templates/manager/adminindex.html:71
#: tronbyt_server/templates/manager/configapp.html:456
-#: tronbyt_server/templates/manager/configapp.html:923
+#: tronbyt_server/templates/manager/configapp.html:936
#: tronbyt_server/templates/manager/updateapp.html:44
#: tronbyt_server/templates/partials/app_card.html:8
+#: tronbyt_server/templates/partials/app_card.html:59
#: tronbyt_server/templates/partials/device_card.html:29
msgid "Preview"
msgstr "Vorschau"
@@ -872,7 +873,7 @@ msgid "Show Render Debug"
msgstr "Debug-Ausgabe anzeigen"
#: tronbyt_server/templates/manager/configapp.html:25
-#: tronbyt_server/templates/manager/configapp.html:766
+#: tronbyt_server/templates/manager/configapp.html:779
#: tronbyt_server/templates/manager/import_config.html:12
msgid "Cancel"
msgstr "Abbrechen"
@@ -901,23 +902,29 @@ msgstr "Standort eingeben"
msgid "Upload Image"
msgstr "Bild hochladen"
+#: tronbyt_server/templates/manager/configapp.html:469
+msgid "Please upload a valid image file (PNG, JPEG, GIF, SVG, or WebP)."
+msgstr "Bitte ein gültiges Bild hochladen (PNG, JPEG, GIF, SVG oder WebP)"
+
#: tronbyt_server/templates/manager/configapp.html:477
-msgid "Please upload a valid image file (PNG, JPEG, GIF, or SVG)."
-msgstr "Bitte ein gültiges Bild hochladen (PNG, JPEG, GIF oder SVG)"
+msgid "File size exceeds 500KB limit. Please upload a smaller image."
+msgstr ""
+"Die Dateigröße überschreitet das 500KB-Limit. Bitte laden Sie ein "
+"kleineres Bild hoch."
-#: tronbyt_server/templates/manager/configapp.html:492
+#: tronbyt_server/templates/manager/configapp.html:505
msgid "Start typing..."
msgstr "Bitte eingeben…"
-#: tronbyt_server/templates/manager/configapp.html:686
+#: tronbyt_server/templates/manager/configapp.html:699
msgid "No options available for this location"
msgstr "Keine Optionen für diesen Standort verfügbar"
-#: tronbyt_server/templates/manager/configapp.html:699
+#: tronbyt_server/templates/manager/configapp.html:712
msgid "Error loading options"
msgstr "Fehler beim Laden der Optionen"
-#: tronbyt_server/templates/manager/configapp.html:755
+#: tronbyt_server/templates/manager/configapp.html:768
#: tronbyt_server/templates/manager/update.html:119
#: tronbyt_server/templates/manager/update.html:131
msgid "Reset"
@@ -1066,7 +1073,7 @@ msgid "Upload JSON File"
msgstr "JSON-Datei hochladen"
#: tronbyt_server/templates/manager/update.html:6
-#: tronbyt_server/templates/partials/device_card.html:92
+#: tronbyt_server/templates/partials/device_card.html:97
msgid "Edit Device"
msgstr "Gerät bearbeiten"
@@ -1093,7 +1100,7 @@ msgid "Websocket URL"
msgstr "Websocket URL"
#: tronbyt_server/templates/manager/update.html:156
-#: tronbyt_server/templates/partials/device_card.html:78
+#: tronbyt_server/templates/partials/device_card.html:83
msgid "App Cycle Time (Seconds)"
msgstr "App-Zykluszeit (Sekunden)"
@@ -1102,7 +1109,7 @@ msgid "Brightness Settings"
msgstr "Helligkeitseinstellungen"
#: tronbyt_server/templates/manager/update.html:174
-#: tronbyt_server/templates/partials/device_card.html:58
+#: tronbyt_server/templates/partials/device_card.html:63
msgid "Brightness"
msgstr "Helligkeit"
@@ -1566,31 +1573,31 @@ msgstr "Keine Ausgabe für "
msgid "Last:"
msgstr "Zuletzt:"
-#: tronbyt_server/templates/partials/app_card.html:59
+#: tronbyt_server/templates/partials/app_card.html:61
msgid "Duplicate"
msgstr "Duplizieren"
-#: tronbyt_server/templates/partials/app_card.html:68
+#: tronbyt_server/templates/partials/app_card.html:70
msgid "Top"
msgstr "Nach oben"
-#: tronbyt_server/templates/partials/app_card.html:71
+#: tronbyt_server/templates/partials/app_card.html:73
msgid "Bottom"
msgstr "Nach unten"
-#: tronbyt_server/templates/partials/app_card.html:74
+#: tronbyt_server/templates/partials/app_card.html:76
msgid "Unpin"
msgstr "Entpinnen"
-#: tronbyt_server/templates/partials/app_card.html:77
+#: tronbyt_server/templates/partials/app_card.html:79
msgid "Pin"
msgstr "Anheften"
-#: tronbyt_server/templates/partials/app_card.html:80
+#: tronbyt_server/templates/partials/app_card.html:82
msgid "Disable"
msgstr "Deaktivieren"
-#: tronbyt_server/templates/partials/app_card.html:83
+#: tronbyt_server/templates/partials/app_card.html:85
msgid "Enable"
msgstr "Aktivieren"
@@ -1602,62 +1609,66 @@ msgstr "Angeheftet:"
msgid "Currently Displaying App"
msgstr "Derzeit angezeigte App"
-#: tronbyt_server/templates/partials/device_card.html:35
+#: tronbyt_server/templates/partials/device_card.html:34
+msgid "Device Info"
+msgstr "Geräteinformationen"
+
+#: tronbyt_server/templates/partials/device_card.html:39
msgid "Firmware Version:"
msgstr "Firmware-Version:"
-#: tronbyt_server/templates/partials/device_card.html:38
+#: tronbyt_server/templates/partials/device_card.html:42
msgid "Firmware Type:"
msgstr "Firmware-Typ:"
-#: tronbyt_server/templates/partials/device_card.html:41
+#: tronbyt_server/templates/partials/device_card.html:45
msgid "Protocol Version:"
msgstr "Protokoll-Version:"
-#: tronbyt_server/templates/partials/device_card.html:44
+#: tronbyt_server/templates/partials/device_card.html:48
msgid "MAC Address:"
msgstr "MAC-Adresse:"
-#: tronbyt_server/templates/partials/device_card.html:47
+#: tronbyt_server/templates/partials/device_card.html:51
msgid "Protocol Type:"
msgstr "Protokoll-Typ:"
-#: tronbyt_server/templates/partials/device_card.html:50
+#: tronbyt_server/templates/partials/device_card.html:54
msgid "Last Seen:"
msgstr "Zuletzt gesehen:"
-#: tronbyt_server/templates/partials/device_card.html:95
+#: tronbyt_server/templates/partials/device_card.html:100
msgid "Firmware"
msgstr "Firmware"
-#: tronbyt_server/templates/partials/device_card.html:103
+#: tronbyt_server/templates/partials/device_card.html:108
msgid "View:"
msgstr "Ansicht:"
-#: tronbyt_server/templates/partials/device_card.html:105
+#: tronbyt_server/templates/partials/device_card.html:110
msgid "List View"
msgstr "Listenansicht"
-#: tronbyt_server/templates/partials/device_card.html:106
+#: tronbyt_server/templates/partials/device_card.html:111
msgid "List"
msgstr "Liste"
-#: tronbyt_server/templates/partials/device_card.html:109
+#: tronbyt_server/templates/partials/device_card.html:114
msgid "Grid View"
msgstr "Rasteransicht"
-#: tronbyt_server/templates/partials/device_card.html:110
+#: tronbyt_server/templates/partials/device_card.html:115
msgid "Grid"
msgstr "Raster"
-#: tronbyt_server/templates/partials/device_card.html:113
+#: tronbyt_server/templates/partials/device_card.html:118
msgid "Collapsed View"
msgstr "Eingeklappte Ansicht"
-#: tronbyt_server/templates/partials/device_card.html:114
+#: tronbyt_server/templates/partials/device_card.html:119
msgid "Collapsed"
msgstr "Eingeklappt"
-#: tronbyt_server/templates/partials/device_card.html:118
+#: tronbyt_server/templates/partials/device_card.html:123
msgid "Drag apps to reorder"
msgstr "Apps zum Neuanordnen ziehen"