mirror of
https://github.com/gethomepage/homepage.git
synced 2026-01-07 16:02:10 +08:00
Compare commits
59 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f89093a067 | ||
|
|
e303888119 | ||
|
|
a7676c4daa | ||
|
|
535a7d2f2d | ||
|
|
656b818488 | ||
|
|
249c3eab8c | ||
|
|
6de0205d07 | ||
|
|
826fe15e15 | ||
|
|
0ce5311b5f | ||
|
|
90cb395dc6 | ||
|
|
cbf72eedab | ||
|
|
3f79a2fdda | ||
|
|
1a94453849 | ||
|
|
6045e53207 | ||
|
|
d3c6d1fe85 | ||
|
|
35a7ba77e3 | ||
|
|
57d12c32fc | ||
|
|
f09268230e | ||
|
|
98cefe37d2 | ||
|
|
01b55a17f1 | ||
|
|
aaacf2ea4b | ||
|
|
8672998f08 | ||
|
|
d8039031ca | ||
|
|
f5ad46f1e1 | ||
|
|
c1473b4045 | ||
|
|
285ae970c8 | ||
|
|
bf1c67a7ac | ||
|
|
98165bf9dd | ||
|
|
19e297e4c6 | ||
|
|
8eaa942572 | ||
|
|
ce1be46c0b | ||
|
|
da75b7b0d3 | ||
|
|
d70c618442 | ||
|
|
f4e3cafa25 | ||
|
|
dcafcb983e | ||
|
|
faac4518f5 | ||
|
|
45ba9c6961 | ||
|
|
25c5f36a0c | ||
|
|
2ff06d12b0 | ||
|
|
c3305c2cd7 | ||
|
|
7cae96a77b | ||
|
|
0a7616f0f6 | ||
|
|
5de93bcad2 | ||
|
|
c72961573b | ||
|
|
2a9c39532a | ||
|
|
2e6d760c53 | ||
|
|
d2f3098b2a | ||
|
|
22dd4e5f77 | ||
|
|
31e6c1fa86 | ||
|
|
ba44c0ae9d | ||
|
|
8c918f1ea6 | ||
|
|
ff31b36b46 | ||
|
|
01704ec38b | ||
|
|
8a84eba232 | ||
|
|
0d28fe25f8 | ||
|
|
97a3346ff6 | ||
|
|
9d2f1ab8c8 | ||
|
|
7087ed80cc | ||
|
|
1aeb3a3b63 |
@@ -52,7 +52,7 @@
|
|||||||
- Coin Market Cap, Mastodon
|
- Coin Market Cap, Mastodon
|
||||||
- Information & Utility Widgets
|
- Information & Utility Widgets
|
||||||
- System Stats (Disk, CPU, Memory)
|
- System Stats (Disk, CPU, Memory)
|
||||||
- Weather via WeatherAPI.com or OpenWeatherMap
|
- Weather via [OpenWeatherMap](https://openweathermap.org/) or [Open-Meteo](https://open-meteo.com/)
|
||||||
- Search Bar
|
- Search Bar
|
||||||
- Customizable
|
- Customizable
|
||||||
- 21 theme colors with light and dark mode support
|
- 21 theme colors with light and dark mode support
|
||||||
|
|||||||
@@ -355,5 +355,11 @@
|
|||||||
"seed": "Seed",
|
"seed": "Seed",
|
||||||
"download": "Download",
|
"download": "Download",
|
||||||
"upload": "Upload"
|
"upload": "Upload"
|
||||||
|
},
|
||||||
|
"flood": {
|
||||||
|
"download": "Download",
|
||||||
|
"upload": "Upload",
|
||||||
|
"leech": "Leech",
|
||||||
|
"seed": "Seed"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -355,5 +355,11 @@
|
|||||||
"download": "Download",
|
"download": "Download",
|
||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"leech": "Leech"
|
"leech": "Leech"
|
||||||
|
},
|
||||||
|
"flood": {
|
||||||
|
"leech": "Leech",
|
||||||
|
"seed": "Seed",
|
||||||
|
"download": "Download",
|
||||||
|
"upload": "Upload"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -355,5 +355,11 @@
|
|||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"leech": "Leech",
|
"leech": "Leech",
|
||||||
"seed": "Seed"
|
"seed": "Seed"
|
||||||
|
},
|
||||||
|
"flood": {
|
||||||
|
"download": "Download",
|
||||||
|
"upload": "Upload",
|
||||||
|
"leech": "Leech",
|
||||||
|
"seed": "Seed"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -355,5 +355,11 @@
|
|||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"leech": "Leech",
|
"leech": "Leech",
|
||||||
"seed": "Seed"
|
"seed": "Seed"
|
||||||
|
},
|
||||||
|
"flood": {
|
||||||
|
"download": "Download",
|
||||||
|
"upload": "Upload",
|
||||||
|
"leech": "Leech",
|
||||||
|
"seed": "Seed"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -355,5 +355,11 @@
|
|||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"leech": "Leech",
|
"leech": "Leech",
|
||||||
"seed": "Seed"
|
"seed": "Seed"
|
||||||
|
},
|
||||||
|
"flood": {
|
||||||
|
"leech": "Leech",
|
||||||
|
"download": "Download",
|
||||||
|
"upload": "Upload",
|
||||||
|
"seed": "Seed"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -355,5 +355,11 @@
|
|||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"leech": "Leech",
|
"leech": "Leech",
|
||||||
"seed": "Seed"
|
"seed": "Seed"
|
||||||
|
},
|
||||||
|
"flood": {
|
||||||
|
"download": "Download",
|
||||||
|
"upload": "Upload",
|
||||||
|
"leech": "Leech",
|
||||||
|
"seed": "Seed"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,6 +70,12 @@
|
|||||||
"bitrate": "Bitrate",
|
"bitrate": "Bitrate",
|
||||||
"no_active": "No Active Streams"
|
"no_active": "No Active Streams"
|
||||||
},
|
},
|
||||||
|
"flood": {
|
||||||
|
"download": "Download",
|
||||||
|
"upload": "Upload",
|
||||||
|
"leech": "Leech",
|
||||||
|
"seed": "Seed"
|
||||||
|
},
|
||||||
"changedetectionio": {
|
"changedetectionio": {
|
||||||
"totalObserved": "Total Observed",
|
"totalObserved": "Total Observed",
|
||||||
"diffsDetected": "Diffs Detected"
|
"diffsDetected": "Diffs Detected"
|
||||||
|
|||||||
@@ -355,5 +355,11 @@
|
|||||||
"leech": "Leech",
|
"leech": "Leech",
|
||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"seed": "Seed"
|
"seed": "Seed"
|
||||||
|
},
|
||||||
|
"flood": {
|
||||||
|
"download": "Download",
|
||||||
|
"upload": "Upload",
|
||||||
|
"leech": "Leech",
|
||||||
|
"seed": "Seed"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,7 +105,7 @@
|
|||||||
"pending": "Pendiente",
|
"pending": "Pendiente",
|
||||||
"approved": "Aprobado",
|
"approved": "Aprobado",
|
||||||
"available": "Disponible",
|
"available": "Disponible",
|
||||||
"processing": "Processing"
|
"processing": "Procesando"
|
||||||
},
|
},
|
||||||
"sabnzbd": {
|
"sabnzbd": {
|
||||||
"rate": "Tasa",
|
"rate": "Tasa",
|
||||||
@@ -139,7 +139,7 @@
|
|||||||
"transmission": {
|
"transmission": {
|
||||||
"download": "Bajada",
|
"download": "Bajada",
|
||||||
"upload": "Subida",
|
"upload": "Subida",
|
||||||
"leech": "Compañeros",
|
"leech": "Leech",
|
||||||
"seed": "Semillas"
|
"seed": "Semillas"
|
||||||
},
|
},
|
||||||
"jackett": {
|
"jackett": {
|
||||||
@@ -164,7 +164,7 @@
|
|||||||
"qbittorrent": {
|
"qbittorrent": {
|
||||||
"download": "Bajada",
|
"download": "Bajada",
|
||||||
"upload": "Subida",
|
"upload": "Subida",
|
||||||
"leech": "Compañeros",
|
"leech": "Leech",
|
||||||
"seed": "Semillas"
|
"seed": "Semillas"
|
||||||
},
|
},
|
||||||
"mastodon": {
|
"mastodon": {
|
||||||
@@ -351,8 +351,14 @@
|
|||||||
"seed": "Semilla"
|
"seed": "Semilla"
|
||||||
},
|
},
|
||||||
"diskstation": {
|
"diskstation": {
|
||||||
"download": "Download",
|
"download": "Descargar",
|
||||||
"upload": "Upload",
|
"upload": "Cargar",
|
||||||
|
"leech": "Leech",
|
||||||
|
"seed": "Semilla"
|
||||||
|
},
|
||||||
|
"flood": {
|
||||||
|
"download": "Descargar",
|
||||||
|
"upload": "Subir",
|
||||||
"leech": "Leech",
|
"leech": "Leech",
|
||||||
"seed": "Seed"
|
"seed": "Seed"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -355,5 +355,11 @@
|
|||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"leech": "Leech",
|
"leech": "Leech",
|
||||||
"seed": "Seed"
|
"seed": "Seed"
|
||||||
|
},
|
||||||
|
"flood": {
|
||||||
|
"download": "Download",
|
||||||
|
"upload": "Upload",
|
||||||
|
"leech": "Leech",
|
||||||
|
"seed": "Seed"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -351,8 +351,14 @@
|
|||||||
"seed": "Seed"
|
"seed": "Seed"
|
||||||
},
|
},
|
||||||
"diskstation": {
|
"diskstation": {
|
||||||
"download": "Download",
|
"download": "Réception",
|
||||||
"upload": "Upload",
|
"upload": "Envoi",
|
||||||
|
"leech": "Leech",
|
||||||
|
"seed": "Seed"
|
||||||
|
},
|
||||||
|
"flood": {
|
||||||
|
"download": "Récep.",
|
||||||
|
"upload": "Envoi",
|
||||||
"leech": "Leech",
|
"leech": "Leech",
|
||||||
"seed": "Seed"
|
"seed": "Seed"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -355,5 +355,11 @@
|
|||||||
"leech": "Leech",
|
"leech": "Leech",
|
||||||
"download": "Download",
|
"download": "Download",
|
||||||
"seed": "Seed"
|
"seed": "Seed"
|
||||||
|
},
|
||||||
|
"flood": {
|
||||||
|
"download": "Download",
|
||||||
|
"upload": "Upload",
|
||||||
|
"leech": "Leech",
|
||||||
|
"seed": "Seed"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -355,5 +355,11 @@
|
|||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"leech": "Leech",
|
"leech": "Leech",
|
||||||
"seed": "Seed"
|
"seed": "Seed"
|
||||||
|
},
|
||||||
|
"flood": {
|
||||||
|
"download": "Download",
|
||||||
|
"upload": "Upload",
|
||||||
|
"leech": "Leech",
|
||||||
|
"seed": "Seed"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -355,5 +355,11 @@
|
|||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"leech": "Leech",
|
"leech": "Leech",
|
||||||
"seed": "Seed"
|
"seed": "Seed"
|
||||||
|
},
|
||||||
|
"flood": {
|
||||||
|
"download": "Download",
|
||||||
|
"upload": "Upload",
|
||||||
|
"leech": "Leech",
|
||||||
|
"seed": "Seed"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -355,5 +355,11 @@
|
|||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"leech": "Leech",
|
"leech": "Leech",
|
||||||
"seed": "Seed"
|
"seed": "Seed"
|
||||||
|
},
|
||||||
|
"flood": {
|
||||||
|
"download": "Download",
|
||||||
|
"upload": "Upload",
|
||||||
|
"leech": "Leech",
|
||||||
|
"seed": "Seed"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -355,5 +355,11 @@
|
|||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"leech": "Leech",
|
"leech": "Leech",
|
||||||
"seed": "Seed"
|
"seed": "Seed"
|
||||||
|
},
|
||||||
|
"flood": {
|
||||||
|
"download": "Download",
|
||||||
|
"upload": "Upload",
|
||||||
|
"leech": "Leech",
|
||||||
|
"seed": "Seed"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -355,5 +355,11 @@
|
|||||||
"download": "Download",
|
"download": "Download",
|
||||||
"leech": "Leech",
|
"leech": "Leech",
|
||||||
"seed": "Seed"
|
"seed": "Seed"
|
||||||
|
},
|
||||||
|
"flood": {
|
||||||
|
"download": "Download",
|
||||||
|
"upload": "Upload",
|
||||||
|
"leech": "Leech",
|
||||||
|
"seed": "Seed"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -355,5 +355,11 @@
|
|||||||
"download": "Download",
|
"download": "Download",
|
||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"seed": "Seed"
|
"seed": "Seed"
|
||||||
|
},
|
||||||
|
"flood": {
|
||||||
|
"download": "Download",
|
||||||
|
"upload": "Upload",
|
||||||
|
"leech": "Leech",
|
||||||
|
"seed": "Seed"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -355,5 +355,11 @@
|
|||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"leech": "Leech",
|
"leech": "Leech",
|
||||||
"seed": "Seed"
|
"seed": "Seed"
|
||||||
|
},
|
||||||
|
"flood": {
|
||||||
|
"download": "Download",
|
||||||
|
"upload": "Upload",
|
||||||
|
"leech": "Leech",
|
||||||
|
"seed": "Seed"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,7 +127,7 @@
|
|||||||
"pending": "Oczekiwane",
|
"pending": "Oczekiwane",
|
||||||
"approved": "Zaakceptowane",
|
"approved": "Zaakceptowane",
|
||||||
"available": "Dostępne",
|
"available": "Dostępne",
|
||||||
"processing": "Processing"
|
"processing": "Przetwarzane"
|
||||||
},
|
},
|
||||||
"pihole": {
|
"pihole": {
|
||||||
"queries": "Zapytania",
|
"queries": "Zapytania",
|
||||||
@@ -336,23 +336,29 @@
|
|||||||
"ping": "Ping"
|
"ping": "Ping"
|
||||||
},
|
},
|
||||||
"scrutiny": {
|
"scrutiny": {
|
||||||
"passed": "Passed",
|
"passed": "Powodzenie",
|
||||||
"failed": "Failed",
|
"failed": "Niepowodzenie",
|
||||||
"unknown": "Unknown"
|
"unknown": "Nieznane"
|
||||||
},
|
},
|
||||||
"paperlessngx": {
|
"paperlessngx": {
|
||||||
"inbox": "Inbox",
|
"inbox": "Skrzynka odbiorcza",
|
||||||
"total": "Total"
|
"total": "W sumie"
|
||||||
},
|
},
|
||||||
"deluge": {
|
"deluge": {
|
||||||
"download": "Download",
|
"download": "Pobieranie",
|
||||||
"upload": "Upload",
|
"upload": "Wysyłanie",
|
||||||
"leech": "Leech",
|
"leech": "Leech",
|
||||||
"seed": "Seed"
|
"seed": "Seed"
|
||||||
},
|
},
|
||||||
"diskstation": {
|
"diskstation": {
|
||||||
"download": "Download",
|
"download": "Pobieranie",
|
||||||
"upload": "Upload",
|
"upload": "Wysyłanie",
|
||||||
|
"leech": "Leech",
|
||||||
|
"seed": "Seed"
|
||||||
|
},
|
||||||
|
"flood": {
|
||||||
|
"download": "Pobieranie",
|
||||||
|
"upload": "Wysyłanie",
|
||||||
"leech": "Leech",
|
"leech": "Leech",
|
||||||
"seed": "Seed"
|
"seed": "Seed"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -355,5 +355,11 @@
|
|||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"leech": "Leech",
|
"leech": "Leech",
|
||||||
"seed": "Seed"
|
"seed": "Seed"
|
||||||
|
},
|
||||||
|
"flood": {
|
||||||
|
"download": "Download",
|
||||||
|
"upload": "Upload",
|
||||||
|
"leech": "Leech",
|
||||||
|
"seed": "Seed"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -366,5 +366,11 @@
|
|||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"leech": "Leech",
|
"leech": "Leech",
|
||||||
"seed": "Seed"
|
"seed": "Seed"
|
||||||
|
},
|
||||||
|
"flood": {
|
||||||
|
"download": "Download",
|
||||||
|
"upload": "Upload",
|
||||||
|
"leech": "Leech",
|
||||||
|
"seed": "Seed"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -355,5 +355,11 @@
|
|||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"leech": "Leech",
|
"leech": "Leech",
|
||||||
"seed": "Seed"
|
"seed": "Seed"
|
||||||
|
},
|
||||||
|
"flood": {
|
||||||
|
"download": "Download",
|
||||||
|
"upload": "Upload",
|
||||||
|
"leech": "Leech",
|
||||||
|
"seed": "Seed"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -355,5 +355,11 @@
|
|||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"seed": "Seed",
|
"seed": "Seed",
|
||||||
"leech": "Leech"
|
"leech": "Leech"
|
||||||
|
},
|
||||||
|
"flood": {
|
||||||
|
"upload": "Upload",
|
||||||
|
"download": "Download",
|
||||||
|
"leech": "Leech",
|
||||||
|
"seed": "Seed"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -355,5 +355,11 @@
|
|||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"leech": "Leech",
|
"leech": "Leech",
|
||||||
"seed": "Seed"
|
"seed": "Seed"
|
||||||
|
},
|
||||||
|
"flood": {
|
||||||
|
"download": "Download",
|
||||||
|
"seed": "Seed",
|
||||||
|
"upload": "Upload",
|
||||||
|
"leech": "Leech"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -355,5 +355,11 @@
|
|||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"leech": "Leech",
|
"leech": "Leech",
|
||||||
"seed": "Seed"
|
"seed": "Seed"
|
||||||
|
},
|
||||||
|
"flood": {
|
||||||
|
"download": "Download",
|
||||||
|
"upload": "Upload",
|
||||||
|
"leech": "Leech",
|
||||||
|
"seed": "Seed"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -355,5 +355,11 @@
|
|||||||
"download": "Download",
|
"download": "Download",
|
||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"seed": "Seed"
|
"seed": "Seed"
|
||||||
|
},
|
||||||
|
"flood": {
|
||||||
|
"download": "Download",
|
||||||
|
"upload": "Upload",
|
||||||
|
"leech": "Leech",
|
||||||
|
"seed": "Seed"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -355,5 +355,11 @@
|
|||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"leech": "Leech",
|
"leech": "Leech",
|
||||||
"seed": "Seed"
|
"seed": "Seed"
|
||||||
|
},
|
||||||
|
"flood": {
|
||||||
|
"download": "Download",
|
||||||
|
"upload": "Upload",
|
||||||
|
"leech": "Leech",
|
||||||
|
"seed": "Seed"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -355,5 +355,11 @@
|
|||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"leech": "Leech",
|
"leech": "Leech",
|
||||||
"seed": "Seed"
|
"seed": "Seed"
|
||||||
|
},
|
||||||
|
"flood": {
|
||||||
|
"download": "Download",
|
||||||
|
"upload": "Upload",
|
||||||
|
"seed": "Seed",
|
||||||
|
"leech": "Leech"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -355,5 +355,11 @@
|
|||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"leech": "Leech",
|
"leech": "Leech",
|
||||||
"seed": "Seed"
|
"seed": "Seed"
|
||||||
|
},
|
||||||
|
"flood": {
|
||||||
|
"download": "Download",
|
||||||
|
"upload": "Upload",
|
||||||
|
"leech": "Leech",
|
||||||
|
"seed": "Seed"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -355,5 +355,11 @@
|
|||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"leech": "Leech",
|
"leech": "Leech",
|
||||||
"seed": "Seed"
|
"seed": "Seed"
|
||||||
|
},
|
||||||
|
"flood": {
|
||||||
|
"leech": "Leech",
|
||||||
|
"download": "Download",
|
||||||
|
"upload": "Upload",
|
||||||
|
"seed": "Seed"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -355,5 +355,11 @@
|
|||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"leech": "Leech",
|
"leech": "Leech",
|
||||||
"seed": "Seed"
|
"seed": "Seed"
|
||||||
|
},
|
||||||
|
"flood": {
|
||||||
|
"download": "Download",
|
||||||
|
"upload": "Upload",
|
||||||
|
"leech": "Leech",
|
||||||
|
"seed": "Seed"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,7 +107,8 @@ export default function QuickLaunch({servicesAndBookmarks, searchString, setSear
|
|||||||
|
|
||||||
function highlightText(text) {
|
function highlightText(text) {
|
||||||
const parts = text.split(new RegExp(`(${searchString})`, 'gi'));
|
const parts = text.split(new RegExp(`(${searchString})`, 'gi'));
|
||||||
return <span>{parts.map(part => part.toLowerCase() === searchString.toLowerCase() ? <span className="bg-theme-300/10">{part}</span> : part)}</span>;
|
// eslint-disable-next-line react/no-array-index-key
|
||||||
|
return <span>{parts.map((part, i) => part.toLowerCase() === searchString.toLowerCase() ? <span key={`${searchString}_${i}`} className="bg-theme-300/10">{part}</span> : part)}</span>;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import mapIcon from "utils/weather/owm-condition-map";
|
import mapIcon from "utils/weather/openmeteo-condition-map";
|
||||||
|
|
||||||
export default function Icon({ condition, timeOfDay }) {
|
export default function Icon({ condition, timeOfDay }) {
|
||||||
const IconComponent = mapIcon(condition, timeOfDay);
|
const IconComponent = mapIcon(condition, timeOfDay);
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import cachedFetch from "utils/proxy/cached-fetch";
|
import cachedFetch from "utils/proxy/cached-fetch";
|
||||||
|
|
||||||
export default async function handler(req, res) {
|
export default async function handler(req, res) {
|
||||||
const { latitude, longitude, units, cache } = req.query;
|
const { latitude, longitude, units, cache, timezone } = req.query;
|
||||||
const degrees = units === "imperial" ? "fahrenheit" : "celsius";
|
const degrees = units === "imperial" ? "fahrenheit" : "celsius";
|
||||||
const apiUrl = `https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}&daily=sunrise,sunset¤t_weather=true&temperature_unit=${degrees}&timezone=auto`;
|
const timezeone = timezone ?? 'auto'
|
||||||
|
const apiUrl = `https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}&daily=sunrise,sunset¤t_weather=true&temperature_unit=${degrees}&timezone=${timezeone}`;
|
||||||
return res.send(await cachedFetch(apiUrl, cache));
|
return res.send(await cachedFetch(apiUrl, cache));
|
||||||
}
|
}
|
||||||
@@ -118,6 +118,7 @@ export function cleanServiceGroups(groups) {
|
|||||||
container,
|
container,
|
||||||
currency, // coinmarketcap widget
|
currency, // coinmarketcap widget
|
||||||
symbols,
|
symbols,
|
||||||
|
defaultinterval
|
||||||
} = cleanedService.widget;
|
} = cleanedService.widget;
|
||||||
|
|
||||||
cleanedService.widget = {
|
cleanedService.widget = {
|
||||||
@@ -129,6 +130,7 @@ export function cleanServiceGroups(groups) {
|
|||||||
|
|
||||||
if (currency) cleanedService.widget.currency = currency;
|
if (currency) cleanedService.widget.currency = currency;
|
||||||
if (symbols) cleanedService.widget.symbols = symbols;
|
if (symbols) cleanedService.widget.symbols = symbols;
|
||||||
|
if (defaultinterval) cleanedService.widget.defaultinterval = defaultinterval;
|
||||||
|
|
||||||
if (type === "docker") {
|
if (type === "docker") {
|
||||||
if (server) cleanedService.widget.server = server;
|
if (server) cleanedService.widget.server = server;
|
||||||
|
|||||||
211
src/utils/weather/openmeteo-condition-map.js
Normal file
211
src/utils/weather/openmeteo-condition-map.js
Normal file
@@ -0,0 +1,211 @@
|
|||||||
|
import * as Icons from "react-icons/wi";
|
||||||
|
|
||||||
|
// see https://open-meteo.com/en/docs
|
||||||
|
|
||||||
|
const conditions = [
|
||||||
|
{
|
||||||
|
code: 1,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayCloudy,
|
||||||
|
night: Icons.WiNightAltCloudy,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 2,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayCloudy,
|
||||||
|
night: Icons.WiNightAltCloudy,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 3,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayCloudy,
|
||||||
|
night: Icons.WiNightAltCloudy,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 45,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayFog,
|
||||||
|
night: Icons.WiNightFog,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 48,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayFog,
|
||||||
|
night: Icons.WiNightFog,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 51,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDaySprinkle,
|
||||||
|
night: Icons.WiNightAltSprinkle,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 53,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDaySprinkle,
|
||||||
|
night: Icons.WiNightAltSprinkle,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 55,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDaySprinkle,
|
||||||
|
night: Icons.WiNightAltSprinkle,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 56,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDaySleet,
|
||||||
|
night: Icons.WiNightAltSleet,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 57,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDaySleet,
|
||||||
|
night: Icons.WiNightAltSleet,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 61,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayShowers,
|
||||||
|
night: Icons.WiNightAltShowers,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 63,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayShowers,
|
||||||
|
night: Icons.WiNightAltShowers,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 65,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayShowers,
|
||||||
|
night: Icons.WiNightAltShowers,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 66,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDaySleet,
|
||||||
|
night: Icons.WiNightAltSleet,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 67,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDaySleet,
|
||||||
|
night: Icons.WiNightAltSleet,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 71,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDaySnow,
|
||||||
|
night: Icons.WiNightAltSnow,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 73,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDaySnow,
|
||||||
|
night: Icons.WiNightAltSnow,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 75,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDaySnow,
|
||||||
|
night: Icons.WiNightAltSnow,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 77,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDaySnow,
|
||||||
|
night: Icons.WiNightAltSnow,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 80,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDaySnow,
|
||||||
|
night: Icons.WiNightAltSnow,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 81,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDaySnow,
|
||||||
|
night: Icons.WiNightAltSnow,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 82,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDaySnow,
|
||||||
|
night: Icons.WiNightAltSnow,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 85,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDaySnow,
|
||||||
|
night: Icons.WiNightAltSnow,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 86,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDaySnow,
|
||||||
|
night: Icons.WiNightAltSnow,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 95,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayThunderstorm,
|
||||||
|
night: Icons.WiNightAltThunderstorm,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 96,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayThunderstorm,
|
||||||
|
night: Icons.WiNightAltThunderstorm,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 99,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayThunderstorm,
|
||||||
|
night: Icons.WiNightAltThunderstorm,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function mapIcon(weatherStatusCode, timeOfDay) {
|
||||||
|
const mapping = conditions.find((condition) => condition.code === weatherStatusCode);
|
||||||
|
|
||||||
|
if (mapping) {
|
||||||
|
if (timeOfDay === "day") {
|
||||||
|
return mapping.icon.day;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timeOfDay === "night") {
|
||||||
|
return mapping.icon.night;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Icons.WiDaySunny;
|
||||||
|
}
|
||||||
@@ -17,11 +17,12 @@ export default function Component({ service }) {
|
|||||||
{ label: t("coinmarketcap.30days"), value: "30d" },
|
{ label: t("coinmarketcap.30days"), value: "30d" },
|
||||||
];
|
];
|
||||||
|
|
||||||
const [dateRange, setDateRange] = useState(dateRangeOptions[0].value);
|
|
||||||
|
|
||||||
const { widget } = service;
|
const { widget } = service;
|
||||||
const { symbols } = widget;
|
const { symbols } = widget;
|
||||||
const currencyCode = widget.currency ?? "USD";
|
const currencyCode = widget.currency ?? "USD";
|
||||||
|
const interval = widget.defaultinterval ?? dateRangeOptions[0].value;
|
||||||
|
|
||||||
|
const [dateRange, setDateRange] = useState(interval);
|
||||||
|
|
||||||
const { data: statsData, error: statsError } = useWidgetAPI(widget, "v1/cryptocurrency/quotes/latest", {
|
const { data: statsData, error: statsError } = useWidgetAPI(widget, "v1/cryptocurrency/quotes/latest", {
|
||||||
symbol: `${symbols.join(",")}`,
|
symbol: `${symbols.join(",")}`,
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ const components = {
|
|||||||
diskstation: dynamic(() => import("./diskstation/component")),
|
diskstation: dynamic(() => import("./diskstation/component")),
|
||||||
docker: dynamic(() => import("./docker/component")),
|
docker: dynamic(() => import("./docker/component")),
|
||||||
emby: dynamic(() => import("./emby/component")),
|
emby: dynamic(() => import("./emby/component")),
|
||||||
|
flood: dynamic(() => import("./flood/component")),
|
||||||
gluetun: dynamic(() => import("./gluetun/component")),
|
gluetun: dynamic(() => import("./gluetun/component")),
|
||||||
gotify: dynamic(() => import("./gotify/component")),
|
gotify: dynamic(() => import("./gotify/component")),
|
||||||
hdhomerun: dynamic(() => import("./hdhomerun/component")),
|
hdhomerun: dynamic(() => import("./hdhomerun/component")),
|
||||||
|
|||||||
@@ -46,7 +46,9 @@ export default function Component({ service }) {
|
|||||||
return (
|
return (
|
||||||
<Container service={service}>
|
<Container service={service}>
|
||||||
<Block label="docker.cpu" value={t("common.percent", { value: calculateCPUPercent(statsData.stats) })} />
|
<Block label="docker.cpu" value={t("common.percent", { value: calculateCPUPercent(statsData.stats) })} />
|
||||||
<Block label="docker.mem" value={t("common.bytes", { value: statsData.stats.memory_stats.usage })} />
|
{statsData.stats.memory_stats.usage &&
|
||||||
|
<Block label="docker.mem" value={t("common.bytes", { value: statsData.stats.memory_stats.usage })} />
|
||||||
|
}
|
||||||
{network && (
|
{network && (
|
||||||
<>
|
<>
|
||||||
<Block label="docker.rx" value={t("common.bytes", { value: network.rx_bytes })} />
|
<Block label="docker.rx" value={t("common.bytes", { value: network.rx_bytes })} />
|
||||||
|
|||||||
53
src/widgets/flood/component.jsx
Normal file
53
src/widgets/flood/component.jsx
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
import { useTranslation } from "next-i18next";
|
||||||
|
|
||||||
|
import Container from "components/services/widget/container";
|
||||||
|
import Block from "components/services/widget/block";
|
||||||
|
import useWidgetAPI from "utils/proxy/use-widget-api";
|
||||||
|
|
||||||
|
export default function Component({ service }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const { widget } = service;
|
||||||
|
|
||||||
|
const { data: torrentData, error: torrentError } = useWidgetAPI(widget, "torrents");
|
||||||
|
|
||||||
|
if (torrentError) {
|
||||||
|
return <Container error={torrentError} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!torrentData) {
|
||||||
|
return (
|
||||||
|
<Container service={service}>
|
||||||
|
<Block label="flood.leech" />
|
||||||
|
<Block label="flood.download" />
|
||||||
|
<Block label="flood.seed" />
|
||||||
|
<Block label="flood.upload" />
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let rateDl = 0;
|
||||||
|
let rateUl = 0;
|
||||||
|
let completed = 0;
|
||||||
|
let leech = 0;
|
||||||
|
|
||||||
|
Object.values(torrentData.torrents).forEach(torrent => {
|
||||||
|
rateDl += torrent.downRate;
|
||||||
|
rateUl += torrent.upRate;
|
||||||
|
if(torrent.status.includes('complete')){
|
||||||
|
completed += 1;
|
||||||
|
}
|
||||||
|
if(torrent.status.includes('downloading')){
|
||||||
|
leech += 1;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Container service={service}>
|
||||||
|
<Block label="flood.leech" value={t("common.number", { value: leech })} />
|
||||||
|
<Block label="flood.download" value={t("common.bitrate", { value: rateDl })} />
|
||||||
|
<Block label="flood.seed" value={t("common.number", { value: completed })} />
|
||||||
|
<Block label="flood.upload" value={t("common.bitrate", { value: rateUl })} />
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
}
|
||||||
66
src/widgets/flood/proxy.js
Normal file
66
src/widgets/flood/proxy.js
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
import { formatApiCall } from "utils/proxy/api-helpers";
|
||||||
|
import { httpProxy } from "utils/proxy/http";
|
||||||
|
import getServiceWidget from "utils/config/service-helpers";
|
||||||
|
import createLogger from "utils/logger";
|
||||||
|
|
||||||
|
const logger = createLogger("floodProxyHandler");
|
||||||
|
|
||||||
|
async function login(widget) {
|
||||||
|
logger.debug("flood is rejecting the request, logging in.");
|
||||||
|
const loginUrl = new URL(`${widget.url}/api/auth/authenticate`).toString();
|
||||||
|
|
||||||
|
const loginParams = {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: null
|
||||||
|
};
|
||||||
|
|
||||||
|
if (widget.username && widget.password) {
|
||||||
|
loginParams.body = JSON.stringify({
|
||||||
|
"username": widget.username,
|
||||||
|
"password": widget.password
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
const [status, contentType, data] = await httpProxy(loginUrl, loginParams);
|
||||||
|
return [status, data];
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async function floodProxyHandler(req, res) {
|
||||||
|
const { group, service, endpoint } = req.query;
|
||||||
|
|
||||||
|
if (!group || !service) {
|
||||||
|
logger.debug("Invalid or missing service '%s' or group '%s'", service, group);
|
||||||
|
return res.status(400).json({ error: "Invalid proxy service type" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const widget = await getServiceWidget(group, service);
|
||||||
|
|
||||||
|
if (!widget) {
|
||||||
|
logger.debug("Invalid or missing widget for service '%s' in group '%s'", service, group);
|
||||||
|
return res.status(400).json({ error: "Invalid proxy service type" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const url = new URL(formatApiCall("{url}/api/{endpoint}", { endpoint, ...widget }));
|
||||||
|
const params = { method: "GET", headers: {} };
|
||||||
|
|
||||||
|
let [status, contentType, data] = await httpProxy(url, params);
|
||||||
|
if (status === 401) {
|
||||||
|
[status, data] = await login(widget);
|
||||||
|
|
||||||
|
if (status !== 200) {
|
||||||
|
logger.error("HTTP %d logging in to flood. Data: %s", status, data);
|
||||||
|
return res.status(status).end(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
[status, contentType, data] = await httpProxy(url, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status !== 200) {
|
||||||
|
logger.error("HTTP %d getting data from flood. Data: %s", status, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (contentType) res.setHeader("Content-Type", contentType);
|
||||||
|
return res.status(status).send(data);
|
||||||
|
}
|
||||||
7
src/widgets/flood/widget.js
Normal file
7
src/widgets/flood/widget.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import floodProxyHandler from "./proxy";
|
||||||
|
|
||||||
|
const widget = {
|
||||||
|
proxyHandler: floodProxyHandler,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default widget;
|
||||||
@@ -2,16 +2,37 @@ import Container from "components/services/widget/container";
|
|||||||
import Block from "components/services/widget/block";
|
import Block from "components/services/widget/block";
|
||||||
import useWidgetAPI from "utils/proxy/use-widget-api";
|
import useWidgetAPI from "utils/proxy/use-widget-api";
|
||||||
|
|
||||||
|
|
||||||
|
// @see https://github.com/AnalogJ/scrutiny/blob/d8d56f77f9e868127c4849dac74d65512db658e8/webapp/frontend/src/app/shared/device-status.pipe.ts
|
||||||
|
const DeviceStatus = {
|
||||||
|
passed: 0,
|
||||||
|
failed_smart: 1,
|
||||||
|
failed_scrutiny: 2,
|
||||||
|
failed_both: 3,
|
||||||
|
|
||||||
|
isFailed(s){ return s > this.passed && s <= this.failed_both},
|
||||||
|
isUnknown(s){ return s < this.passed || s > this.failed_both}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @see https://github.com/AnalogJ/scrutiny/blob/d8d56f77f9e868127c4849dac74d65512db658e8/webapp/frontend/src/app/core/config/app.config.ts
|
||||||
|
const DeviceStatusThreshold = {
|
||||||
|
smart: 1,
|
||||||
|
scrutiny: 2,
|
||||||
|
both: 3
|
||||||
|
}
|
||||||
|
|
||||||
export default function Component({ service }) {
|
export default function Component({ service }) {
|
||||||
const { widget } = service;
|
const { widget } = service;
|
||||||
|
|
||||||
|
const { data: scrutinySettings, error: scrutinySettingsError } = useWidgetAPI(widget, "settings");
|
||||||
const { data: scrutinyData, error: scrutinyError } = useWidgetAPI(widget, "summary");
|
const { data: scrutinyData, error: scrutinyError } = useWidgetAPI(widget, "summary");
|
||||||
|
|
||||||
if (scrutinyError) {
|
if (scrutinyError || scrutinySettingsError) {
|
||||||
return <Container error={scrutinyError} />;
|
const finalError = scrutinyError ?? scrutinySettingsError;
|
||||||
|
return <Container error={finalError} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!scrutinyData) {
|
if (!scrutinyData || !scrutinySettings) {
|
||||||
return (
|
return (
|
||||||
<Container service={service}>
|
<Container service={service}>
|
||||||
<Block label="scrutiny.passed" />
|
<Block label="scrutiny.passed" />
|
||||||
@@ -19,13 +40,14 @@ export default function Component({ service }) {
|
|||||||
<Block label="scrutiny.unknown" />
|
<Block label="scrutiny.unknown" />
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const deviceIds = Object.values(scrutinyData.data.summary);
|
const deviceIds = Object.values(scrutinyData.data.summary);
|
||||||
|
const statusThreshold = scrutinySettings.settings.metrics.status_threshold;
|
||||||
const passed = deviceIds.filter(deviceId => deviceId.device.device_status === 0)?.length || 0;
|
|
||||||
const failed = deviceIds.filter(deviceId => deviceId.device.device_status > 0 && deviceId.device.device_status <= 3)?.length || 0;
|
const failed = deviceIds.filter(deviceId => (DeviceStatus.isFailed(deviceId.device.device_status) && statusThreshold === DeviceStatusThreshold.both) || [statusThreshold, DeviceStatus.failed_both].includes(deviceId.device.device_status))?.length || 0;
|
||||||
const unknown = deviceIds.length - (passed + failed) || 0;
|
const unknown = deviceIds.filter(deviceId => DeviceStatus.isUnknown(deviceId.device.device_status))?.length || 0;
|
||||||
|
const passed = deviceIds.length - (failed + unknown);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container service={service}>
|
<Container service={service}>
|
||||||
@@ -33,5 +55,8 @@ export default function Component({ service }) {
|
|||||||
<Block label="scrutiny.failed" value={failed} />
|
<Block label="scrutiny.failed" value={failed} />
|
||||||
<Block label="scrutiny.unknown" value={unknown} />
|
<Block label="scrutiny.unknown" value={unknown} />
|
||||||
</Container>
|
</Container>
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,12 @@ const widget = {
|
|||||||
"data",
|
"data",
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
settings: {
|
||||||
|
endpoint: "settings",
|
||||||
|
validate: [
|
||||||
|
"settings",
|
||||||
|
]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import coinmarketcap from "./coinmarketcap/widget";
|
|||||||
import deluge from "./deluge/widget";
|
import deluge from "./deluge/widget";
|
||||||
import diskstation from "./diskstation/widget";
|
import diskstation from "./diskstation/widget";
|
||||||
import emby from "./emby/widget";
|
import emby from "./emby/widget";
|
||||||
|
import flood from "./flood/widget";
|
||||||
import gluetun from "./gluetun/widget";
|
import gluetun from "./gluetun/widget";
|
||||||
import gotify from "./gotify/widget";
|
import gotify from "./gotify/widget";
|
||||||
import hdhomerun from "./hdhomerun/widget";
|
import hdhomerun from "./hdhomerun/widget";
|
||||||
@@ -54,6 +55,7 @@ const widgets = {
|
|||||||
deluge,
|
deluge,
|
||||||
diskstation,
|
diskstation,
|
||||||
emby,
|
emby,
|
||||||
|
flood,
|
||||||
gluetun,
|
gluetun,
|
||||||
gotify,
|
gotify,
|
||||||
hdhomerun,
|
hdhomerun,
|
||||||
|
|||||||
Reference in New Issue
Block a user