Compare commits

...

188 Commits

Author SHA1 Message Date
shamoon
d4a39299c5 Fix k8s traefikingresslist detection (#2030) 2023-09-19 15:00:22 -07:00
shamoon
7d2bfa2d84 Update index.jsx 2023-09-19 14:10:19 -07:00
shamoon
c094bd3d83 Update service-helpers.js 2023-09-19 13:12:03 -07:00
Daniel Li
69ee459e8a Fix: SMART result of OMV should always from monitored devices (#2025) 2023-09-19 08:46:16 -07:00
shamoon
ed0527a3da Fix custom.js not working (#2023) 2023-09-18 21:41:31 -07:00
shamoon
04a1c68ba0 Fix k3d memory specification 2023-09-18 14:35:42 -07:00
Pysta
b74faea449 Translated using Weblate (Slovak)
Currently translated at 24.1% (129 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/sk/
2023-09-18 14:23:36 +02:00
avb15621
0c9b6480c5 Translated using Weblate (Dutch)
Currently translated at 53.9% (288 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nl/
2023-09-18 14:23:35 +02:00
Roel van de Wiel
6fbb3bfbb1 Translated using Weblate (Dutch)
Currently translated at 53.9% (288 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nl/
2023-09-18 14:23:35 +02:00
A Warmerdam
53355561a8 Translated using Weblate (Dutch)
Currently translated at 53.9% (288 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nl/
2023-09-18 14:23:35 +02:00
Jan-Philipp Fischer
6e43194f71 Fix: Kubernetes discovery & Check for Custom Resource Definitions (#2003)
* Implement a CRD existence check

* test adding patch
2023-09-17 16:49:03 -07:00
shamoon
a72a27a8b5 Maybe handle k8s traefik ingress routes returns nothing 2023-09-17 10:05:45 -07:00
Ben Phelps
6c682cb648 Update README.md 2023-09-17 11:00:15 +03:00
Ben Phelps
e7587b8308 update readme image 2023-09-17 10:57:37 +03:00
shamoon
e663994c9b Allow tab name 0 2023-09-16 15:24:32 -07:00
shamoon
898fb88d86 Allow numbers in tab name (#2004) 2023-09-16 14:37:06 -07:00
Ben Phelps
6f5c2a8c1e update readme 2023-09-16 22:16:34 +03:00
shamoon
2908bfcb7c Update service-helpers.js 2023-09-16 08:59:36 -07:00
shamoon
34589f0514 reduce k8s traefik discovery log noise 2023-09-16 08:28:58 -07:00
shamoon
3cd441a45e Maybe handle no traefik ingress routes
See #1998
2023-09-16 08:06:24 -07:00
shamoon
816a2a5106 Fix ping stats not clickable in 0.6.30
Closes #1997
2023-09-16 07:37:31 -07:00
shamoon
38079badc8 Pixel-perfect aligned edges 2023-09-16 02:37:24 -07:00
Denis Papec
5109facf1c Fix layouts for initial tab (#1996) 2023-09-15 09:55:23 -07:00
shamoon
ee0afaa638 Fix activeTab with no layout settings
Closes #1995
2023-09-15 09:22:37 -07:00
shamoon
42b69e44a2 replace spaces in tab slugify 2023-09-15 08:35:24 -07:00
shamoon
6dc3be6029 Fix: slugify tab names (#1994) 2023-09-15 08:17:57 -07:00
shamoon
ec1cf2f3ca Resolve bad setState warning in tabprovider (#1993) 2023-09-15 08:00:08 -07:00
shamoon
cde8c658ae Fix duplicate keys on customapi widget 2023-09-15 07:47:10 -07:00
Denis Papec
8a520e07a5 Fix for broken layout when layout is not defined (#1989)
* Fix for broken layout when layout is not defined

* code style

---------

Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
2023-09-15 07:41:56 -07:00
Greg Look
eb2b37063f Enhancement: add remap, scale, and suffx to customapi fields (#1958) 2023-09-14 23:50:54 -07:00
Denis Papec
2d8160512f Feature: tabbed layouts (#1981) 2023-09-14 14:55:14 -07:00
shamoon
768107cde8 Update index.jsx 2023-09-14 00:18:43 -07:00
Gino Cicatiello
9fb0917054 Translated using Weblate (Italian)
Currently translated at 100.0% (534 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/it/
2023-09-13 05:57:42 +02:00
shamoon
1895899839 Merge pull request #1974 from benphelps/dependabot/github_actions/docker/setup-buildx-action-3
Bump docker/setup-buildx-action from 2 to 3
2023-09-12 11:02:08 -07:00
shamoon
ec25af781c Merge pull request #1973 from benphelps/dependabot/github_actions/docker/build-push-action-5
Bump docker/build-push-action from 4 to 5
2023-09-12 11:01:54 -07:00
dependabot[bot]
bda567e961 Bump docker/build-push-action from 4 to 5
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 4 to 5.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](https://github.com/docker/build-push-action/compare/v4...v5)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-12 17:29:15 +00:00
shamoon
c525dda77d Merge pull request #1972 from benphelps/dependabot/github_actions/docker/setup-qemu-action-3
Bump docker/setup-qemu-action from 2 to 3
2023-09-12 10:28:27 -07:00
shamoon
65a0b9f905 Merge pull request #1971 from benphelps/dependabot/github_actions/docker/metadata-action-5
Bump docker/metadata-action from 4 to 5
2023-09-12 10:12:52 -07:00
shamoon
74e3a3f09c Merge pull request #1970 from benphelps/dependabot/github_actions/docker/login-action-3
Bump docker/login-action from 2 to 3
2023-09-12 10:02:08 -07:00
dependabot[bot]
d610d379f8 Bump docker/setup-buildx-action from 2 to 3
Bumps [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) from 2 to 3.
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](https://github.com/docker/setup-buildx-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: docker/setup-buildx-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-12 16:46:19 +00:00
dependabot[bot]
e3acc444d8 Bump docker/setup-qemu-action from 2 to 3
Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 2 to 3.
- [Release notes](https://github.com/docker/setup-qemu-action/releases)
- [Commits](https://github.com/docker/setup-qemu-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: docker/setup-qemu-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-12 16:46:03 +00:00
dependabot[bot]
16299ced66 Bump docker/metadata-action from 4 to 5
Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 4 to 5.
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Upgrade guide](https://github.com/docker/metadata-action/blob/master/UPGRADE.md)
- [Commits](https://github.com/docker/metadata-action/compare/v4...v5)

---
updated-dependencies:
- dependency-name: docker/metadata-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-12 16:45:55 +00:00
dependabot[bot]
3a018d5a63 Bump docker/login-action from 2 to 3
Bumps [docker/login-action](https://github.com/docker/login-action) from 2 to 3.
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](https://github.com/docker/login-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: docker/login-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-12 16:45:50 +00:00
TheRolf
b39c79bea1 Custom JS and CSS (#1950)
* First commit for custom styles and JS

* Adjusted classes

* Added ids and classes for services and bookmarks

* Apply suggestions from code review

* Remove mime dependency

* Update settings.json

* Detect custom css / js changes, no refresh

* Added preload to custom scripts and styles so they can load earlier

* Added data attribute name for bookmarks too

* Update [path].js

* code style, revert some pointer changes

---------

Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
2023-09-10 14:36:54 -07:00
Vojislav
0741ef0427 Added start_url in manifest.json to fulfill requirements for installable app (#1955)
Co-authored-by: Vojislav Zelić <vodzo@Vojislavs-MacBook-Air.local>
2023-09-09 11:25:29 -07:00
Alex Tzonkov
bce43c28d6 Translated using Weblate (Bulgarian)
Currently translated at 15.1% (81 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/bg/
2023-09-09 15:52:35 +02:00
gallegonovato
e94796f878 Translated using Weblate (Spanish)
Currently translated at 100.0% (534 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2023-09-09 15:52:34 +02:00
CosminPerRam
2ee6881376 Update GameDig dependency to 4.1.0 and revert compressjs fix. (#1939)
* Update GD to 4.1.0 and revert compressjs fix

* Update package-lock
2023-09-09 06:18:38 -07:00
shamoon
95635fca04 Revert "Enhancement: forward cookies from request (#1804)" (#1946)
This reverts commit d4edd432d8.
2023-09-09 06:07:04 -07:00
Nils Gereke
4f1cde97ec fix: total servers only representing last node (#1936) 2023-09-09 06:04:41 -07:00
James Waters
d4edd432d8 Enhancement: forward cookies from request (#1804) 2023-09-08 16:50:32 -07:00
shamoon
63f952509e Support disable glances cpu + mem (#1931) 2023-09-08 08:59:04 -07:00
shamoon
89f2e9739d Fix error glances cpu data not available yet (#1932) 2023-09-08 08:58:56 -07:00
Ben Phelps
9569f56aa5 attempt a fix (#1929) 2023-09-08 08:58:39 -07:00
shamoon
ae3634e9d4 Change crossorigin to crossOrigin
Co-Authored-By: Shagon94 <9140783+shagon94@users.noreply.github.com>
2023-09-08 07:16:36 -07:00
Gino Cicatiello
f96154189b Translated using Weblate (Italian)
Currently translated at 99.8% (533 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/it/
2023-09-08 04:31:23 +02:00
BluePhi09
402f86fc1b Translated using Weblate (German)
Currently translated at 97.9% (523 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/de/
2023-09-08 04:31:23 +02:00
shamoon
3f71bff13f fix blur on bookmark items 2023-09-06 21:27:24 -07:00
shamoon
a061eccef5 Merge pull request #1920 from benphelps/fix/ping-blocks-link
Fix: remove pointer events on ping div
2023-09-06 12:46:06 -07:00
shamoon
957bd9491b remove pointer events on ping div 2023-09-06 12:45:03 -07:00
Ben Phelps
7a1f8850b8 pass chart to all containers 2023-09-06 15:28:37 +03:00
Anonymous
ef3da08d93 Translated using Weblate (Basque)
Currently translated at 6.3% (34 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/eu/
2023-09-06 13:08:39 +02:00
Anonymous
5a67bcd14d Translated using Weblate (Indonesian)
Currently translated at 4.4% (24 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/id/
2023-09-06 13:08:39 +02:00
Anonymous
864f4ef6cc Translated using Weblate (Slovenian)
Currently translated at 97.5% (521 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/sl/
2023-09-06 13:08:38 +02:00
Anonymous
cc88bf21a9 Translated using Weblate (Greek)
Currently translated at 33.8% (181 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/el/
2023-09-06 13:08:38 +02:00
Anonymous
a6eba9bcde Translated using Weblate (Korean)
Currently translated at 32.3% (173 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ko/
2023-09-06 13:08:38 +02:00
Anonymous
8bf3b3e217 Translated using Weblate (Slovak)
Currently translated at 1.8% (10 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/sk/
2023-09-06 13:08:37 +02:00
Anonymous
97c3d7c513 Translated using Weblate (Thai)
Currently translated at 8.9% (48 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/th/
2023-09-06 13:08:37 +02:00
Anonymous
13ee73f178 Translated using Weblate (Latvian)
Currently translated at 22.0% (118 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/lv/
2023-09-06 13:08:37 +02:00
Anonymous
eedc47e091 Translated using Weblate (Japanese)
Currently translated at 94.7% (506 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ja/
2023-09-06 13:08:37 +02:00
Anonymous
dc8d0f6ca9 Translated using Weblate (Ukrainian)
Currently translated at 94.7% (506 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/uk/
2023-09-06 13:08:36 +02:00
Anonymous
9811a4d5ee Translated using Weblate (Esperanto)
Currently translated at 27.1% (145 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/eo/
2023-09-06 13:08:36 +02:00
Anonymous
27f52fd981 Translated using Weblate (Hindi)
Currently translated at 1.8% (10 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/hi/
2023-09-06 13:08:36 +02:00
Anonymous
7adcd6c242 Translated using Weblate (Malay)
Currently translated at 47.1% (252 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ms/
2023-09-06 13:08:36 +02:00
Anonymous
74b73f99b7 Translated using Weblate (Danish)
Currently translated at 97.5% (521 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/da/
2023-09-06 13:08:35 +02:00
Anonymous
1841a794a4 Translated using Weblate (Czech)
Currently translated at 83.1% (444 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/cs/
2023-09-06 13:08:35 +02:00
Anonymous
bca024e3c2 Translated using Weblate (Arabic)
Currently translated at 49.0% (262 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ar/
2023-09-06 13:08:34 +02:00
Anonymous
7cb4780a9c Translated using Weblate (Serbian)
Currently translated at 1.8% (10 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/sr/
2023-09-06 13:08:34 +02:00
Anonymous
b0d68b3c0e Translated using Weblate (Turkish)
Currently translated at 73.5% (393 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/tr/
2023-09-06 13:08:34 +02:00
Anonymous
9a060b3db1 Translated using Weblate (Bulgarian)
Currently translated at 8.8% (47 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/bg/
2023-09-06 13:08:34 +02:00
Anonymous
0ffa5b8ace Translated using Weblate (Telugu)
Currently translated at 40.4% (216 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/te/
2023-09-06 13:08:33 +02:00
Anonymous
2ec96a6457 Translated using Weblate (Finnish)
Currently translated at 33.1% (177 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fi/
2023-09-06 13:08:33 +02:00
Anonymous
1098b0d4f9 Translated using Weblate (Yue (Traditional))
Currently translated at 22.0% (118 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/yue_Hant/
2023-09-06 13:08:33 +02:00
Anonymous
1ecfa382bc Translated using Weblate (Portuguese (Brazil))
Currently translated at 86.3% (461 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pt_BR/
2023-09-06 13:08:32 +02:00
Anonymous
2f83906244 Translated using Weblate (Romanian)
Currently translated at 29.2% (156 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ro/
2023-09-06 13:08:32 +02:00
Anonymous
6eacff4638 Translated using Weblate (Hebrew)
Currently translated at 18.9% (101 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/he/
2023-09-06 13:08:32 +02:00
Anonymous
e1c615de14 Translated using Weblate (Hungarian)
Currently translated at 88.2% (471 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/hu/
2023-09-06 13:08:31 +02:00
Anonymous
dd842ee7a8 Translated using Weblate (Croatian)
Currently translated at 88.0% (470 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/hr/
2023-09-06 13:08:31 +02:00
Anonymous
2681930b2e Translated using Weblate (Swedish)
Currently translated at 24.7% (132 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/sv/
2023-09-06 13:08:31 +02:00
Anonymous
4bfad4d27e Translated using Weblate (Polish)
Currently translated at 70.0% (374 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pl/
2023-09-06 13:08:31 +02:00
Anonymous
c13567bcb7 Translated using Weblate (Catalan)
Currently translated at 48.8% (261 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ca/
2023-09-06 13:08:30 +02:00
Anonymous
eb77e42264 Translated using Weblate (Chinese (Traditional))
Currently translated at 93.4% (499 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hant/
2023-09-06 13:08:30 +02:00
Anonymous
75b46509c1 Translated using Weblate (Dutch)
Currently translated at 45.5% (243 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nl/
2023-09-06 13:08:30 +02:00
Anonymous
e433d75372 Translated using Weblate (Vietnamese)
Currently translated at 8.4% (45 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/vi/
2023-09-06 13:08:29 +02:00
Anonymous
5d76ac4c7f Translated using Weblate (Norwegian Bokmål)
Currently translated at 15.1% (81 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nb_NO/
2023-09-06 13:08:29 +02:00
Anonymous
95b91b953a Translated using Weblate (Italian)
Currently translated at 99.8% (533 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/it/
2023-09-06 13:08:29 +02:00
Anonymous
63e65d721b Translated using Weblate (Chinese (Simplified))
Currently translated at 84.2% (450 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hans/
2023-09-06 13:08:29 +02:00
Anonymous
ec6deb5ac9 Translated using Weblate (Russian)
Currently translated at 80.5% (430 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ru/
2023-09-06 13:08:28 +02:00
Anonymous
b4c7faf178 Translated using Weblate (Portuguese)
Currently translated at 77.7% (415 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pt/
2023-09-06 13:08:28 +02:00
Anonymous
132ec69f29 Translated using Weblate (French)
Currently translated at 99.8% (533 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2023-09-06 13:08:28 +02:00
Anonymous
673404e441 Translated using Weblate (Spanish)
Currently translated at 99.8% (533 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2023-09-06 13:08:28 +02:00
Anonymous
e267717898 Translated using Weblate (German)
Currently translated at 97.5% (521 of 534 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/de/
2023-09-06 13:08:27 +02:00
Ben Phelps
99f60eab29 Merge pull request #1917 from benphelps/non-graphs
mini-non-chart charts
2023-09-06 14:06:37 +03:00
Ben Phelps
17b0f635d8 mini-non-chart charts 2023-09-06 13:53:39 +03:00
fenix_vd
c2058f353d Translated using Weblate (Russian)
Currently translated at 80.6% (430 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ru/
2023-09-05 14:56:10 +02:00
shamoon
3a10214a45 Merge pull request #1903 from benphelps/feature-mixed-layout
Enhancement: mixed bookmarks / services layout
2023-09-04 20:27:04 -07:00
shamoon
9713a16e1f Merge pull request #1910 from benphelps/dependabot/github_actions/actions/checkout-4
Bump actions/checkout from 3 to 4
2023-09-04 12:21:49 -07:00
dependabot[bot]
0e57547824 Bump actions/checkout from 3 to 4
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-09-04 16:51:58 +00:00
Anonymous
80eb03194f Translated using Weblate (German)
Currently translated at 97.7% (521 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/de/
2023-09-04 05:46:39 +02:00
Ettore Atalan
a0019d832e Translated using Weblate (German)
Currently translated at 97.7% (521 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/de/
2023-09-04 05:46:37 +02:00
shamoon
4517409dbd Support mixing services & bookmarks layout 2023-09-03 07:50:04 -07:00
Ben Phelps
61b969cced Merge pull request #1906 from benphelps/glances-fs
fix linting
2023-09-03 17:49:11 +03:00
shamoon
ed293071b4 Update fs.jsx 2023-09-03 07:49:05 -07:00
Ben Phelps
5d0a793195 fix linting 2023-09-03 17:47:54 +03:00
Ben Phelps
b2908cdd97 Merge pull request #1905 from benphelps/glances-fs
Add glances filesystem graph
2023-09-03 17:28:50 +03:00
Ben Phelps
108ca23212 Merge branch 'main' into glances-fs 2023-09-03 17:23:08 +03:00
Georges-Antoine Assi
9529553102 Enhancement: apply layout settings to bookmarks (#1902)
* Apply layout settings to bookmarks

* merge columnMap const

* Remove bookmarksOnTop setting

---------

Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
2023-09-03 07:05:25 -07:00
Gino Cicatiello
4d55f1fba4 Translated using Weblate (Italian)
Currently translated at 100.0% (533 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/it/
2023-09-03 09:52:24 +02:00
gallegonovato
257ab91ffb Translated using Weblate (Spanish)
Currently translated at 100.0% (533 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2023-09-03 09:52:23 +02:00
shamoon
96e8882fb5 Merge pull request #1896 from benphelps/fix/issue-1894
Fix: cardBlur with boxedWidgets shrinks search widget
2023-08-31 10:45:54 -07:00
shamoon
864eb8cfbb Fix duplicate additionalClassNames 2023-08-31 10:43:57 -07:00
shamoon
147ed30b09 Merge pull request #1893 from Spideramn/fix/manifest-credentials
Add crossorigin="use-credentials" to manifest link tag.
2023-08-31 10:41:14 -07:00
CosminPerRam
14aebf9e41 Translated using Weblate (Romanian)
Currently translated at 29.2% (156 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ro/
2023-08-31 17:55:38 +02:00
Spideramn
76013b32b3 Add crossorigin="use-credentials" to manifest link tag. 2023-08-31 11:58:51 +02:00
CosminPerRam
f0a4ab645c Update GameDig dependency to 4.0.7 (#1886) 2023-08-30 08:19:45 -07:00
Azurite
eedb728025 Translated using Weblate (Japanese)
Currently translated at 94.9% (506 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ja/
2023-08-30 15:55:21 +02:00
Nonoss117
419e930456 Translated using Weblate (French)
Currently translated at 100.0% (533 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2023-08-30 15:55:21 +02:00
shamoon
494a1c50d5 Update index.jsx 2023-08-29 09:48:32 -07:00
shamoon
3b05655fb0 Merge pull request #1881 from benphelps/fix/issue-1878
Fix location of quicklaunch, some focus issues
2023-08-29 09:37:58 -07:00
shamoon
98baf0507b Fix location of quicklaunch, some focus issues 2023-08-29 09:33:58 -07:00
shamoon
36760caff9 Update component.jsx 2023-08-28 17:48:44 -07:00
Anonymous
2363f96f1b Translated using Weblate (Basque)
Currently translated at 6.3% (34 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/eu/
2023-08-29 02:04:35 +02:00
Anonymous
c0c14b0233 Translated using Weblate (Indonesian)
Currently translated at 4.5% (24 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/id/
2023-08-29 02:04:34 +02:00
Anonymous
5c28b501f6 Translated using Weblate (Slovenian)
Currently translated at 97.7% (521 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/sl/
2023-08-29 02:04:34 +02:00
Anonymous
5d9155ab22 Translated using Weblate (Greek)
Currently translated at 33.9% (181 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/el/
2023-08-29 02:04:33 +02:00
Anonymous
2d13c38d38 Translated using Weblate (Korean)
Currently translated at 32.4% (173 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ko/
2023-08-29 02:04:33 +02:00
Anonymous
d5891793dd Translated using Weblate (Slovak)
Currently translated at 1.8% (10 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/sk/
2023-08-29 02:04:33 +02:00
Anonymous
7c8ab99df6 Translated using Weblate (Thai)
Currently translated at 9.0% (48 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/th/
2023-08-29 02:04:32 +02:00
Anonymous
c09785b4f5 Translated using Weblate (Latvian)
Currently translated at 22.1% (118 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/lv/
2023-08-29 02:04:32 +02:00
Anonymous
31d7b56fb6 Translated using Weblate (Japanese)
Currently translated at 94.9% (506 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ja/
2023-08-29 02:04:32 +02:00
Anonymous
d5fd904e55 Translated using Weblate (Ukrainian)
Currently translated at 94.9% (506 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/uk/
2023-08-29 02:04:32 +02:00
Anonymous
67b1ca6251 Translated using Weblate (Esperanto)
Currently translated at 27.2% (145 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/eo/
2023-08-29 02:04:31 +02:00
Anonymous
3d13d9311d Translated using Weblate (Hindi)
Currently translated at 1.8% (10 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/hi/
2023-08-29 02:04:31 +02:00
Anonymous
1b81942549 Translated using Weblate (Malay)
Currently translated at 47.2% (252 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ms/
2023-08-29 02:04:31 +02:00
Anonymous
2013fc8193 Translated using Weblate (Danish)
Currently translated at 97.7% (521 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/da/
2023-08-29 02:04:30 +02:00
Anonymous
a8415ab40f Translated using Weblate (Czech)
Currently translated at 83.3% (444 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/cs/
2023-08-29 02:04:30 +02:00
Anonymous
4ce941a781 Translated using Weblate (Arabic)
Currently translated at 49.1% (262 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ar/
2023-08-29 02:04:29 +02:00
Anonymous
2bf5830ca8 Translated using Weblate (Serbian)
Currently translated at 1.8% (10 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/sr/
2023-08-29 02:04:29 +02:00
Anonymous
b554683eca Translated using Weblate (Turkish)
Currently translated at 73.7% (393 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/tr/
2023-08-29 02:04:29 +02:00
Anonymous
9612a76bce Translated using Weblate (Bulgarian)
Currently translated at 8.8% (47 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/bg/
2023-08-29 02:04:28 +02:00
Anonymous
4a2cf8764d Translated using Weblate (Telugu)
Currently translated at 40.5% (216 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/te/
2023-08-29 02:04:28 +02:00
Anonymous
1d99f2ebf1 Translated using Weblate (Finnish)
Currently translated at 33.2% (177 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fi/
2023-08-29 02:04:27 +02:00
Anonymous
3d32c129c0 Translated using Weblate (Yue (Traditional))
Currently translated at 22.1% (118 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/yue_Hant/
2023-08-29 02:04:27 +02:00
Anonymous
5e42da6e53 Translated using Weblate (Portuguese (Brazil))
Currently translated at 86.4% (461 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pt_BR/
2023-08-29 02:04:27 +02:00
Anonymous
61190f6e49 Translated using Weblate (Romanian)
Currently translated at 28.3% (151 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ro/
2023-08-29 02:04:26 +02:00
Anonymous
dcb3ca52e3 Translated using Weblate (Hebrew)
Currently translated at 18.9% (101 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/he/
2023-08-29 02:04:26 +02:00
Anonymous
41aea0166e Translated using Weblate (Hungarian)
Currently translated at 88.3% (471 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/hu/
2023-08-29 02:04:25 +02:00
Anonymous
5c9d2ba04c Translated using Weblate (Croatian)
Currently translated at 88.1% (470 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/hr/
2023-08-29 02:04:25 +02:00
Anonymous
4ad13625be Translated using Weblate (Swedish)
Currently translated at 24.7% (132 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/sv/
2023-08-29 02:04:24 +02:00
Anonymous
acb28389f4 Translated using Weblate (Polish)
Currently translated at 70.1% (374 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pl/
2023-08-29 02:04:23 +02:00
Anonymous
117930a6f5 Translated using Weblate (Catalan)
Currently translated at 48.9% (261 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ca/
2023-08-29 02:04:23 +02:00
Anonymous
d4db335d3d Translated using Weblate (Chinese (Traditional))
Currently translated at 93.6% (499 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hant/
2023-08-29 02:04:22 +02:00
Anonymous
7b1ac03e3a Translated using Weblate (Dutch)
Currently translated at 45.5% (243 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nl/
2023-08-29 02:04:22 +02:00
Anonymous
2405e8afbd Translated using Weblate (Vietnamese)
Currently translated at 8.4% (45 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/vi/
2023-08-29 02:04:21 +02:00
Anonymous
bccf83467b Translated using Weblate (Norwegian Bokmål)
Currently translated at 15.1% (81 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nb_NO/
2023-08-29 02:04:21 +02:00
Anonymous
374e8873ce Translated using Weblate (Italian)
Currently translated at 88.1% (470 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/it/
2023-08-29 02:04:21 +02:00
Anonymous
313211f756 Translated using Weblate (Chinese (Simplified))
Currently translated at 84.4% (450 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hans/
2023-08-29 02:04:20 +02:00
Anonymous
49a68488b4 Translated using Weblate (Russian)
Currently translated at 80.1% (427 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ru/
2023-08-29 02:04:20 +02:00
Anonymous
5d66323edd Translated using Weblate (Portuguese)
Currently translated at 77.8% (415 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pt/
2023-08-29 02:04:19 +02:00
Anonymous
7d7964bfa8 Translated using Weblate (French)
Currently translated at 97.7% (521 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2023-08-29 02:04:19 +02:00
Anonymous
34bf5da16f Translated using Weblate (Spanish)
Currently translated at 97.7% (521 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2023-08-29 02:04:19 +02:00
Anonymous
0aefe4e327 Translated using Weblate (German)
Currently translated at 85.7% (457 of 533 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/de/
2023-08-29 02:04:18 +02:00
Andrej Kralj
15d36f74d3 Translated using Weblate (Slovenian)
Currently translated at 100.0% (521 of 521 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/sl/
2023-08-29 02:02:58 +02:00
AwesomeClips
0ee1656872 Translated using Weblate (Greek)
Currently translated at 34.7% (181 of 521 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/el/
2023-08-29 02:02:58 +02:00
Azurite
0e3d05ffe2 Translated using Weblate (Japanese)
Currently translated at 97.1% (506 of 521 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ja/
2023-08-29 02:02:58 +02:00
Allan Grauengaard Hedelain
843f624655 Translated using Weblate (Danish)
Currently translated at 100.0% (521 of 521 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/da/
2023-08-29 02:02:58 +02:00
oxygen44k
ba77e0e0f7 Translated using Weblate (Chinese (Simplified))
Currently translated at 86.3% (450 of 521 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hans/
2023-08-29 02:02:58 +02:00
gallegonovato
b7198d1d52 Translated using Weblate (Spanish)
Currently translated at 100.0% (521 of 521 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2023-08-29 02:02:58 +02:00
shamoon
e990ba3394 Merge pull request #1876 from tomhoover/uptimerobot-widget
Add UptimeRobot widget

---------

Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
2023-08-28 17:02:46 -07:00
Tom Hoover
e19dab3c5d Add UptimeRobot widget 2023-08-28 17:02:00 -07:00
Atropos
82d2f08e8b Enhancement: support silmultaneous traefik .containio.us and .io ingress routes for k8s (#1875) 2023-08-28 11:00:39 -07:00
shamoon
43b32fd1fb Merge pull request #1869 from rauenzi/widget-options
Allow widgets to add headers or set method
2023-08-27 16:12:22 -07:00
Zack Rauen
d6448763e0 Allow widgets to add header or set methods 2023-08-27 18:46:50 -04:00
shamoon
51ea4ea405 Merge pull request #1868 from benphelps/fix/issue-1866
Fix: support streaming media from jellyfin
2023-08-27 13:56:33 -07:00
shamoon
713cb217e4 Support streaming media from jellyfin 2023-08-27 13:55:47 -07:00
Nonoss117
8ef88f2153 Translated using Weblate (French)
Currently translated at 100.0% (521 of 521 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2023-08-26 13:27:32 +02:00
shamoon
6bfc98daf8 Collapse should rotate 180 degrees 2023-08-26 00:25:24 -07:00
Ben Phelps
d90a038884 fs widget? 2023-08-22 10:49:14 +03:00
129 changed files with 2752 additions and 1425 deletions

View File

@@ -16,7 +16,6 @@
**/compose* **/compose*
**/Dockerfile* **/Dockerfile*
**/node_modules **/node_modules
!**/node_modules/.pnpm/compressjs@*/**
**/npm-debug.log **/npm-debug.log
**/obj **/obj
**/secrets.dev.yaml **/secrets.dev.yaml

View File

@@ -35,7 +35,7 @@ jobs:
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v3 uses: actions/checkout@v4
# Install the cosign tool except on PR # Install the cosign tool except on PR
# https://github.com/sigstore/cosign-installer # https://github.com/sigstore/cosign-installer
@@ -48,11 +48,11 @@ jobs:
# Setup QEMU # Setup QEMU
# https://github.com/marketplace/actions/docker-setup-buildx#with-qemu # https://github.com/marketplace/actions/docker-setup-buildx#with-qemu
- name: Setup QEMU - name: Setup QEMU
uses: docker/setup-qemu-action@v2 uses: docker/setup-qemu-action@v3
# Workaround: https://github.com/docker/build-push-action/issues/461 # Workaround: https://github.com/docker/build-push-action/issues/461
- name: Setup Docker buildx - name: Setup Docker buildx
uses: docker/setup-buildx-action@v2 uses: docker/setup-buildx-action@v3
# This step is being disabled because the runner is on a self-hosted machine # This step is being disabled because the runner is on a self-hosted machine
# where the cache will stick between runs. # where the cache will stick between runs.
@@ -68,7 +68,7 @@ jobs:
# https://github.com/docker/login-action # https://github.com/docker/login-action
- name: Log into registry ${{ env.REGISTRY }} - name: Log into registry ${{ env.REGISTRY }}
if: github.event_name != 'pull_request' if: github.event_name != 'pull_request'
uses: docker/login-action@v2 uses: docker/login-action@v3
with: with:
registry: ${{ env.REGISTRY }} registry: ${{ env.REGISTRY }}
username: ${{ github.actor }} username: ${{ github.actor }}
@@ -78,7 +78,7 @@ jobs:
# https://github.com/docker/metadata-action # https://github.com/docker/metadata-action
- name: Extract Docker metadata - name: Extract Docker metadata
id: meta id: meta
uses: docker/metadata-action@v4 uses: docker/metadata-action@v5
with: with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
flavor: | flavor: |
@@ -88,7 +88,7 @@ jobs:
# https://github.com/docker/build-push-action # https://github.com/docker/build-push-action
- name: Build and push Docker image - name: Build and push Docker image
id: build-and-push id: build-and-push
uses: docker/build-push-action@v4 uses: docker/build-push-action@v5
with: with:
context: . context: .
push: ${{ github.event_name != 'pull_request' }} push: ${{ github.event_name != 'pull_request' }}

2
.vscode/launch.json vendored
View File

@@ -16,4 +16,4 @@
} }
} }
] ]
} }

View File

@@ -52,8 +52,6 @@ COPY --link --chown=1000:1000 /public ./public/
# Copy files from builder # Copy files from builder
COPY --link --from=builder --chown=1000:1000 /app/.next/standalone ./ COPY --link --from=builder --chown=1000:1000 /app/.next/standalone ./
COPY --link --from=builder --chown=1000:1000 /app/.next/static/ ./.next/static/ COPY --link --from=builder --chown=1000:1000 /app/.next/static/ ./.next/static/
# see https://github.com/benphelps/homepage/issues/1795
COPY --link --from=builder /app/node_modules/.pnpm/compressjs@1.0.3/node_modules/compressjs/lib/ ./node_modules/.pnpm/compressjs@1.0.3/node_modules/compressjs/lib/
COPY --link --chmod=755 docker-entrypoint.sh /usr/local/bin/ COPY --link --chmod=755 docker-entrypoint.sh /usr/local/bin/
RUN apk add --no-cache su-exec RUN apk add --no-cache su-exec

134
README.md
View File

@@ -6,71 +6,58 @@
</p> </p>
<p align="center"> <p align="center">
A modern <em>(fully static, fast)</em>, secure <em>(fully proxied)</em>, highly customizable application dashboard with integrations for more than 25 services and translations for over 15 languages. Easily configured via YAML files (or discovery via docker labels). A modern, <em>fully static, fast</em>, secure <em>fully proxied</em>, highly customizable application dashboard with integrations for over 100 services and translations into multiple languages. Easily configured via YAML files or through docker label discovery.
</p> </p>
<p align="center"> <p align="center">
<img src="images/1.png" /> <img src="images/1.png?v=2" />
</p> </p>
<p align="center"> <p align="center">
<img src="images/2.png" width="19%" /> <a href="https://github.com/benphelps/homepage/actions/workflows/docker-publish.yml"><img alt="GitHub Workflow Status (with event)" src="https://img.shields.io/github/actions/workflow/status/benphelps/homepage/docker-publish.yml"></a>
<img src="images/3.png" width="19%" /> &nbsp;
<img src="images/4.png" width="19%" />
<img src="images/5.png" width="19%" />
<img src="images/6.png" width="19%" />
</p>
<p align="center">
<a href="https://discord.gg/k4ruYNrudu"><img src="https://img.shields.io/badge/Discord - Chat-blue?logo=discord&logoColor=white" /></a>
<a href="https://paypal.me/phelpsben" title="Donate"><img src="https://img.shields.io/badge/PayPal - Donate-blue?logo=paypal&logoColor=white" alt="Linkedin - phelpsben"></a>
</p>
<p align="center">
<a href="https://github.com/benphelps/homepage/actions/workflows/docker-publish.yml"><img src="https://github.com/benphelps/homepage/actions/workflows/docker-publish.yml/badge.svg" alt="Docker"></a>
<a href="https://hosted.weblate.org/engage/homepage/"><img src="https://hosted.weblate.org/widgets/homepage/-/homepage/svg-badge.svg" alt="Weblate"></a> <a href="https://hosted.weblate.org/engage/homepage/"><img src="https://hosted.weblate.org/widgets/homepage/-/homepage/svg-badge.svg" alt="Weblate"></a>
&nbsp;
<a href="https://discord.gg/k4ruYNrudu"><img alt="Discord" src="https://img.shields.io/discord/1019316731635834932"></a>
&nbsp;
<a href="https://paypal.me/phelpsben" title="Donate"><img alt="GitHub Sponsors" src="https://img.shields.io/github/sponsors/benphelps"></a>
</p> </p>
## Features # Features
- **Fast!** The entire site is statically generated at build time, so you can expect instant load times With features like quick search, bookmarks, weather support, a wide range of integrations and widgets, an elegant and modern design, and a focus on performance, Homepage is your ideal start to the day and a handy companion throughout it.
- **Secure!** Every API request to backend services goes through a proxy server, so your API keys are never exposed to the frontend client.
- Images built for AMD64 (x86_64), ARM64, ARMv7 and ARMv6
- Supports all Raspberry Pi's, most SBCs & Apple Silicon
- Full i18n support with translations for Catalan, Chinese, Dutch, Finnish, French, German, Hebrew, Hungarian, Malay, Norwegian Bokmål, Polish, Portuguese, Portuguese (Brazil), Romanian, Russian, Spanish, Swedish and Yue
- Want to help translate? [Join the Weblate project](https://hosted.weblate.org/engage/homepage/)
- Service & Web Bookmarks
- Docker Integration
- Container status (Running / Stopped) & statistics (CPU, Memory, Network)
- Automatic service discovery (via labels)
- Service Integration
- Sonarr, Radarr, Readarr, Prowlarr, Bazarr, Lidarr, Emby, Jellyfin, Tautulli, Plex and more
- Ombi, Overseerr, Jellyseerr, Jackett, NZBGet, SABnzbd, ruTorrent, Transmission, qBittorrent and more
- Portainer, Traefik, Speedtest Tracker, PiHole, AdGuard Home, Nginx Proxy Manager, Gotify, Syncthing Relay Server, Authentik, Proxmox and more
- Information Providers
- Coin Market Cap, Mastodon and more
- Information & Utility Widgets
- System Stats (Disk, CPU, Memory)
- Weather via [OpenWeatherMap](https://openweathermap.org/) or [Open-Meteo](https://open-meteo.com/)
- Web Search Bar
- UniFi Console, Glances and more
- Instant "Quick-launch" search
- Customizable
- 21 theme colors with light and dark mode support
- Background image support
- Column and Row layout options
## Support & Suggestions - **Fast** - The site is statically generated at build time for instant load times.
- **Secure** - All API requests to backend services are proxied, keeping your API keys hidden. Constantly reviewed for security by the community.
- **For Everyone** - Images built for AMD64, ARM64, ARMv7, and ARMv6.
- **Full i18n** - Support for over 40 languages.
- **Service & Web Bookmarks** - Add custom links to the homepage.
- **Docker Integration** - Container status and stats. Automatic service discovery via labels.
- **Service Integration** - Over 100 service integrations, including popular starr and self-hosted apps.
- **Information & Utility Widgets** - Weather, time, date, search, and more.
- **And much more...**
If you have any questions, suggestions, or general issues, please start a discussion on the [Discussions](https://github.com/benphelps/homepage/discussions) page. ## Docker Integration
For bug reports, please open an issue on the [Issues](https://github.com/benphelps/homepage/issues) page. Homepage has built-in support for Docker, and can automatically discover and add services to the homepage based on labels. See the [Docker](https://gethomepage.dev/en/installation/docker/) page for more information.
## Getting Started ## Service Widgets
For configuration options, examples and more, [please check out the homepage site](http://gethomepage.dev). Homepage also has support for over 100 3rd party services, including all popular starr apps, and most popular self-hosted apps. Some examples include: Radarr, Sonarr, Lidarr, Bazarr, Ombi, Tautulli, Plex, Jellyfin, Emby, Transmission, qBittorrent, Deluge, Jackett, NZBGet, SABnzbd, etc. As well as service integrations, Homepage also has a number of information providers, sourcing information from a variety of external 3rd party APIs. See the [Service](https://gethomepage.dev/en/configs/service-widgets/) page for more information.
### With Docker ## Information Widgets
Homepage has built-in support for a number of information providers, including weather, time, date, search, glances and more. System and status information presented at the top of the page. See the [Information Providers](https://gethomepage.dev/en/configs/widgets/) page for more information.
## Customization
Homepage is highly customizable, with support for custom themes, custom CSS & JS, custom layouts, formatting, localization and more. See the [Settings](https://gethomepage.dev/en/configs/settings/) page for more information.
# Getting Started
For configuration options, examples and more, [please check out the homepage documentation](http://gethomepage.dev).
## With Docker
Using docker compose: Using docker compose:
@@ -80,22 +67,31 @@ services:
homepage: homepage:
image: ghcr.io/benphelps/homepage:latest image: ghcr.io/benphelps/homepage:latest
container_name: homepage container_name: homepage
environment:
PUID: 1000 -- optional, your user id
PGID: 1000 -- optional, your group id
ports: ports:
- 3000:3000 - 3000:3000
volumes: volumes:
- /path/to/config:/app/config # Make sure your local config directory exists - /path/to/config:/app/config # Make sure your local config directory exists
- /var/run/docker.sock:/var/run/docker.sock:ro # (optional) For docker integrations - /var/run/docker.sock:/var/run/docker.sock:ro # optional, for docker integrations
# user: 1000:1000 optional, not compatibile with direct socket see https://gethomepage.dev/en/configs/docker/#using-socket-directly
restart: unless-stopped restart: unless-stopped
``` ```
or docker run: or docker run:
```bash ```bash
docker run -p 3000:3000 -v /path/to/config:/app/config -v /var/run/docker.sock:/var/run/docker.sock ghcr.io/benphelps/homepage:latest docker run --name homepage \
-e PUID=1000 \
-e PGID=1000 \
-p 3000:3000 \
-v /path/to/config:/app/config \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
--restart unless-stopped \
ghcr.io/benphelps/homepage:latest
``` ```
### With Node ## With Node
First, clone the repository: First, clone the repository:
@@ -112,22 +108,23 @@ pnpm build
If this is your first time starting, copy the `src/skeleton` directory to `config/` to populate initial example config files. If this is your first time starting, copy the `src/skeleton` directory to `config/` to populate initial example config files.
Finally, run the server: Finally, run the server in production mode:
```bash ```bash
pnpm start pnpm start
``` ```
## Configuration or development mode:
Configuration files will be generated and placed on the first request. ```bash
pnpm dev
```
Configuration is done in the /config directory using .yaml files. Refer to each config for # Configuration
the specific configuration options.
You may also check [the homepage site](http://gethomepage.dev) for detailed configuration instructions, examples and more. Please refere to the [homepage documentation](https://gethomepage.dev/) website for more information. Everything you need to know about configuring Homepage is there. Please read everything carefully before asking for help, as most questions are answered there or are simple YAML configuration issues.
## Development # Development
Install NPM packages, this project uses [pnpm](https://pnpm.io/) (and so should you!): Install NPM packages, this project uses [pnpm](https://pnpm.io/) (and so should you!):
@@ -145,19 +142,14 @@ Open [http://localhost:3000](http://localhost:3000) to start.
This is a [Next.js](https://nextjs.org/) application, see their documentation for more information: This is a [Next.js](https://nextjs.org/) application, see their documentation for more information:
## Contributors # Support & Suggestions
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --> If you have any questions, suggestions, or general issues, please start a discussion on the [Discussions](https://github.com/benphelps/homepage/discussions) page.
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<!-- markdownlint-restore --> For bug reports, please open an issue on the [Issues](https://github.com/benphelps/homepage/issues) page.
<!-- prettier-ignore-end -->
<!-- ALL-CONTRIBUTORS-LIST:END --> ## Contributing & Contributers
Contributions are welcome! Please see the [CONTRIBUTING.md](CONTRIBUTING.md) file for more information.
Thanks to the over 200 contributors who have helped make this project what it is today!
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
[![All Contributors](https://img.shields.io/badge/all_contributors-13-orange.svg?style=flat-square)](#contributors)
<!-- ALL-CONTRIBUTORS-BADGE:END -->

Binary file not shown.

Before

Width:  |  Height:  |  Size: 345 KiB

After

Width:  |  Height:  |  Size: 734 KiB

View File

@@ -36,8 +36,8 @@ options:
switchCurrentContext: false switchCurrentContext: false
runtime: runtime:
gpuRequest: "" gpuRequest: ""
serversMemory: "1024Mi" serversMemory: "1024MiB"
agentsMemory: "1024Mi" agentsMemory: "1024MiB"
labels: labels:
- label: foo=bar - label: foo=bar
nodeFilters: nodeFilters:

68
package-lock.json generated
View File

@@ -14,7 +14,7 @@
"compare-versions": "^5.0.1", "compare-versions": "^5.0.1",
"dockerode": "^3.3.4", "dockerode": "^3.3.4",
"follow-redirects": "^1.15.2", "follow-redirects": "^1.15.2",
"gamedig": "^4.0.6", "gamedig": "^4.1.0",
"i18next": "^21.9.2", "i18next": "^21.9.2",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",
"json-rpc-2.0": "^1.4.1", "json-rpc-2.0": "^1.4.1",
@@ -769,14 +769,6 @@
"url": "https://github.com/sponsors/epoberezkin" "url": "https://github.com/sponsors/epoberezkin"
} }
}, },
"node_modules/amdefine": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
"integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==",
"engines": {
"node": ">=0.4.2"
}
},
"node_modules/ansi-regex": { "node_modules/ansi-regex": {
"version": "5.0.1", "version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
@@ -1503,29 +1495,6 @@
"resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-5.0.3.tgz", "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-5.0.3.tgz",
"integrity": "sha512-4UZlZP8Z99MGEY+Ovg/uJxJuvoXuN4M6B3hKaiackiHrgzQFEe3diJi1mf1PNHbFujM7FvLrK2bpgIaImbtZ1A==" "integrity": "sha512-4UZlZP8Z99MGEY+Ovg/uJxJuvoXuN4M6B3hKaiackiHrgzQFEe3diJi1mf1PNHbFujM7FvLrK2bpgIaImbtZ1A=="
}, },
"node_modules/compressjs": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/compressjs/-/compressjs-1.0.3.tgz",
"integrity": "sha512-jpKJjBTretQACTGLNuvnozP1JdP2ZLrjdGdBgk/tz1VfXlUcBhhSZW6vEsuThmeot/yjvSrPQKEgfF3X2Lpi8Q==",
"dependencies": {
"amdefine": "~1.0.0",
"commander": "~2.8.1"
},
"bin": {
"compressjs": "bin/compressjs"
}
},
"node_modules/compressjs/node_modules/commander": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz",
"integrity": "sha512-+pJLBFVk+9ZZdlAOB5WuIElVPPth47hILFkmGym57aq8kwxsowvByvB0DHs1vQAhyMZzdcpTtF0VDKGkSDR4ZQ==",
"dependencies": {
"graceful-readlink": ">= 1.0.0"
},
"engines": {
"node": ">= 0.6.x"
}
},
"node_modules/concat-map": { "node_modules/concat-map": {
"version": "0.0.1", "version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@@ -2977,18 +2946,18 @@
} }
}, },
"node_modules/gamedig": { "node_modules/gamedig": {
"version": "4.0.6", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/gamedig/-/gamedig-4.0.6.tgz", "resolved": "https://registry.npmjs.org/gamedig/-/gamedig-4.1.0.tgz",
"integrity": "sha512-h0k9n/e5vNrd9Mh2wyFUp2Vo7ABWbDkdBxKC6FNJLOZiU5d9Z29bntGeYbXtOkcRWoV6Q63wSAJ3jLWxYQkpZw==", "integrity": "sha512-jvLUEakihJgpiw9t9yQRsbcemeALeTNlnaWY1gvYdwI63ZlkxznTaLqX5K/eluRTTCtAWNW3YceT6NVjyAZIwA==",
"dependencies": { "dependencies": {
"cheerio": "^1.0.0-rc.10", "cheerio": "^1.0.0-rc.10",
"compressjs": "^1.0.2",
"gbxremote": "^0.2.1", "gbxremote": "^0.2.1",
"got": "^12.0.3", "got": "^12.1.0",
"iconv-lite": "^0.6.3", "iconv-lite": "^0.6.3",
"long": "^5.2.0", "long": "^5.2.0",
"minimist": "^1.2.6", "minimist": "^1.2.6",
"punycode": "^2.1.1", "punycode": "^2.1.1",
"seek-bzip": "^2.0.0",
"varint": "^6.0.0" "varint": "^6.0.0"
}, },
"bin": { "bin": {
@@ -3190,11 +3159,6 @@
"url": "https://github.com/sindresorhus/got?sponsor=1" "url": "https://github.com/sindresorhus/got?sponsor=1"
} }
}, },
"node_modules/graceful-readlink": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
"integrity": "sha512-8tLu60LgxF6XpdbK8OW3FA+IfTNBn1ZHGHKF4KQbEeSkajYw5PlYJcKluntgegDPTg8UkHjpet1T82vk6TQ68w=="
},
"node_modules/grapheme-splitter": { "node_modules/grapheme-splitter": {
"version": "1.0.4", "version": "1.0.4",
"resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
@@ -5586,6 +5550,26 @@
"loose-envify": "^1.1.0" "loose-envify": "^1.1.0"
} }
}, },
"node_modules/seek-bzip": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-2.0.0.tgz",
"integrity": "sha512-SMguiTnYrhpLdk3PwfzHeotrcwi8bNV4iemL9tx9poR/yeaMYwB9VzR1w7b57DuWpuqR8n6oZboi0hj3AxZxQg==",
"dependencies": {
"commander": "^6.0.0"
},
"bin": {
"seek-bunzip": "bin/seek-bunzip",
"seek-table": "bin/seek-bzip-table"
}
},
"node_modules/seek-bzip/node_modules/commander": {
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
"integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==",
"engines": {
"node": ">= 6"
}
},
"node_modules/semver": { "node_modules/semver": {
"version": "6.3.0", "version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",

View File

@@ -16,7 +16,7 @@
"compare-versions": "^5.0.1", "compare-versions": "^5.0.1",
"dockerode": "^3.3.4", "dockerode": "^3.3.4",
"follow-redirects": "^1.15.2", "follow-redirects": "^1.15.2",
"gamedig": "^4.0.6", "gamedig": "^4.1.0",
"i18next": "^21.9.2", "i18next": "^21.9.2",
"js-yaml": "^4.1.0", "js-yaml": "^4.1.0",
"json-rpc-2.0": "^1.4.1", "json-rpc-2.0": "^1.4.1",

46
pnpm-lock.yaml generated
View File

@@ -24,8 +24,8 @@ dependencies:
specifier: ^1.15.2 specifier: ^1.15.2
version: 1.15.2 version: 1.15.2
gamedig: gamedig:
specifier: ^4.0.6 specifier: ^4.1.0
version: 4.0.6 version: 4.1.0
i18next: i18next:
specifier: ^21.9.2 specifier: ^21.9.2
version: 21.10.0 version: 21.10.0
@@ -602,11 +602,6 @@ packages:
json-schema-traverse: 0.4.1 json-schema-traverse: 0.4.1
uri-js: 4.4.1 uri-js: 4.4.1
/amdefine@1.0.1:
resolution: {integrity: sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==}
engines: {node: '>=0.4.2'}
dev: false
/ansi-regex@5.0.1: /ansi-regex@5.0.1:
resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
engines: {node: '>=8'} engines: {node: '>=8'}
@@ -1002,28 +997,18 @@ packages:
delayed-stream: 1.0.0 delayed-stream: 1.0.0
dev: false dev: false
/commander@2.8.1:
resolution: {integrity: sha512-+pJLBFVk+9ZZdlAOB5WuIElVPPth47hILFkmGym57aq8kwxsowvByvB0DHs1vQAhyMZzdcpTtF0VDKGkSDR4ZQ==}
engines: {node: '>= 0.6.x'}
dependencies:
graceful-readlink: 1.0.1
dev: false
/commander@4.1.1: /commander@4.1.1:
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
engines: {node: '>= 6'} engines: {node: '>= 6'}
dev: true dev: true
/compare-versions@5.0.3: /commander@6.2.1:
resolution: {integrity: sha512-4UZlZP8Z99MGEY+Ovg/uJxJuvoXuN4M6B3hKaiackiHrgzQFEe3diJi1mf1PNHbFujM7FvLrK2bpgIaImbtZ1A==} resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==}
engines: {node: '>= 6'}
dev: false dev: false
/compressjs@1.0.3: /compare-versions@5.0.3:
resolution: {integrity: sha512-jpKJjBTretQACTGLNuvnozP1JdP2ZLrjdGdBgk/tz1VfXlUcBhhSZW6vEsuThmeot/yjvSrPQKEgfF3X2Lpi8Q==} resolution: {integrity: sha512-4UZlZP8Z99MGEY+Ovg/uJxJuvoXuN4M6B3hKaiackiHrgzQFEe3diJi1mf1PNHbFujM7FvLrK2bpgIaImbtZ1A==}
hasBin: true
dependencies:
amdefine: 1.0.1
commander: 2.8.1
dev: false dev: false
/concat-map@0.0.1: /concat-map@0.0.1:
@@ -1972,19 +1957,19 @@ packages:
resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
dev: true dev: true
/gamedig@4.0.6: /gamedig@4.1.0:
resolution: {integrity: sha512-h0k9n/e5vNrd9Mh2wyFUp2Vo7ABWbDkdBxKC6FNJLOZiU5d9Z29bntGeYbXtOkcRWoV6Q63wSAJ3jLWxYQkpZw==} resolution: {integrity: sha512-jvLUEakihJgpiw9t9yQRsbcemeALeTNlnaWY1gvYdwI63ZlkxznTaLqX5K/eluRTTCtAWNW3YceT6NVjyAZIwA==}
engines: {node: '>=14.0.0'} engines: {node: '>=14.0.0'}
hasBin: true hasBin: true
dependencies: dependencies:
cheerio: 1.0.0-rc.12 cheerio: 1.0.0-rc.12
compressjs: 1.0.3
gbxremote: 0.2.1 gbxremote: 0.2.1
got: 12.6.1 got: 12.6.1
iconv-lite: 0.6.3 iconv-lite: 0.6.3
long: 5.2.3 long: 5.2.3
minimist: 1.2.8 minimist: 1.2.8
punycode: 2.3.0 punycode: 2.3.0
seek-bzip: 2.0.0
varint: 6.0.0 varint: 6.0.0
dev: false dev: false
@@ -2121,10 +2106,6 @@ packages:
responselike: 3.0.0 responselike: 3.0.0
dev: false dev: false
/graceful-readlink@1.0.1:
resolution: {integrity: sha512-8tLu60LgxF6XpdbK8OW3FA+IfTNBn1ZHGHKF4KQbEeSkajYw5PlYJcKluntgegDPTg8UkHjpet1T82vk6TQ68w==}
dev: false
/grapheme-splitter@1.0.4: /grapheme-splitter@1.0.4:
resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==}
dev: true dev: true
@@ -3584,6 +3565,13 @@ packages:
loose-envify: 1.4.0 loose-envify: 1.4.0
dev: false dev: false
/seek-bzip@2.0.0:
resolution: {integrity: sha512-SMguiTnYrhpLdk3PwfzHeotrcwi8bNV4iemL9tx9poR/yeaMYwB9VzR1w7b57DuWpuqR8n6oZboi0hj3AxZxQg==}
hasBin: true
dependencies:
commander: 6.2.1
dev: false
/semver@6.3.0: /semver@6.3.0:
resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==}
dev: true dev: true

View File

@@ -316,7 +316,8 @@
"write": "Write", "write": "Write",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Mem",
"swap": "Swap" "swap": "Swap",
"_temp": "Temp"
}, },
"quicklaunch": { "quicklaunch": {
"bookmark": "مفضلة", "bookmark": "مفضلة",
@@ -718,5 +719,19 @@
"series": "Series", "series": "Series",
"books": "Books", "books": "Books",
"authors": "Authors" "authors": "Authors"
},
"uptimerobot": {
"seemsdown": "Seems Down",
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@@ -13,7 +13,7 @@
"missing_type": "Липсваща приставка: {{type}}", "missing_type": "Липсваща приставка: {{type}}",
"api_error": "API Грешка", "api_error": "API Грешка",
"status": "Статус", "status": "Статус",
"information": "Information", "information": "Информация",
"url": "URL", "url": "URL",
"raw_error": "Raw Error", "raw_error": "Raw Error",
"response_data": "Response Data" "response_data": "Response Data"
@@ -28,7 +28,7 @@
"placeholder": "Търсене…" "placeholder": "Търсене…"
}, },
"resources": { "resources": {
"cpu": "CPU", "cpu": "Процесор",
"total": "Общо", "total": "Общо",
"free": "Свободни", "free": "Свободни",
"used": "Заети", "used": "Заети",
@@ -54,9 +54,9 @@
"wait": "Моля изчакайте", "wait": "Моля изчакайте",
"lan": "LAN", "lan": "LAN",
"wlan": "WLAN", "wlan": "WLAN",
"devices": "Devices", "devices": "Устройства",
"lan_devices": "LAN Devices", "lan_devices": "LAN Устройства",
"wlan_devices": "WLAN Devices", "wlan_devices": "WLAN Устройства",
"empty_data": "Subsystem status unknown" "empty_data": "Subsystem status unknown"
}, },
"docker": { "docker": {
@@ -64,8 +64,8 @@
"rx": "RX", "rx": "RX",
"tx": "TX", "tx": "TX",
"mem": "MEM", "mem": "MEM",
"cpu": "CPU", "cpu": "Процесор",
"error": "Error", "error": "Грешка",
"unknown": "Unknown", "unknown": "Unknown",
"partial": "Partial", "partial": "Partial",
"running": "Running", "running": "Running",
@@ -125,7 +125,7 @@
"radarr": { "radarr": {
"wanted": "Wanted", "wanted": "Wanted",
"queued": "Queued", "queued": "Queued",
"movies": "Movies", "movies": "Филми",
"missing": "Missing", "missing": "Missing",
"queue": "Queue", "queue": "Queue",
"unknown": "Unknown" "unknown": "Unknown"
@@ -138,38 +138,38 @@
"readarr": { "readarr": {
"wanted": "Wanted", "wanted": "Wanted",
"queued": "Queued", "queued": "Queued",
"books": "Books" "books": "Книги"
}, },
"bazarr": { "bazarr": {
"missingEpisodes": "Missing Episodes", "missingEpisodes": "Липсващи Епизоди",
"missingMovies": "Missing Movies" "missingMovies": "Липсващи Филми"
}, },
"ombi": { "ombi": {
"pending": "Pending", "pending": "Pending",
"approved": "Approved", "approved": "Одобрен",
"available": "Available" "available": "Наличен"
}, },
"jellyseerr": { "jellyseerr": {
"pending": "Pending", "pending": "Pending",
"approved": "Approved", "approved": "Одобрен",
"available": "Available" "available": "Наличен"
}, },
"overseerr": { "overseerr": {
"pending": "Pending", "pending": "Pending",
"approved": "Approved", "approved": "Одобрен",
"available": "Available", "available": "Наличен",
"processing": "Processing" "processing": "Processing"
}, },
"pihole": { "pihole": {
"queries": "Queries", "queries": "Заявки",
"blocked": "Blocked", "blocked": "Блокирани",
"gravity": "Gravity", "gravity": "Gravity",
"blocked_percent": "Blocked %" "blocked_percent": "Blocked %"
}, },
"adguard": { "adguard": {
"queries": "Queries", "queries": "Queries",
"blocked": "Blocked", "blocked": "Блокирани",
"filtered": "Filtered", "filtered": "Филтрирани",
"latency": "Latency" "latency": "Latency"
}, },
"speedtest": { "speedtest": {
@@ -179,7 +179,7 @@
}, },
"portainer": { "portainer": {
"running": "Running", "running": "Running",
"stopped": "Stopped", "stopped": "Спрян",
"total": "Total" "total": "Total"
}, },
"traefik": { "traefik": {
@@ -188,15 +188,15 @@
"middleware": "Middleware" "middleware": "Middleware"
}, },
"npm": { "npm": {
"enabled": "Enabled", "enabled": "Активирано",
"disabled": "Disabled", "disabled": "Деактивирано",
"total": "Total" "total": "Total"
}, },
"coinmarketcap": { "coinmarketcap": {
"configure": "Configure one or more crypto currencies to track", "configure": "Configure one or more crypto currencies to track",
"1hour": "1 Hour", "1hour": "1 Час",
"1day": "1 Day", "1day": "1 Ден",
"7days": "7 Days", "7days": "7 Дена",
"30days": "30 Days" "30days": "30 Days"
}, },
"gotify": { "gotify": {
@@ -254,22 +254,23 @@
"write": "Write", "write": "Write",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Mem",
"swap": "Swap" "swap": "Swap",
"_temp": "Temp"
}, },
"changedetectionio": { "changedetectionio": {
"totalObserved": "Total Observed", "totalObserved": "Total Observed",
"diffsDetected": "Diffs Detected" "diffsDetected": "Diffs Detected"
}, },
"wmo": { "wmo": {
"0-day": "Sunny", "0-day": "Слънчево",
"57-day": "Freezing Drizzle", "57-day": "Freezing Drizzle",
"57-night": "Freezing Drizzle", "57-night": "Freezing Drizzle",
"96-day": "Thunderstorm With Hail", "96-day": "Thunderstorm With Hail",
"96-night": "Thunderstorm With Hail", "96-night": "Thunderstorm With Hail",
"0-night": "Clear", "0-night": "Ясно",
"1-day": "Mainly Sunny", "1-day": "Предимно Слънчево",
"1-night": "Mainly Clear", "1-night": "Предимно Ясно",
"2-day": "Partly Cloudy", "2-day": "Частична Облачност",
"2-night": "Partly Cloudy", "2-night": "Partly Cloudy",
"3-day": "Cloudy", "3-day": "Cloudy",
"3-night": "Cloudy", "3-night": "Cloudy",
@@ -362,7 +363,7 @@
}, },
"navidrome": { "navidrome": {
"nothing_streaming": "No Active Streams", "nothing_streaming": "No Active Streams",
"please_wait": "Please Wait" "please_wait": "Моля Изчакайте"
}, },
"pyload": { "pyload": {
"speed": "Speed", "speed": "Speed",
@@ -381,7 +382,7 @@
}, },
"ping": { "ping": {
"ping": "Ping", "ping": "Ping",
"error": "Error" "error": "Грешка"
}, },
"scrutiny": { "scrutiny": {
"passed": "Passed", "passed": "Passed",
@@ -718,5 +719,19 @@
"authors": "Authors", "authors": "Authors",
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@@ -254,7 +254,8 @@
"write": "Write", "write": "Write",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Mem",
"swap": "Swap" "swap": "Swap",
"_temp": "Temp"
}, },
"changedetectionio": { "changedetectionio": {
"totalObserved": "Total d'observats", "totalObserved": "Total d'observats",
@@ -718,5 +719,19 @@
"authors": "Authors", "authors": "Authors",
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@@ -328,7 +328,8 @@
"write": "Write", "write": "Write",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Mem",
"swap": "Swap" "swap": "Swap",
"_temp": "Temp"
}, },
"quicklaunch": { "quicklaunch": {
"bookmark": "Záložka", "bookmark": "Záložka",
@@ -718,5 +719,19 @@
"authors": "Authors", "authors": "Authors",
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@@ -10,13 +10,13 @@
"movies": "Film", "movies": "Film",
"wanted": "Ønskede", "wanted": "Ønskede",
"missing": "Mangler", "missing": "Mangler",
"queue": "Queue", "queue": "",
"unknown": "Unknown" "unknown": "Ukendt"
}, },
"lidarr": { "lidarr": {
"wanted": "Ønsket", "wanted": "Ønsket",
"queued": "I Kø", "queued": "I Kø",
"artists": "Artists" "artists": "Artister"
}, },
"jellyseerr": { "jellyseerr": {
"available": "Tilgængelig", "available": "Tilgængelig",
@@ -27,13 +27,13 @@
"pending": "Afventer", "pending": "Afventer",
"approved": "Godkendt", "approved": "Godkendt",
"available": "Tilgængelig", "available": "Tilgængelig",
"processing": "Processing" "processing": "Behandler"
}, },
"adguard": { "adguard": {
"queries": "Forespørgsler", "queries": "Forespørgsler",
"blocked": "Blokerede", "blocked": "Blokerede",
"filtered": "Filtreret", "filtered": "Filtreret",
"latency": "Latency" "latency": "Latenstid"
}, },
"speedtest": { "speedtest": {
"upload": "Upload", "upload": "Upload",
@@ -48,7 +48,7 @@
"coinmarketcap": { "coinmarketcap": {
"30days": "30 Dage", "30days": "30 Dage",
"1day": "1 Dag", "1day": "1 Dag",
"configure": "Konfigurer en eller flere crypto valutaer til tracking", "configure": "Konfigurer en eller flere crypto valutaer til tracking",
"7days": "7 Dage", "7days": "7 Dage",
"1hour": "1 time" "1hour": "1 time"
}, },
@@ -73,67 +73,68 @@
"wait": "Vent venligst", "wait": "Vent venligst",
"uptime": "UP", "uptime": "UP",
"days": "d", "days": "d",
"hours": "h", "hours": "t",
"temp": "TEMP", "temp": "TEMP",
"load": "Load", "load": "Load",
"warn": "Warn", "warn": "Advar",
"total": "Total", "total": "Total",
"free": "Free", "free": "Ledig",
"used": "Used", "used": "Brugt",
"crit": "Crit", "crit": "Crit",
"read": "Read", "read": "Læs",
"write": "Write", "write": "Skriv",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Ram",
"swap": "Swap" "swap": "Swap",
"_temp": "Temp"
}, },
"wmo": { "wmo": {
"1-day": "Hovedsageligt solrigt", "1-day": "Overvejende Solrigt",
"48-day": "Tåget", "48-day": "Tåget",
"48-night": "Tåget", "48-night": "Tåget",
"51-day": "Let støvregn", "51-day": "Let Støvregn",
"51-night": "Let støvregn", "51-night": "Let Støvregn",
"66-night": "Frysende regn", "66-night": "Frysende Regn",
"67-day": "Frysende regn", "67-day": "Frysende Regn",
"67-night": "Frysende regn", "67-night": "Frysende Regn",
"71-day": "Let Sne", "71-day": "Let Sne",
"75-night": "Kraftig Sne", "75-night": "Kraftig Sne",
"86-day": "Snebyger", "86-day": "Snebyger",
"86-night": "Snebyger", "86-night": "Snebyger",
"95-day": "Tordenvejr", "95-day": "Tordenvejr",
"99-day": "Tordenvejr med hagl", "99-day": "Tordenvejr Med Hagl",
"99-night": "Tordenvejr med hagl", "99-night": "Tordenvejr Med Hagl",
"0-day": "Solrig", "0-day": "Solrig",
"0-night": "Klart", "0-night": "Klart",
"1-night": "Hovedsageligt klart", "1-night": "Overvejende Skyfrit",
"2-day": "Delvist skyet", "2-day": "Delvist Overskyet",
"2-night": "Delvist skyet", "2-night": "Delvist Overskyet",
"3-day": "Skyet", "3-day": "Skyet",
"3-night": "Skyet", "3-night": "Skyet",
"45-day": "Tåget", "45-day": "Tåget",
"65-day": "Kraftig regn", "65-day": "Kraftig Regn",
"65-night": "Kraftig regn", "65-night": "Kraftig Regn",
"45-night": "Tåget", "45-night": "Tåget",
"53-day": "Støvregn", "53-day": "Støvregn",
"53-night": "Støvregn", "53-night": "Støvregn",
"55-day": "Kraftig støvregn", "55-day": "Kraftig Støvregn",
"55-night": "Kraftig støvregn", "55-night": "Kraftig Støvregn",
"56-day": "Let frysende støvregn", "56-day": "Let Frysende Støvregn",
"56-night": "Let frysende støvregn", "56-night": "Let Frysende Støvregn",
"57-day": "Frysende støvregn", "57-day": "Frysende Støvregn",
"57-night": "Frysende støvregn", "57-night": "Frysende Støvregn",
"61-day": "Let Regn", "61-day": "Let Regn",
"61-night": "Let Regn", "61-night": "Let Regn",
"63-day": "Regn", "63-day": "Regn",
"63-night": "Regn", "63-night": "Regn",
"66-day": "Frysende regn", "66-day": "Frysende Regn",
"71-night": "Let Sne", "71-night": "Let Sne",
"73-day": "Sne", "73-day": "Sne",
"73-night": "Sne", "73-night": "Sne",
"75-day": "Kraftig Sne", "75-day": "Kraftig Sne",
"77-day": "Snekorn", "77-day": "Snekorn",
"80-day": "Lette byger", "80-day": "Lette Byger",
"80-night": "Lette byger", "80-night": "Lette Byger",
"81-day": "Byger", "81-day": "Byger",
"77-night": "Snekorn", "77-night": "Snekorn",
"81-night": "Byger", "81-night": "Byger",
@@ -142,19 +143,19 @@
"85-day": "Snebyger", "85-day": "Snebyger",
"85-night": "Snebyger", "85-night": "Snebyger",
"95-night": "Tordenvejr", "95-night": "Tordenvejr",
"96-day": "Tordenvejr med hagl", "96-day": "Tordenvejr Med Hagl",
"96-night": "Tordenvejr med hagl" "96-night": "Tordenvejr Med Hagl"
}, },
"homebridge": { "homebridge": {
"available_update": "System", "available_update": "System",
"updates": "Opdateringer", "updates": "Opdateringer",
"update_available": "Opdateringer tilgængelige", "update_available": "Opdateringer Tilgængelige",
"up_to_date": "Opdateret", "up_to_date": "Opdateret",
"child_bridges": "Child Bridges", "child_bridges": "Child Bridges",
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Oppe",
"pending": "Pending", "pending": "Afventer",
"down": "Down" "down": "Nede"
}, },
"widget": { "widget": {
"missing_type": "Manglende Widget Type: {{type}}", "missing_type": "Manglende Widget Type: {{type}}",
@@ -162,8 +163,8 @@
"status": "Status", "status": "Status",
"information": "Information", "information": "Information",
"url": "URL", "url": "URL",
"raw_error": "Raw Error", "raw_error": "Rå Fejl",
"response_data": "Response Data" "response_data": "Svardata"
}, },
"weather": { "weather": {
"current": "Nuværende lokation", "current": "Nuværende lokation",
@@ -180,13 +181,13 @@
"free": "Fri", "free": "Fri",
"used": "Brugt", "used": "Brugt",
"load": "Belastning", "load": "Belastning",
"mem": "MEM", "mem": "RAM",
"hours": "h", "hours": "t",
"minutes": "m", "minutes": "m",
"temp": "TEMP", "temp": "TEMP",
"max": "Max", "max": "Max",
"uptime": "UP", "uptime": "UP",
"months": "mo", "months": "mdr",
"days": "d" "days": "d"
}, },
"unifi": { "unifi": {
@@ -204,7 +205,7 @@
"up": "Oppe", "up": "Oppe",
"down": "NED", "down": "NED",
"wait": "Vent venligst", "wait": "Vent venligst",
"empty_data": "Subsystem status unknown" "empty_data": "Subsystem status ukendt"
}, },
"docker": { "docker": {
"cpu": "CPU", "cpu": "CPU",
@@ -213,24 +214,24 @@
"mem": "RAM", "mem": "RAM",
"offline": "Offline", "offline": "Offline",
"error": "Error", "error": "Error",
"unknown": "Unknown", "unknown": "Ukendt",
"running": "Running", "running": "Kører",
"starting": "Starting", "starting": "Starter",
"unhealthy": "Unhealthy", "unhealthy": "Usund",
"not_found": "Not Found", "not_found": "Ikke Fundet",
"exited": "Exited", "exited": "Forladt",
"partial": "Partial", "partial": "Delvis",
"healthy": "Healthy" "healthy": "Sund"
}, },
"emby": { "emby": {
"playing": "Afspiller", "playing": "Afspiller",
"transcoding": "Transcoder", "transcoding": "Transcoder",
"bitrate": "Bitrate", "bitrate": "Bitrate",
"no_active": "Ingen Aktive Streams", "no_active": "Ingen Aktive Streams",
"movies": "Movies", "movies": "Film",
"series": "Series", "series": "Serier",
"episodes": "Episodes", "episodes": "Episoder",
"songs": "Songs" "songs": "Sange"
}, },
"changedetectionio": { "changedetectionio": {
"totalObserved": "Total Observeret", "totalObserved": "Total Observeret",
@@ -241,7 +242,7 @@
"transcoding": "Transcoder", "transcoding": "Transcoder",
"bitrate": "Bitrate", "bitrate": "Bitrate",
"no_active": "Ingen Aktive Streams", "no_active": "Ingen Aktive Streams",
"plex_connection_error": "Check Plex Connection" "plex_connection_error": "Tjek Plex-forbindelse"
}, },
"nzbget": { "nzbget": {
"rate": "Rate", "rate": "Rate",
@@ -274,8 +275,8 @@
"wanted": "Ønsket", "wanted": "Ønsket",
"queued": "I Kø", "queued": "I Kø",
"series": "Serier", "series": "Serier",
"queue": "Queue", "queue": "",
"unknown": "Unknown" "unknown": "Ukendt"
}, },
"readarr": { "readarr": {
"wanted": "Ønskede", "wanted": "Ønskede",
@@ -295,7 +296,7 @@
"blocked": "Blokerede", "blocked": "Blokerede",
"gravity": "Gravity", "gravity": "Gravity",
"queries": "Forespørgsler", "queries": "Forespørgsler",
"blocked_percent": "Blocked %" "blocked_percent": "Blokeret %"
}, },
"portainer": { "portainer": {
"running": "Kørende", "running": "Kørende",
@@ -316,8 +317,8 @@
"enableIndexers": "Indeksører", "enableIndexers": "Indeksører",
"numberOfGrabs": "Grabs", "numberOfGrabs": "Grabs",
"numberOfQueries": "Forespørgsler", "numberOfQueries": "Forespørgsler",
"numberOfFailGrabs": "Fail Grabs", "numberOfFailGrabs": "Fejl Grabs",
"numberOfFailQueries": "Fejl forespørgsler" "numberOfFailQueries": "Fejl Forespørgsler"
}, },
"jackett": { "jackett": {
"configured": "Konfigureret", "configured": "Konfigureret",
@@ -332,9 +333,9 @@
"quicklaunch": { "quicklaunch": {
"bookmark": "Bogmærker", "bookmark": "Bogmærker",
"service": "Service", "service": "Service",
"search": "Search", "search": "Søg",
"custom": "Custom", "custom": "Brugerdefinerede",
"visit": "Visit", "visit": "Besøg",
"url": "URL" "url": "URL"
}, },
"watchtower": { "watchtower": {
@@ -371,25 +372,25 @@
"total": "Total" "total": "Total"
}, },
"gluetun": { "gluetun": {
"public_ip": "Public IP", "public_ip": "Offentlig IP",
"region": "Region", "region": "Region",
"country": "Country" "country": "Land"
}, },
"hdhomerun": { "hdhomerun": {
"channels": "Channels", "channels": "Kanaler",
"hd": "HD" "hd": "HD"
}, },
"ping": { "ping": {
"error": "Error", "error": "Fejl",
"ping": "Ping" "ping": "Ping"
}, },
"scrutiny": { "scrutiny": {
"passed": "Passed", "passed": "Bestået",
"failed": "Failed", "failed": "Mislykket",
"unknown": "Unknown" "unknown": "Ukendt"
}, },
"paperlessngx": { "paperlessngx": {
"inbox": "Inbox", "inbox": "Indbakke",
"total": "Total" "total": "Total"
}, },
"deluge": { "deluge": {
@@ -405,29 +406,29 @@
"seed": "Seed" "seed": "Seed"
}, },
"tdarr": { "tdarr": {
"queue": "Queue", "queue": "",
"processed": "Processed", "processed": "Behandlet",
"errored": "Errored", "errored": "Fejlet",
"saved": "Saved" "saved": "Gemt"
}, },
"miniflux": { "miniflux": {
"read": "Read", "read": "Læst",
"unread": "Unread" "unread": "Ulæst"
}, },
"nextdns": { "nextdns": {
"wait": "Please Wait", "wait": "Vent Venligst",
"no_devices": "No Device Data Received" "no_devices": "Ingen Enhedsdata Modtaget"
}, },
"common": { "common": {
"bibyterate": "{{value, rate(bits: false; binary: true)}}", "bibyterate": "{{value, rate(bits: false; binary: true)}}",
"bibitrate": "{{value, rate(bits: true; binary: true)}}" "bibitrate": "{{value, rate(bits: true; binary: true)}}"
}, },
"omada": { "omada": {
"connectedAp": "Connected APs", "connectedAp": "Forbundne APs",
"activeUser": "Active devices", "activeUser": "Aktive enheder",
"alerts": "Alerts", "alerts": "Advarsler",
"connectedGateway": "Connected gateways", "connectedGateway": "Forbundne gateways",
"connectedSwitches": "Connected switches" "connectedSwitches": "Forbundne switches"
}, },
"downloadstation": { "downloadstation": {
"download": "Download", "download": "Download",
@@ -436,238 +437,238 @@
"seed": "Seed" "seed": "Seed"
}, },
"mikrotik": { "mikrotik": {
"cpuLoad": "CPU Load", "cpuLoad": "CPU Belastning",
"memoryUsed": "Memory Used", "memoryUsed": "Hukommelse Brugt",
"uptime": "Uptime", "uptime": "Oppetid",
"numberOfLeases": "Leases" "numberOfLeases": "Leases"
}, },
"xteve": { "xteve": {
"streams_all": "All Streams", "streams_all": "Alle Streams",
"streams_active": "Active Streams", "streams_active": "Aktive Streams",
"streams_xepg": "XEPG Channels" "streams_xepg": "XEPG Kanaler"
}, },
"opnsense": { "opnsense": {
"cpu": "CPU Load", "cpu": "CPU Belastning",
"memory": "Active Memory", "memory": "Aktiv Hukommelse",
"wanUpload": "WAN Upload", "wanUpload": "WAN Upload",
"wanDownload": "WAN Download" "wanDownload": "WAN Download"
}, },
"moonraker": { "moonraker": {
"printer_state": "Printer State", "printer_state": "Printer Tilstand",
"print_status": "Print Status", "print_status": "Print Status",
"print_progress": "Progress", "print_progress": "Fremskridt",
"layers": "Layers" "layers": "Lag"
}, },
"medusa": { "medusa": {
"wanted": "Wanted", "wanted": "Ønskede",
"queued": "Queued", "queued": "I Kø",
"series": "Series" "series": "Serier"
}, },
"octoprint": { "octoprint": {
"printer_state": "Status", "printer_state": "Status",
"temp_tool": "Tool temp", "temp_tool": "Tool temp",
"temp_bed": "Bed temp", "temp_bed": "Bed temp",
"job_completion": "Completion" "job_completion": "Færdiggørelse"
}, },
"cloudflared": { "cloudflared": {
"origin_ip": "Origin IP", "origin_ip": "Oprindelses-IP",
"status": "Status" "status": "Status"
}, },
"proxmoxbackupserver": { "proxmoxbackupserver": {
"datastore_usage": "Datastore", "datastore_usage": "Datalager",
"failed_tasks_24h": "Failed Tasks 24h", "failed_tasks_24h": "Mislykkede Opgaver 24t",
"cpu_usage": "CPU", "cpu_usage": "CPU",
"memory_usage": "Memory" "memory_usage": "Hukommelse"
}, },
"immich": { "immich": {
"users": "Users", "users": "Brugere",
"photos": "Photos", "photos": "Billeder",
"videos": "Videos", "videos": "Videoer",
"storage": "Storage" "storage": "Lager"
}, },
"uptimekuma": { "uptimekuma": {
"up": "Sites Up", "up": "Sider Oppe",
"down": "Sites Down", "down": "Sider Nede",
"uptime": "Uptime", "uptime": "Oppetid",
"incident": "Incident", "incident": "Hændelse",
"m": "m" "m": "m"
}, },
"komga": { "komga": {
"libraries": "Libraries", "libraries": "Biblioteker",
"series": "Series", "series": "Serier",
"books": "Books" "books": "Bøger"
}, },
"mylar": { "mylar": {
"series": "Series", "series": "Serier",
"issues": "Issues", "issues": "Problemer",
"wanted": "Wanted" "wanted": "Ønskede"
}, },
"photoprism": { "photoprism": {
"albums": "Albums", "albums": "Albums",
"photos": "Photos", "photos": "Billeder",
"videos": "Videos", "videos": "Videoer",
"people": "People" "people": "Mennesker"
}, },
"diskstation": { "diskstation": {
"days": "Days", "days": "Dage",
"uptime": "Uptime", "uptime": "Oppetid",
"volumeAvailable": "Available" "volumeAvailable": "Tilgængelig"
}, },
"fileflows": { "fileflows": {
"queue": "Queue", "queue": "",
"processing": "Processing", "processing": "Behandler",
"processed": "Processed", "processed": "Behandlet",
"time": "Time" "time": "Tid"
}, },
"grafana": { "grafana": {
"totalalerts": "Total Alerts", "totalalerts": "Totale Advarsler",
"dashboards": "Dashboards", "dashboards": "Dashboards",
"datasources": "Data Sources", "datasources": "Data Kilder",
"alertstriggered": "Alerts Triggered" "alertstriggered": "Advarsler Udløst"
}, },
"nextcloud": { "nextcloud": {
"memoryusage": "Memory Usage", "memoryusage": "Hukommelse Forbrug",
"cpuload": "Cpu Load", "cpuload": "Cpu Belastning",
"freespace": "Free Space", "freespace": "Ledig Plads",
"activeusers": "Active Users", "activeusers": "Aktive Brugere",
"numfiles": "Files", "numfiles": "Filer",
"numshares": "Shared Items" "numshares": "Delte Genstande"
}, },
"kopia": { "kopia": {
"status": "Status", "status": "Status",
"size": "Size", "size": "Størrelse",
"lastrun": "Last Run", "lastrun": "Sidst Kørt",
"nextrun": "Next Run", "nextrun": "Næste Kørsel",
"failed": "Failed" "failed": "Mislykket"
}, },
"unmanic": { "unmanic": {
"active_workers": "Active Workers", "active_workers": "Aktive Arbejdere",
"total_workers": "Total Workers", "total_workers": "Totale Arbejdere",
"records_total": "Queue Length" "records_total": " Længde"
}, },
"healthchecks": { "healthchecks": {
"new": "New", "new": "Ny",
"up": "Online", "up": "Online",
"grace": "In Grace Period", "grace": "In Grace Period",
"down": "Offline", "down": "Offline",
"paused": "Paused", "paused": "Pause",
"status": "Status", "status": "Status",
"last_ping": "Last Ping", "last_ping": "Sidste Ping",
"never": "No pings yet" "never": "Ingen Pings Endnu"
}, },
"pterodactyl": { "pterodactyl": {
"servers": "Servers", "servers": "Servere",
"nodes": "Nodes" "nodes": "Noder"
}, },
"prometheus": { "prometheus": {
"targets_up": "Targets Up", "targets_up": "Mål Oppe",
"targets_down": "Targets Down", "targets_down": "Mål Nede",
"targets_total": "Total Targets" "targets_total": "Totale Mål"
}, },
"minecraft": { "minecraft": {
"players": "Players", "players": "Afspillere",
"version": "Version", "version": "Version",
"status": "Status", "status": "Status",
"up": "Online", "up": "Online",
"down": "Offline" "down": "Offline"
}, },
"ghostfolio": { "ghostfolio": {
"gross_percent_today": "Today", "gross_percent_today": "I Dag",
"gross_percent_1y": "One year", "gross_percent_1y": "Et År",
"gross_percent_max": "All time" "gross_percent_max": "Altid"
}, },
"audiobookshelf": { "audiobookshelf": {
"booksDuration": "Duration", "booksDuration": "Varighed",
"podcasts": "Podcasts", "podcasts": "Podcasts",
"books": "Books", "books": "Bøger",
"podcastsDuration": "Duration" "podcastsDuration": "Varighed"
}, },
"homeassistant": { "homeassistant": {
"people_home": "People Home", "people_home": "Personer Hjemme",
"lights_on": "Lights On", "lights_on": "Lys Tændt",
"switches_on": "Switches On" "switches_on": "Kontakter Tændt"
}, },
"freshrss": { "freshrss": {
"subscriptions": "Subscriptions", "subscriptions": "Abonnementer",
"unread": "Unread" "unread": "Ulæst"
}, },
"channelsdvrserver": { "channelsdvrserver": {
"shows": "Shows", "shows": "Shows",
"recordings": "Recordings", "recordings": "Optagelser",
"scheduled": "Scheduled", "scheduled": "Planlagt",
"passes": "Passes" "passes": "Passes"
}, },
"whatsupdocker": { "whatsupdocker": {
"monitoring": "Monitoring", "monitoring": "Overvåger",
"updates": "Updates" "updates": "Opdateringer"
}, },
"tailscale": { "tailscale": {
"address": "Address", "address": "Adresse",
"expires": "Expires", "expires": "Udløber",
"now": "Now", "now": "Nu",
"years": "{{number}}y", "years": "{{number}}y",
"weeks": "{{number}}w", "weeks": "{{number}}w",
"days": "{{number}}d", "days": "{{number}}d",
"hours": "{{number}}h", "hours": "{{number}}h",
"minutes": "{{number}}m", "minutes": "{{number}}m",
"seconds": "{{number}}s", "seconds": "{{number}}s",
"never": "Never", "never": "Aldrig",
"last_seen": "Last Seen", "last_seen": "Sidst Set",
"ago": "{{value}} Ago" "ago": "{{value}} Siden"
}, },
"qnap": { "qnap": {
"cpuUsage": "CPU Usage", "cpuUsage": "CPU Forbrug",
"memUsage": "MEM Usage", "memUsage": "MEM Forbrug",
"systemTempC": "System Temp", "systemTempC": "System Temp",
"poolUsage": "Pool Usage", "poolUsage": "Pool Forbrug",
"volumeUsage": "Volume Usage", "volumeUsage": "Volume Forbrug",
"invalid": "Invalid" "invalid": "Ugyldig"
}, },
"pfsense": { "pfsense": {
"load": "Load Avg", "load": "Belastning Gns",
"memory": "Mem Usage", "memory": "Hukommelse Forbrug",
"wanStatus": "WAN Status", "wanStatus": "WAN Status",
"up": "Up", "up": "Op",
"down": "Down", "down": "Ned",
"temp": "Temp", "temp": "Temp",
"disk": "Disk Usage", "disk": "Disk Forbrug",
"wanIP": "WAN IP" "wanIP": "WAN IP"
}, },
"caddy": { "caddy": {
"upstreams": "Upstreams", "upstreams": "Upstreams",
"requests": "Current requests", "requests": "Aktuelle anmodninger",
"requests_failed": "Failed requests" "requests_failed": "Mislykkede anmodninger"
}, },
"evcc": { "evcc": {
"pv_power": "Production", "pv_power": "Produktion",
"battery_soc": "Battery", "battery_soc": "Batteri",
"grid_power": "Grid", "grid_power": "Gitter",
"home_power": "Consumption", "home_power": "Forbrug",
"charge_power": "Charger", "charge_power": "Oplader",
"watt_hour": "Wh" "watt_hour": "Wh"
}, },
"pialert": { "pialert": {
"total": "Total", "total": "Total",
"connected": "Connected", "connected": "Forbundet",
"new_devices": "New Devices", "new_devices": "Nye Enheder",
"down_alerts": "Down Alerts" "down_alerts": "Nedadvarsler"
}, },
"jdownloader": { "jdownloader": {
"downloadSpeed": "Download Speed", "downloadSpeed": "Hastighed",
"downloadCount": "Queue Count", "downloadCount": "",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Tilbage",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Størrelse"
}, },
"kavita": { "kavita": {
"seriesCount": "Series", "seriesCount": "Serier",
"totalFiles": "Files" "totalFiles": "Filer"
}, },
"gamedig": { "gamedig": {
"name": "Name", "name": "Navn",
"map": "Map", "map": "Kort",
"currentPlayers": "Current players", "currentPlayers": "Nuværende Spillere",
"players": "Players", "players": "Spillere",
"maxPlayers": "Max players", "maxPlayers": "Maks spillere",
"bots": "Bots", "bots": "Bots",
"ping": "Ping", "ping": "Ping",
"status": "Status", "status": "Status",
@@ -675,48 +676,62 @@
"offline": "Offline" "offline": "Offline"
}, },
"azuredevops": { "azuredevops": {
"result": "Result", "result": "Resultat",
"status": "Status", "status": "Status",
"buildId": "Build ID", "buildId": "Build ID",
"succeeded": "Succeeded", "succeeded": "Lykkedes",
"notStarted": "Not Started", "notStarted": "Ikke Startet",
"failed": "Failed", "failed": "Mislykket",
"canceled": "Canceled", "canceled": "Annulleret",
"inProgress": "In Progress", "inProgress": "I Gang",
"totalPrs": "Total PRs", "totalPrs": "Total PRs",
"myPrs": "My PRs", "myPrs": "Mine PRs",
"approved": "Approved" "approved": "Godkendt"
}, },
"urbackup": { "urbackup": {
"ok": "Ok", "ok": "Ok",
"errored": "Errors", "errored": "Fejl",
"noRecent": "Out of Date", "noRecent": "Uddateret",
"totalUsed": "Used Storage" "totalUsed": "Brugt Lager"
}, },
"openmediavault": { "openmediavault": {
"downloading": "Downloading", "downloading": "Downloader",
"total": "Total", "total": "Total",
"running": "Running", "running": "Kører",
"stopped": "Stopped", "stopped": "Stoppet",
"passed": "Passed", "passed": "Gennemført",
"failed": "Failed" "failed": "Mislykket"
}, },
"mealie": { "mealie": {
"recipes": "Recipes", "recipes": "Opskrifter",
"users": "Users", "users": "Brugere",
"categories": "Categories", "categories": "Kategorier",
"tags": "Tags" "tags": "Tags"
}, },
"atsumeru": { "atsumeru": {
"series": "Series", "series": "Serier",
"archives": "Archives", "archives": "Arkiver",
"chapters": "Chapters", "chapters": "Kapitler",
"categories": "Categories" "categories": "Kategorier"
}, },
"calibreweb": { "calibreweb": {
"books": "Books", "books": "Bøger",
"authors": "Authors", "authors": "Forfattere",
"categories": "Categories", "categories": "Kategorier",
"series": "Series" "series": "Serier"
},
"uptimerobot": {
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@@ -34,7 +34,7 @@
"offline": "Offline", "offline": "Offline",
"error": "Fehler", "error": "Fehler",
"unknown": "Unbekannt", "unknown": "Unbekannt",
"running": "Laufend", "running": "Wird ausgeführt",
"starting": "Startet", "starting": "Startet",
"unhealthy": "Unhealthy", "unhealthy": "Unhealthy",
"not_found": "Nicht gefunden", "not_found": "Nicht gefunden",
@@ -48,7 +48,7 @@
"bitrate": "Bitrate", "bitrate": "Bitrate",
"no_active": "Keine aktiven Streams", "no_active": "Keine aktiven Streams",
"movies": "Filme", "movies": "Filme",
"series": "Serien", "series": "Serie",
"episodes": "Folgen", "episodes": "Folgen",
"songs": "Songs" "songs": "Songs"
}, },
@@ -57,7 +57,7 @@
"transcoding": "Transcodierung", "transcoding": "Transcodierung",
"bitrate": "Bitrate", "bitrate": "Bitrate",
"no_active": "Keine aktiven Streams", "no_active": "Keine aktiven Streams",
"plex_connection_error": "Check Plex Connection" "plex_connection_error": "Plex-Verbindung prüfen"
}, },
"rutorrent": { "rutorrent": {
"active": "Aktiv", "active": "Aktiv",
@@ -67,17 +67,17 @@
"sonarr": { "sonarr": {
"wanted": "Gesucht", "wanted": "Gesucht",
"queued": "In Warteschlange", "queued": "In Warteschlange",
"series": "Serien", "series": "Serie",
"queue": "Queue", "queue": "Warteschlange",
"unknown": "Unknown" "unknown": "Unbekannt"
}, },
"radarr": { "radarr": {
"wanted": "Gesucht", "wanted": "Gesucht",
"queued": "In Warteschlange", "queued": "In Warteschlange",
"movies": "Filme", "movies": "Filme",
"missing": "Fehlt", "missing": "Fehlt",
"queue": "Queue", "queue": "Warteschlange",
"unknown": "Unknown" "unknown": "Unbekannt"
}, },
"readarr": { "readarr": {
"wanted": "Gesucht", "wanted": "Gesucht",
@@ -106,7 +106,7 @@
"ping": "Ping" "ping": "Ping"
}, },
"portainer": { "portainer": {
"running": "Betrieb", "running": "Wird ausgeführt",
"stopped": "Gestoppt", "stopped": "Gestoppt",
"total": "Gesamt" "total": "Gesamt"
}, },
@@ -178,7 +178,7 @@
"lidarr": { "lidarr": {
"wanted": "Gesucht", "wanted": "Gesucht",
"queued": "In Warteschlange", "queued": "In Warteschlange",
"artists": "Artists" "artists": "Künstler"
}, },
"adguard": { "adguard": {
"queries": "Anfragen", "queries": "Anfragen",
@@ -249,12 +249,13 @@
"total": "Gesamt", "total": "Gesamt",
"free": "Frei", "free": "Frei",
"used": "Verwendet", "used": "Verwendet",
"write": "Write", "write": "Schreiben",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Mem",
"swap": "Swap", "swap": "Auslagerung",
"crit": "Crit", "crit": "Krit",
"read": "Read" "read": "Lesen",
"_temp": "Temperatur"
}, },
"changedetectionio": { "changedetectionio": {
"totalObserved": "Gesamt beobachtet", "totalObserved": "Gesamt beobachtet",
@@ -438,7 +439,7 @@
"mikrotik": { "mikrotik": {
"cpuLoad": "CPU Auslastung", "cpuLoad": "CPU Auslastung",
"memoryUsed": "RAM Verbrauch", "memoryUsed": "RAM Verbrauch",
"uptime": "Laufzeit", "uptime": "Betriebszeit",
"numberOfLeases": "Leases" "numberOfLeases": "Leases"
}, },
"xteve": { "xteve": {
@@ -488,7 +489,7 @@
"uptimekuma": { "uptimekuma": {
"up": "Seiten verfügbar", "up": "Seiten verfügbar",
"down": "Seiten nicht verfügbar", "down": "Seiten nicht verfügbar",
"uptime": "Laufzeit", "uptime": "Betriebszeit",
"incident": "Vorfall", "incident": "Vorfall",
"m": "m" "m": "m"
}, },
@@ -510,7 +511,7 @@
}, },
"diskstation": { "diskstation": {
"days": "Tage", "days": "Tage",
"uptime": "Laufzeit", "uptime": "Betriebszeit",
"volumeAvailable": "Verfügbar" "volumeAvailable": "Verfügbar"
}, },
"fileflows": { "fileflows": {
@@ -620,7 +621,7 @@
"memUsage": "MEM Nutzung", "memUsage": "MEM Nutzung",
"systemTempC": "System Temp", "systemTempC": "System Temp",
"poolUsage": "Pool Nutzung", "poolUsage": "Pool Nutzung",
"volumeUsage": "Volume Usage", "volumeUsage": "Speicher benutzung",
"invalid": "Ungültig" "invalid": "Ungültig"
}, },
"pfsense": { "pfsense": {
@@ -642,7 +643,7 @@
"watt_hour": "Wh", "watt_hour": "Wh",
"pv_power": "Produktion", "pv_power": "Produktion",
"battery_soc": "Batterie", "battery_soc": "Batterie",
"grid_power": "Grid", "grid_power": "Raster",
"home_power": "Verbrauch", "home_power": "Verbrauch",
"charge_power": "Ladegerät" "charge_power": "Ladegerät"
}, },
@@ -653,70 +654,84 @@
"down_alerts": "Down Alarme" "down_alerts": "Down Alarme"
}, },
"jdownloader": { "jdownloader": {
"downloadCount": "Queue Count", "downloadCount": "Warteschlange",
"downloadSpeed": "Download Speed", "downloadSpeed": "Geschwindigkeit",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "Verbleibend",
"downloadTotalBytes": "Size" "downloadTotalBytes": "Größe"
}, },
"kavita": { "kavita": {
"seriesCount": "Series", "seriesCount": "Serie",
"totalFiles": "Files" "totalFiles": "Dateien"
}, },
"gamedig": { "gamedig": {
"name": "Name", "name": "Name",
"map": "Map", "map": "Karte",
"currentPlayers": "Current players", "currentPlayers": "Aktuelle Spieler",
"players": "Players", "players": "Spieler",
"bots": "Bots", "bots": "Bots",
"ping": "Ping", "ping": "Ping",
"maxPlayers": "Max players", "maxPlayers": "Max. Spieler",
"status": "Status", "status": "Status",
"online": "Online", "online": "Online",
"offline": "Offline" "offline": "Offline"
}, },
"azuredevops": { "azuredevops": {
"result": "Result", "result": "Ergebnis",
"status": "Status", "status": "Status",
"buildId": "Build ID", "buildId": "Build ID",
"succeeded": "Succeeded", "succeeded": "Erfolgreich",
"notStarted": "Not Started", "notStarted": "Nicht gestartet",
"failed": "Failed", "failed": "Fehlgeschlagen",
"canceled": "Canceled", "canceled": "Abgebrochen",
"totalPrs": "Total PRs", "totalPrs": "Total PRs",
"myPrs": "My PRs", "myPrs": "My PRs",
"approved": "Approved", "approved": "Genehmigt",
"inProgress": "In Progress" "inProgress": "In Bearbeitung"
}, },
"urbackup": { "urbackup": {
"ok": "Ok", "ok": "Ok",
"errored": "Errors", "errored": "Fehler",
"noRecent": "Out of Date", "noRecent": "Nicht mehr aktuell",
"totalUsed": "Used Storage" "totalUsed": "Belegter Speicherplatz"
}, },
"openmediavault": { "openmediavault": {
"downloading": "Downloading", "downloading": "Wird heruntergeladen",
"total": "Total", "total": "Gesamt",
"running": "Running", "running": "Wird ausgeführt",
"stopped": "Stopped", "stopped": "Gestoppt",
"passed": "Passed", "passed": "Bestanden",
"failed": "Failed" "failed": "Fehlgeschlagen"
}, },
"mealie": { "mealie": {
"recipes": "Recipes", "recipes": "Recipes",
"users": "Users", "users": "Benutzer",
"categories": "Categories", "categories": "Kategorien",
"tags": "Tags" "tags": "Schlagwörter"
}, },
"atsumeru": { "atsumeru": {
"series": "Series", "series": "Serie",
"archives": "Archives", "archives": "Archive",
"chapters": "Chapters", "chapters": "Kapitel",
"categories": "Categories" "categories": "Kategorien"
}, },
"calibreweb": { "calibreweb": {
"books": "Books", "books": "Bücher",
"authors": "Authors", "authors": "Autoren",
"categories": "Categories", "categories": "Kategorien",
"series": "Series" "series": "Serie"
},
"uptimerobot": {
"status": "Status",
"uptime": "Betriebszeit",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Seiten verfügbar",
"sitesDown": "Seiten nicht verfügbar",
"paused": "Pausiert",
"notyetchecked": "Noch nicht geprüft",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unbekannt"
} }
} }

View File

@@ -375,7 +375,8 @@
"write": "Write", "write": "Write",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Mem",
"swap": "Swap" "swap": "Swap",
"_temp": "Temp"
}, },
"quicklaunch": { "quicklaunch": {
"bookmark": "Bookmark", "bookmark": "Bookmark",
@@ -431,7 +432,7 @@
}, },
"pyload": { "pyload": {
"speed": "Speed", "speed": "Speed",
"active": "Active", "active": "Ενεργό",
"queue": "Queue", "queue": "Queue",
"total": "Total" "total": "Total"
}, },
@@ -718,5 +719,19 @@
"authors": "Authors", "authors": "Authors",
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
},
"uptimerobot": {
"status": "Status",
"up": "Up",
"unknown": "Unknown",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"seemsdown": "Seems Down",
"down": "Down"
} }
} }

View File

@@ -365,6 +365,7 @@
"load": "Load", "load": "Load",
"wait": "Please wait", "wait": "Please wait",
"temp": "TEMP", "temp": "TEMP",
"_temp": "Temp",
"warn": "Warn", "warn": "Warn",
"uptime": "UP", "uptime": "UP",
"total": "Total", "total": "Total",
@@ -727,5 +728,19 @@
"stopped": "Stopped", "stopped": "Stopped",
"passed": "Passed", "passed": "Passed",
"failed": "Failed" "failed": "Failed"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@@ -272,7 +272,8 @@
"write": "Write", "write": "Write",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Mem",
"swap": "Swap" "swap": "Swap",
"_temp": "Temp"
}, },
"quicklaunch": { "quicklaunch": {
"bookmark": "Bookmark", "bookmark": "Bookmark",
@@ -718,5 +719,19 @@
"categories": "Categories", "categories": "Categories",
"authors": "Authors", "authors": "Authors",
"series": "Series" "series": "Series"
},
"uptimerobot": {
"status": "Status",
"notyetchecked": "Not Yet Checked",
"downDuration": "Downtime Duration",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@@ -48,7 +48,7 @@
"bitrate": "Tasa de bits", "bitrate": "Tasa de bits",
"no_active": "Sin transmisiones activas", "no_active": "Sin transmisiones activas",
"movies": "Películas", "movies": "Películas",
"series": "Serie", "series": "Series",
"episodes": "Episodios", "episodes": "Episodios",
"songs": "Canciones" "songs": "Canciones"
}, },
@@ -234,7 +234,7 @@
"plex": { "plex": {
"streams": "Transmisiones activas", "streams": "Transmisiones activas",
"movies": "Películas", "movies": "Películas",
"tv": "Series", "tv": "Programas de televisión",
"albums": "Álbumes" "albums": "Álbumes"
}, },
"glances": { "glances": {
@@ -254,7 +254,8 @@
"write": "Escribir", "write": "Escribir",
"gpu": "GPU", "gpu": "GPU",
"mem": "Memoria", "mem": "Memoria",
"swap": "Intercambiar" "swap": "Intercambiar",
"_temp": "Temperatura"
}, },
"changedetectionio": { "changedetectionio": {
"totalObserved": "Total Observados", "totalObserved": "Total Observados",
@@ -461,7 +462,7 @@
"medusa": { "medusa": {
"wanted": "Querido", "wanted": "Querido",
"queued": "A la espera", "queued": "A la espera",
"series": "Serie" "series": "Series"
}, },
"octoprint": { "octoprint": {
"temp_bed": "Temperatura de la plataforma", "temp_bed": "Temperatura de la plataforma",
@@ -659,7 +660,7 @@
"downloadTotalBytes": "Tamaño" "downloadTotalBytes": "Tamaño"
}, },
"kavita": { "kavita": {
"seriesCount": "Serie", "seriesCount": "Series",
"totalFiles": "Archivos" "totalFiles": "Archivos"
}, },
"gamedig": { "gamedig": {
@@ -714,9 +715,23 @@
"categories": "Categorías" "categories": "Categorías"
}, },
"calibreweb": { "calibreweb": {
"books": "Books", "books": "Libros",
"authors": "Authors", "authors": "Autores",
"categories": "Categories", "categories": "Categorías",
"series": "Series" "series": "Series"
},
"uptimerobot": {
"status": "Estado",
"uptime": "Tiempo de actividad",
"lastDown": "Último periodo de inactividad",
"downDuration": "Tiempo de inactividad",
"sitesUp": "Páginas web con conexión",
"sitesDown": "Páginas web caídas",
"paused": "Pausado",
"notyetchecked": "Aún no verificado",
"up": "Arriba",
"seemsdown": "Parece caída",
"down": "Abajo",
"unknown": "Desconocido"
} }
} }

View File

@@ -437,7 +437,8 @@
"write": "Write", "write": "Write",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Mem",
"swap": "Swap" "swap": "Swap",
"_temp": "Temp"
}, },
"quicklaunch": { "quicklaunch": {
"bookmark": "Bookmark", "bookmark": "Bookmark",
@@ -718,5 +719,19 @@
"authors": "Authors", "authors": "Authors",
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
},
"uptimerobot": {
"uptime": "Uptime",
"status": "Status",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@@ -254,7 +254,8 @@
"write": "Write", "write": "Write",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Mem",
"swap": "Swap" "swap": "Swap",
"_temp": "Temp"
}, },
"changedetectionio": { "changedetectionio": {
"totalObserved": "Total Observed", "totalObserved": "Total Observed",
@@ -718,5 +719,19 @@
"authors": "Authors", "authors": "Authors",
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@@ -254,7 +254,8 @@
"write": "Écrit.", "write": "Écrit.",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mém.", "mem": "Mém.",
"swap": "Swap" "swap": "Swap",
"_temp": "Temp"
}, },
"changedetectionio": { "changedetectionio": {
"totalObserved": "Total Observé", "totalObserved": "Total Observé",
@@ -714,9 +715,23 @@
"categories": "Catégories" "categories": "Catégories"
}, },
"calibreweb": { "calibreweb": {
"series": "Series", "series": "Séries",
"books": "Books", "books": "Ebooks",
"authors": "Authors", "authors": "Auteurs",
"categories": "Categories" "categories": "Catégories"
},
"uptimerobot": {
"status": "Statut",
"uptime": "Disponibilité",
"lastDown": "Dernière interruption",
"downDuration": "Durée d'interruption",
"sitesUp": "Sites en ligne",
"sitesDown": "Sites hors ligne",
"paused": "En pause",
"notyetchecked": "Non vérifié",
"up": "En ligne",
"seemsdown": "Semble hors ligne",
"down": "Hors ligne",
"unknown": "Inconnu"
} }
} }

View File

@@ -254,7 +254,8 @@
"write": "Write", "write": "Write",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Mem",
"swap": "Swap" "swap": "Swap",
"_temp": "Temp"
}, },
"changedetectionio": { "changedetectionio": {
"totalObserved": "Total Observed", "totalObserved": "Total Observed",
@@ -718,5 +719,19 @@
"authors": "Authors", "authors": "Authors",
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@@ -262,7 +262,8 @@
"write": "Write", "write": "Write",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Mem",
"swap": "Swap" "swap": "Swap",
"_temp": "Temp"
}, },
"quicklaunch": { "quicklaunch": {
"bookmark": "Bookmark", "bookmark": "Bookmark",
@@ -718,5 +719,19 @@
"authors": "Authors", "authors": "Authors",
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@@ -254,7 +254,8 @@
"write": "Write", "write": "Write",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Mem",
"swap": "Swap" "swap": "Swap",
"_temp": "Temp"
}, },
"changedetectionio": { "changedetectionio": {
"totalObserved": "Ukupno promatrano", "totalObserved": "Ukupno promatrano",
@@ -718,5 +719,19 @@
"categories": "Categories", "categories": "Categories",
"series": "Series", "series": "Series",
"authors": "Authors" "authors": "Authors"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@@ -254,7 +254,8 @@
"write": "Write", "write": "Write",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Mem",
"swap": "Swap" "swap": "Swap",
"_temp": "Temp"
}, },
"changedetectionio": { "changedetectionio": {
"totalObserved": "Összes Megfigyelt", "totalObserved": "Összes Megfigyelt",
@@ -718,5 +719,19 @@
"authors": "Authors", "authors": "Authors",
"series": "Series", "series": "Series",
"categories": "Categories" "categories": "Categories"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@@ -228,7 +228,8 @@
"write": "Write", "write": "Write",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Mem",
"swap": "Swap" "swap": "Swap",
"_temp": "Temp"
}, },
"quicklaunch": { "quicklaunch": {
"bookmark": "Bookmark", "bookmark": "Bookmark",
@@ -718,5 +719,19 @@
"authors": "Authors", "authors": "Authors",
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@@ -9,11 +9,11 @@
"unknown": "Sconosciuto", "unknown": "Sconosciuto",
"running": "In esecuzione", "running": "In esecuzione",
"starting": "In avvio", "starting": "In avvio",
"unhealthy": "Unhealthy", "unhealthy": "Non sano",
"not_found": "Non trovato", "not_found": "Non trovato",
"exited": "Uscito", "exited": "Uscito",
"partial": "Parziale", "partial": "Parziale",
"healthy": "Healthy" "healthy": "Sano"
}, },
"emby": { "emby": {
"playing": "In riproduzione", "playing": "In riproduzione",
@@ -30,7 +30,7 @@
"transcoding": "Transcodifica", "transcoding": "Transcodifica",
"bitrate": "Bitrate", "bitrate": "Bitrate",
"no_active": "Nessuno Stream Attivo", "no_active": "Nessuno Stream Attivo",
"plex_connection_error": "Check Plex Connection" "plex_connection_error": "Controllo Connessione a Plex"
}, },
"speedtest": { "speedtest": {
"upload": "Upload", "upload": "Upload",
@@ -53,7 +53,7 @@
"status": "Stato", "status": "Stato",
"url": "URL", "url": "URL",
"information": "Informazione", "information": "Informazione",
"raw_error": "Raw Error", "raw_error": "Errore non processato",
"response_data": "Dati risposta" "response_data": "Dati risposta"
}, },
"search": { "search": {
@@ -116,7 +116,7 @@
"blocked_percent": "Bloccato %" "blocked_percent": "Bloccato %"
}, },
"npm": { "npm": {
"enabled": "Attivi", "enabled": "Abilitato",
"disabled": "Disabilitati", "disabled": "Disabilitati",
"total": "Totali" "total": "Totali"
}, },
@@ -156,7 +156,7 @@
}, },
"prowlarr": { "prowlarr": {
"enableIndexers": "Indicizzatori", "enableIndexers": "Indicizzatori",
"numberOfGrabs": "Grabs", "numberOfGrabs": "Grab",
"numberOfQueries": "Interrogazioni", "numberOfQueries": "Interrogazioni",
"numberOfFailGrabs": "Grabs Falliti", "numberOfFailGrabs": "Grabs Falliti",
"numberOfFailQueries": "Queries Fallite" "numberOfFailQueries": "Queries Fallite"
@@ -164,12 +164,12 @@
"transmission": { "transmission": {
"download": "Download", "download": "Download",
"upload": "Upload", "upload": "Upload",
"leech": "Leech", "leech": "In scaricamento",
"seed": "Seed" "seed": "Seed"
}, },
"jackett": { "jackett": {
"configured": "Configurato", "configured": "Configurato",
"errored": "Errore" "errored": "In errore"
}, },
"bazarr": { "bazarr": {
"missingEpisodes": "Episodi Mancanti", "missingEpisodes": "Episodi Mancanti",
@@ -188,7 +188,7 @@
}, },
"qbittorrent": { "qbittorrent": {
"download": "Download", "download": "Download",
"leech": "Leech", "leech": "In scaricamento",
"upload": "Upload", "upload": "Upload",
"seed": "Seed" "seed": "Seed"
}, },
@@ -242,19 +242,20 @@
"wait": "Attendere prego", "wait": "Attendere prego",
"temp": "TEMP", "temp": "TEMP",
"uptime": "UP", "uptime": "UP",
"days": "d", "days": "g",
"hours": "h", "hours": "o",
"load": "Carico", "load": "Carico",
"warn": "Avviso", "warn": "Avviso",
"total": "Totale", "total": "Totale",
"free": "Libero", "free": "Libero",
"used": "Usato", "used": "Usato",
"crit": "Crit", "crit": "Critico",
"read": "Read", "read": "Lettura",
"write": "Write", "write": "Scrittura",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Mem.",
"swap": "Swap" "swap": "Swap",
"_temp": "Temp."
}, },
"changedetectionio": { "changedetectionio": {
"totalObserved": "Totale Osservato", "totalObserved": "Totale Osservato",
@@ -331,7 +332,7 @@
"updates": "Aggiornamenti", "updates": "Aggiornamenti",
"update_available": "Aggiornamento Disponibile", "update_available": "Aggiornamento Disponibile",
"up_to_date": "Aggiornato", "up_to_date": "Aggiornato",
"child_bridges": "Child Bridges", "child_bridges": "Bridge Figli",
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Up",
"pending": "In attesa", "pending": "In attesa",
@@ -373,7 +374,7 @@
"gluetun": { "gluetun": {
"public_ip": "IP pubblico", "public_ip": "IP pubblico",
"region": "Località", "region": "Località",
"country": "Stato" "country": "Paese"
}, },
"hdhomerun": { "hdhomerun": {
"channels": "Canali", "channels": "Canali",
@@ -395,19 +396,19 @@
"deluge": { "deluge": {
"download": "Download", "download": "Download",
"upload": "Upload", "upload": "Upload",
"leech": "Leech", "leech": "In scaricamento",
"seed": "Seed" "seed": "Seed"
}, },
"flood": { "flood": {
"download": "Download", "download": "Download",
"upload": "Upload", "upload": "Upload",
"leech": "Leech", "leech": "In scaricamento",
"seed": "Seed" "seed": "Seed"
}, },
"tdarr": { "tdarr": {
"queue": "In coda", "queue": "In coda",
"processed": "Elaborati", "processed": "Elaborati",
"errored": "Errori", "errored": "In errore",
"saved": "Salvati" "saved": "Salvati"
}, },
"miniflux": { "miniflux": {
@@ -432,7 +433,7 @@
"downloadstation": { "downloadstation": {
"download": "Download", "download": "Download",
"upload": "Upload", "upload": "Upload",
"leech": "Leech", "leech": "In scaricamento",
"seed": "Seed" "seed": "Seed"
}, },
"mikrotik": { "mikrotik": {
@@ -465,8 +466,8 @@
}, },
"octoprint": { "octoprint": {
"printer_state": "Stato", "printer_state": "Stato",
"temp_tool": "Tool temp", "temp_tool": "Temp. utensile",
"temp_bed": "Bed temp", "temp_bed": "Temp. letto",
"job_completion": "Completamento" "job_completion": "Completamento"
}, },
"cloudflared": { "cloudflared": {
@@ -474,7 +475,7 @@
"status": "Stato" "status": "Stato"
}, },
"proxmoxbackupserver": { "proxmoxbackupserver": {
"datastore_usage": "Datastore", "datastore_usage": "Archivio dati",
"failed_tasks_24h": "Attività Non Riuscite 24h", "failed_tasks_24h": "Attività Non Riuscite 24h",
"cpu_usage": "CPU", "cpu_usage": "CPU",
"memory_usage": "Memoria" "memory_usage": "Memoria"
@@ -483,12 +484,12 @@
"users": "Utenti", "users": "Utenti",
"photos": "Foto", "photos": "Foto",
"videos": "Video", "videos": "Video",
"storage": "Memoria" "storage": "Archiviazione"
}, },
"uptimekuma": { "uptimekuma": {
"up": "Siti On", "up": "Siti On",
"down": "Siti Down", "down": "Siti Down",
"uptime": "Uptime", "uptime": "Operatività",
"incident": "Incidente", "incident": "Incidente",
"m": "m" "m": "m"
}, },
@@ -510,7 +511,7 @@
}, },
"diskstation": { "diskstation": {
"days": "Giorni", "days": "Giorni",
"uptime": "Uptime", "uptime": "Periodo Attività",
"volumeAvailable": "Disponibile" "volumeAvailable": "Disponibile"
}, },
"fileflows": { "fileflows": {
@@ -520,7 +521,7 @@
"time": "Tempo" "time": "Tempo"
}, },
"grafana": { "grafana": {
"dashboards": "Dashboards", "dashboards": "Dashboard",
"datasources": "Origine dei Dati", "datasources": "Origine dei Dati",
"totalalerts": "Avvisi Totali", "totalalerts": "Avvisi Totali",
"alertstriggered": "Avvisi Attivati" "alertstriggered": "Avvisi Attivati"
@@ -560,8 +561,8 @@
"nodes": "Nodi" "nodes": "Nodi"
}, },
"prometheus": { "prometheus": {
"targets_up": "Targets Up", "targets_up": "Target Attivi",
"targets_down": "Targets Down", "targets_down": "Target Non Attivi",
"targets_total": "Targets Totali" "targets_total": "Targets Totali"
}, },
"minecraft": { "minecraft": {
@@ -663,60 +664,74 @@
"totalFiles": "File" "totalFiles": "File"
}, },
"gamedig": { "gamedig": {
"name": "Name", "name": "Nome",
"map": "Map", "map": "Mappa",
"currentPlayers": "Current players", "currentPlayers": "Giocatori attuali",
"players": "Players", "players": "Giocatori",
"maxPlayers": "Max players", "maxPlayers": "Giocatori max",
"bots": "Bots", "bots": "Bot",
"ping": "Ping", "ping": "Ping",
"status": "Status", "status": "Stato",
"online": "Online", "online": "Online",
"offline": "Offline" "offline": "Offline"
}, },
"azuredevops": { "azuredevops": {
"result": "Result", "result": "Risultato",
"myPrs": "My PRs", "myPrs": "Miei PR",
"approved": "Approved", "approved": "Approvato",
"status": "Status", "status": "Stato",
"buildId": "Build ID", "buildId": "ID Build",
"succeeded": "Succeeded", "succeeded": "Riuscito",
"notStarted": "Not Started", "notStarted": "Non Avviato",
"failed": "Failed", "failed": "Fallito",
"canceled": "Canceled", "canceled": "Cancellato",
"inProgress": "In Progress", "inProgress": "In corso",
"totalPrs": "Total PRs" "totalPrs": "PR Totali"
}, },
"urbackup": { "urbackup": {
"ok": "Ok", "ok": "Ok",
"errored": "Errors", "errored": "Errori",
"noRecent": "Out of Date", "noRecent": "Obsoleto",
"totalUsed": "Used Storage" "totalUsed": "Spazio usato"
}, },
"openmediavault": { "openmediavault": {
"total": "Total", "total": "Totale",
"running": "Running", "running": "In funzione",
"downloading": "Downloading", "downloading": "Download in corso",
"stopped": "Stopped", "stopped": "Fermati",
"passed": "Passed", "passed": "Riusciti",
"failed": "Failed" "failed": "Falliti"
}, },
"mealie": { "mealie": {
"recipes": "Recipes", "recipes": "Ricette",
"users": "Users", "users": "Utenti",
"categories": "Categories", "categories": "Categorie",
"tags": "Tags" "tags": "Tag"
}, },
"atsumeru": { "atsumeru": {
"series": "Series", "series": "Serie",
"archives": "Archives", "archives": "Archivi",
"chapters": "Chapters", "chapters": "Capitoli",
"categories": "Categories" "categories": "Categorie"
}, },
"calibreweb": { "calibreweb": {
"books": "Books", "books": "Libri",
"authors": "Authors", "authors": "Autori",
"categories": "Categories", "categories": "Categorie",
"series": "Series" "series": "Serie"
},
"uptimerobot": {
"status": "Stato",
"uptime": "Tempo di attività",
"lastDown": "Ultimo periodo di inattività",
"downDuration": "Durata inattività",
"sitesUp": "Siti attivi",
"sitesDown": "Siti non attivi",
"paused": "In pausa",
"notyetchecked": "Non ancora controllati",
"up": "Attivi",
"seemsdown": "Sembrano non attivi",
"down": "Non attivi",
"unknown": "Sconosciuto"
} }
} }

View File

@@ -11,7 +11,7 @@
"strelaysrv": { "strelaysrv": {
"numActiveSessions": "セッション", "numActiveSessions": "セッション",
"numConnections": "コネクション", "numConnections": "コネクション",
"dataRelayed": "Relayed", "dataRelayed": "中継",
"transferRate": "レート" "transferRate": "レート"
}, },
"glances": { "glances": {
@@ -21,17 +21,18 @@
"uptime": "UP", "uptime": "UP",
"days": "日", "days": "日",
"hours": "時間", "hours": "時間",
"load": "Load", "load": "ロード",
"warn": "Warn", "warn": "警告",
"total": "Total", "total": "トータル",
"free": "Free", "free": "空き",
"used": "Used", "used": "使用中",
"crit": "Crit", "crit": "Crit",
"read": "Read", "read": "読み込み",
"write": "Write", "write": "書き込み",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "メモリ",
"swap": "Swap" "swap": "スワップ",
"_temp": "Temp"
}, },
"autobrr": { "autobrr": {
"filters": "フィルター", "filters": "フィルター",
@@ -131,7 +132,7 @@
"flood": { "flood": {
"download": "ダウンロード", "download": "ダウンロード",
"upload": "アップロード", "upload": "アップロード",
"leech": "Leech", "leech": "リーチ",
"seed": "Seed" "seed": "Seed"
}, },
"changedetectionio": { "changedetectionio": {
@@ -143,7 +144,7 @@
"transcoding": "変換中", "transcoding": "変換中",
"bitrate": "ビットレート", "bitrate": "ビットレート",
"no_active": "アクティブストリームなし", "no_active": "アクティブストリームなし",
"plex_connection_error": "Check Plex Connection" "plex_connection_error": "Plex接続の確認"
}, },
"omada": { "omada": {
"connectedAp": "接続されたAP", "connectedAp": "接続されたAP",
@@ -176,7 +177,7 @@
"transmission": { "transmission": {
"download": "ダウンロード", "download": "ダウンロード",
"upload": "アップロード", "upload": "アップロード",
"leech": "Leech", "leech": "リーチ",
"seed": "Seed" "seed": "Seed"
}, },
"qbittorrent": { "qbittorrent": {
@@ -201,21 +202,21 @@
"wanted": "募集中", "wanted": "募集中",
"queued": "待機中", "queued": "待機中",
"series": "シリーズ", "series": "シリーズ",
"queue": "Queue", "queue": "キュー",
"unknown": "Unknown" "unknown": "不明"
}, },
"radarr": { "radarr": {
"wanted": "募集中", "wanted": "募集中",
"missing": "不明", "missing": "不明",
"queued": "キュー", "queued": "キュー",
"movies": "映画", "movies": "映画",
"queue": "Queue", "queue": "キュー",
"unknown": "Unknown" "unknown": "Unknown"
}, },
"lidarr": { "lidarr": {
"wanted": "募集中", "wanted": "募集中",
"queued": "キュー", "queued": "キュー",
"artists": "Artists" "artists": "アーティスト"
}, },
"readarr": { "readarr": {
"wanted": "募集中", "wanted": "募集中",
@@ -224,7 +225,7 @@
}, },
"bazarr": { "bazarr": {
"missingEpisodes": "欠番エピソード", "missingEpisodes": "欠番エピソード",
"missingMovies": "不明映画" "missingMovies": "行方不明映画"
}, },
"ombi": { "ombi": {
"pending": "保留中", "pending": "保留中",
@@ -292,7 +293,7 @@
"numberOfGrabs": "Grabs", "numberOfGrabs": "Grabs",
"numberOfQueries": "クエリ", "numberOfQueries": "クエリ",
"numberOfFailGrabs": "Fail Grabs", "numberOfFailGrabs": "Fail Grabs",
"numberOfFailQueries": "Fail Queries" "numberOfFailQueries": "失敗クエリー"
}, },
"jackett": { "jackett": {
"configured": "設定済", "configured": "設定済",
@@ -304,8 +305,8 @@
"domain_count": "ドメイン" "domain_count": "ドメイン"
}, },
"miniflux": { "miniflux": {
"read": "Read", "read": "既読",
"unread": "Unread" "unread": "未読"
}, },
"authentik": { "authentik": {
"users": "ユーザー", "users": "ユーザー",
@@ -461,7 +462,7 @@
"medusa": { "medusa": {
"wanted": "Wanted", "wanted": "Wanted",
"queued": "Queued", "queued": "Queued",
"series": "Series" "series": "シリーズ"
}, },
"octoprint": { "octoprint": {
"temp_bed": "ベッド温度", "temp_bed": "ベッド温度",
@@ -474,7 +475,7 @@
"status": "状態" "status": "状態"
}, },
"proxmoxbackupserver": { "proxmoxbackupserver": {
"datastore_usage": "Datastore", "datastore_usage": "データストア",
"failed_tasks_24h": "失敗タスク(24h)", "failed_tasks_24h": "失敗タスク(24h)",
"cpu_usage": "CPU", "cpu_usage": "CPU",
"memory_usage": "メモリ" "memory_usage": "メモリ"
@@ -499,7 +500,7 @@
}, },
"mylar": { "mylar": {
"series": "シリーズ", "series": "シリーズ",
"issues": "Issues", "issues": "課題",
"wanted": "Wanted" "wanted": "Wanted"
}, },
"photoprism": { "photoprism": {
@@ -546,7 +547,7 @@
"records_total": "キューの長さ" "records_total": "キューの長さ"
}, },
"healthchecks": { "healthchecks": {
"never": "まだPingはありません", "never": "Pingしていません",
"new": "New", "new": "New",
"up": "オンライン", "up": "オンライン",
"grace": "猶予期間中", "grace": "猶予期間中",
@@ -595,10 +596,10 @@
"shows": "ショー", "shows": "ショー",
"recordings": "レコーディング", "recordings": "レコーディング",
"scheduled": "予定済", "scheduled": "予定済",
"passes": "Passes" "passes": "パス"
}, },
"whatsupdocker": { "whatsupdocker": {
"monitoring": "Monitoring", "monitoring": "モニタリング",
"updates": "アップデート" "updates": "アップデート"
}, },
"tailscale": { "tailscale": {
@@ -621,22 +622,22 @@
"systemTempC": "システム温度", "systemTempC": "システム温度",
"poolUsage": "プール使用量", "poolUsage": "プール使用量",
"volumeUsage": "ボリューム使用量", "volumeUsage": "ボリューム使用量",
"invalid": "Invalid" "invalid": "無効"
}, },
"pfsense": { "pfsense": {
"up": "Up", "up": "アップ",
"load": "Load Avg", "load": "読み込み平均",
"memory": "Mem Usage", "memory": "メモリ使用量",
"wanStatus": "WAN Status", "wanStatus": "WANステータス",
"down": "Down", "down": "ダウン",
"temp": "Temp", "temp": "温度",
"disk": "Disk Usage", "disk": "ディスク使用量",
"wanIP": "WAN IP" "wanIP": "WAN IP"
}, },
"caddy": { "caddy": {
"upstreams": "Upstreams", "upstreams": "アップストリーム",
"requests": "Current requests", "requests": "現在のリクエスト",
"requests_failed": "Failed requests" "requests_failed": "失敗したリクエスト"
}, },
"evcc": { "evcc": {
"watt_hour": "Wh", "watt_hour": "Wh",
@@ -647,76 +648,90 @@
"charge_power": "チャージャー" "charge_power": "チャージャー"
}, },
"pialert": { "pialert": {
"total": "Total", "total": "トータル",
"connected": "Connected", "connected": "接続済み",
"new_devices": "New Devices", "new_devices": "新しいデバイス",
"down_alerts": "Down Alerts" "down_alerts": "ダウンアラート"
}, },
"jdownloader": { "jdownloader": {
"downloadCount": "Queue Count", "downloadCount": "キュー",
"downloadSpeed": "Download Speed", "downloadSpeed": "スピード",
"downloadBytesRemaining": "Remaining", "downloadBytesRemaining": "残り",
"downloadTotalBytes": "Size" "downloadTotalBytes": "サイズ"
}, },
"kavita": { "kavita": {
"seriesCount": "Series", "seriesCount": "シリーズ",
"totalFiles": "Files" "totalFiles": "ファイル"
}, },
"gamedig": { "gamedig": {
"name": "Name", "name": "名前",
"map": "Map", "map": "マップ",
"currentPlayers": "Current players", "currentPlayers": "現在のプレーヤー",
"players": "Players", "players": "プレーヤー",
"maxPlayers": "Max players", "maxPlayers": "最大プレーヤー",
"bots": "Bots", "bots": "ボット",
"ping": "Ping", "ping": "Ping",
"status": "Status", "status": "ステータス",
"online": "Online", "online": "オンライン",
"offline": "Offline" "offline": "オフライン"
}, },
"azuredevops": { "azuredevops": {
"result": "Result", "result": "結果",
"status": "Status", "status": "ステータス",
"buildId": "Build ID", "buildId": "ビルドID",
"succeeded": "Succeeded", "succeeded": "成功",
"notStarted": "Not Started", "notStarted": "Not Started",
"failed": "Failed", "failed": "失敗",
"canceled": "Canceled", "canceled": "キャンセル",
"inProgress": "In Progress", "inProgress": "進行中",
"totalPrs": "Total PRs", "totalPrs": "合計PR",
"myPrs": "My PRs", "myPrs": "私のPR",
"approved": "Approved" "approved": "承認"
}, },
"urbackup": { "urbackup": {
"ok": "Ok", "ok": "Ok",
"errored": "Errors", "errored": "エラー",
"noRecent": "Out of Date", "noRecent": "期限切れ",
"totalUsed": "Used Storage" "totalUsed": "使用済みストレージ"
}, },
"openmediavault": { "openmediavault": {
"downloading": "Downloading", "downloading": "ダウンロード中",
"total": "Total", "total": "トータル",
"running": "Running", "running": "実行中",
"stopped": "Stopped", "stopped": "停止中",
"passed": "Passed", "passed": "合格",
"failed": "Failed" "failed": "不合格"
}, },
"mealie": { "mealie": {
"recipes": "Recipes", "recipes": "レシピ",
"users": "Users", "users": "ユーザー",
"categories": "Categories", "categories": "カテゴリー",
"tags": "Tags" "tags": "タグ"
}, },
"atsumeru": { "atsumeru": {
"series": "Series", "series": "シリーズ",
"archives": "Archives", "archives": "アーカイブ",
"chapters": "Chapters", "chapters": "チャプター",
"categories": "Categories" "categories": "カテゴリー"
}, },
"calibreweb": { "calibreweb": {
"books": "Books", "books": "書籍",
"authors": "Authors", "authors": "著者",
"categories": "Categories", "categories": "カテゴリー",
"series": "Series" "series": "シリーズ"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@@ -321,7 +321,8 @@
"write": "Write", "write": "Write",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Mem",
"swap": "Swap" "swap": "Swap",
"_temp": "Temp"
}, },
"quicklaunch": { "quicklaunch": {
"bookmark": "Bookmark", "bookmark": "Bookmark",
@@ -718,5 +719,19 @@
"authors": "Authors", "authors": "Authors",
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@@ -310,7 +310,8 @@
"write": "Write", "write": "Write",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Mem",
"swap": "Swap" "swap": "Swap",
"_temp": "Temp"
}, },
"quicklaunch": { "quicklaunch": {
"bookmark": "Bookmark", "bookmark": "Bookmark",
@@ -718,5 +719,19 @@
"authors": "Authors", "authors": "Authors",
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
},
"uptimerobot": {
"unknown": "Unknown",
"status": "Status",
"uptime": "Uptime",
"sitesDown": "Sites Down",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down"
} }
} }

View File

@@ -81,7 +81,8 @@
"write": "Write", "write": "Write",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Mem",
"swap": "Swap" "swap": "Swap",
"_temp": "Temp"
}, },
"quicklaunch": { "quicklaunch": {
"bookmark": "Tandabuku", "bookmark": "Tandabuku",
@@ -718,5 +719,19 @@
"authors": "Authors", "authors": "Authors",
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@@ -254,7 +254,8 @@
"write": "Write", "write": "Write",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Mem",
"swap": "Swap" "swap": "Swap",
"_temp": "Temp"
}, },
"changedetectionio": { "changedetectionio": {
"totalObserved": "Total Observed", "totalObserved": "Total Observed",
@@ -718,5 +719,19 @@
"authors": "Authors", "authors": "Authors",
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
},
"uptimerobot": {
"uptime": "Uptime",
"status": "Status",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@@ -1,20 +1,20 @@
{ {
"widget": { "widget": {
"missing_type": "Missend Widget Type: {{type}}", "missing_type": "Missend Widget Type: {{type}}",
"api_error": "API Error", "api_error": "API fout",
"status": "Status", "status": "Status",
"information": "Informatie", "information": "Informatie",
"url": "URL", "url": "URL",
"raw_error": "Raw Fout", "raw_error": "Raw Error",
"response_data": "Reactiegegevens" "response_data": "Responsgegevens"
}, },
"resources": { "resources": {
"total": "Totaal", "total": "Totaal",
"free": "Vrij", "free": "Vrij",
"used": "Gebruikt", "used": "Gebruikt",
"load": "Laadt", "load": "lading",
"cpu": "CPU", "cpu": "CPU",
"mem": "MEM", "mem": "GEH",
"days": "d", "days": "d",
"hours": "h", "hours": "h",
"temp": "TEMP", "temp": "TEMP",
@@ -31,7 +31,7 @@
"offline": "Offline", "offline": "Offline",
"error": "Fout", "error": "Fout",
"unknown": "Onbekend", "unknown": "Onbekend",
"running": "Running", "running": "Lopend",
"starting": "Starten", "starting": "Starten",
"unhealthy": "Ongezond", "unhealthy": "Ongezond",
"not_found": "Niet Gevonden", "not_found": "Niet Gevonden",
@@ -72,8 +72,8 @@
"playing": "Afspelen", "playing": "Afspelen",
"transcoding": "Transcodering", "transcoding": "Transcodering",
"bitrate": "Bitsnelheid", "bitrate": "Bitsnelheid",
"no_active": "Geen Actieve Streams", "no_active": "Geen actieve streams",
"plex_connection_error": "Check Plex Connection" "plex_connection_error": "Controleer Plex Connectie"
}, },
"rutorrent": { "rutorrent": {
"active": "Actief", "active": "Actief",
@@ -84,16 +84,16 @@
"wanted": "Gezocht", "wanted": "Gezocht",
"queued": "In de wachtrij", "queued": "In de wachtrij",
"series": "Series", "series": "Series",
"queue": "Queue", "queue": "Rij",
"unknown": "Unknown" "unknown": "Onbekend"
}, },
"radarr": { "radarr": {
"movies": "Films", "movies": "Films",
"wanted": "Gezocht", "wanted": "Gezocht",
"queued": "In de wachtrij", "queued": "In de wachtrij",
"missing": "Missend", "missing": "Missend",
"queue": "Queue", "queue": "Rij",
"unknown": "Unknown" "unknown": "Onbekend"
}, },
"readarr": { "readarr": {
"wanted": "Gezocht", "wanted": "Gezocht",
@@ -114,7 +114,7 @@
"queries": "Queries", "queries": "Queries",
"blocked": "Geblokkeerd", "blocked": "Geblokkeerd",
"gravity": "Gravity", "gravity": "Gravity",
"blocked_percent": "Blocked %" "blocked_percent": "Geblokkerde %"
}, },
"traefik": { "traefik": {
"routers": "Routers", "routers": "Routers",
@@ -135,15 +135,15 @@
"sabnzbd": { "sabnzbd": {
"rate": "Rate", "rate": "Rate",
"queue": "Wachtrij", "queue": "Wachtrij",
"timeleft": "Time Left" "timeleft": "Tijd Over"
}, },
"nzbget": { "nzbget": {
"rate": "Rate", "rate": "Tarief",
"remaining": "Resterend", "remaining": "Resterend",
"downloaded": "Gedownload" "downloaded": "Gedownload"
}, },
"coinmarketcap": { "coinmarketcap": {
"configure": "Configure one or more crypto currencies to track", "configure": "Configureer een of meer crypto eenheiden om bij te houden",
"1hour": "1 Uur", "1hour": "1 Uur",
"7days": "7 Dagen", "7days": "7 Dagen",
"1day": "1 Dag", "1day": "1 Dag",
@@ -151,7 +151,7 @@
}, },
"gotify": { "gotify": {
"apps": "Applicaties", "apps": "Applicaties",
"clients": "Clients", "clients": "Cliënten",
"messages": "Berichten" "messages": "Berichten"
}, },
"prowlarr": { "prowlarr": {
@@ -164,7 +164,7 @@
"transmission": { "transmission": {
"download": "Download", "download": "Download",
"upload": "Upload", "upload": "Upload",
"leech": "Leech", "leech": "Bloedzuiger",
"seed": "Seed" "seed": "Seed"
}, },
"jackett": { "jackett": {
@@ -178,28 +178,28 @@
"lidarr": { "lidarr": {
"wanted": "Gezocht", "wanted": "Gezocht",
"queued": "In de wachtrij", "queued": "In de wachtrij",
"artists": "Artists" "artists": "Artiesten"
}, },
"adguard": { "adguard": {
"queries": "Queries", "queries": "Queries",
"blocked": "Geblokkeerd", "blocked": "Geblokkeerd",
"filtered": "Filtered", "filtered": "Gefilterde",
"latency": "Latency" "latency": "Latency"
}, },
"qbittorrent": { "qbittorrent": {
"download": "Download", "download": "Download",
"upload": "Upload", "upload": "Upload",
"leech": "Leech", "leech": "Bloedzuiger",
"seed": "Seed" "seed": "Seed"
}, },
"mastodon": { "mastodon": {
"user_count": "Users", "user_count": "Gebruikers",
"status_count": "Posts", "status_count": "Posts",
"domain_count": "Domeinen" "domain_count": "Domeinen"
}, },
"strelaysrv": { "strelaysrv": {
"numActiveSessions": "Sessions", "numActiveSessions": "Sessies",
"numConnections": "Connections", "numConnections": "Connecties",
"dataRelayed": "Relayed", "dataRelayed": "Relayed",
"transferRate": "Rate" "transferRate": "Rate"
}, },
@@ -223,13 +223,13 @@
"wlan_users": "WLAN Gebruikers", "wlan_users": "WLAN Gebruikers",
"up": "UP", "up": "UP",
"down": "DOWN", "down": "DOWN",
"wait": "Wachten aub", "wait": "Even geduld",
"lan": "LAN", "lan": "LAN",
"wlan": "WLAN", "wlan": "WLAN",
"devices": "Apparaten", "devices": "Apparaten",
"lan_devices": "LAN Apparaten", "lan_devices": "LAN Apparaten",
"wlan_devices": "WLAN Apparaten", "wlan_devices": "WLAN Apparaten",
"empty_data": "Subsystem status onbekend" "empty_data": "Subsysteem status onbekend"
}, },
"plex": { "plex": {
"streams": "Actieve Streams", "streams": "Actieve Streams",
@@ -254,7 +254,8 @@
"write": "Write", "write": "Write",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Mem",
"swap": "Swap" "swap": "Swap",
"_temp": "Temp"
}, },
"changedetectionio": { "changedetectionio": {
"totalObserved": "Totaal waargenomen", "totalObserved": "Totaal waargenomen",
@@ -395,7 +396,7 @@
"deluge": { "deluge": {
"download": "Download", "download": "Download",
"upload": "Upload", "upload": "Upload",
"leech": "Leech", "leech": "Bloedzuiger",
"seed": "Seed" "seed": "Seed"
}, },
"flood": { "flood": {
@@ -408,7 +409,7 @@
"queue": "Wachtrij", "queue": "Wachtrij",
"processed": "Processed", "processed": "Processed",
"errored": "Errored", "errored": "Errored",
"saved": "Saved" "saved": "Opgeslagen"
}, },
"miniflux": { "miniflux": {
"read": "Gelezen", "read": "Gelezen",
@@ -423,16 +424,16 @@
"bibitrate": "{{value, rate(bits: true; binary: true)}}" "bibitrate": "{{value, rate(bits: true; binary: true)}}"
}, },
"omada": { "omada": {
"connectedAp": "Connected APs", "connectedAp": "Verbonden APs",
"activeUser": "Actieve apparaten", "activeUser": "Actieve apparaten",
"alerts": "Meldingen", "alerts": "Meldingen",
"connectedGateway": "Connected gateways", "connectedGateway": "Verbonden gateways",
"connectedSwitches": "Connected switches" "connectedSwitches": "Verbonden switches"
}, },
"downloadstation": { "downloadstation": {
"download": "Download", "download": "Download",
"upload": "Upload", "upload": "Upload",
"leech": "Leech", "leech": "Bloedzuiger",
"seed": "Seed" "seed": "Seed"
}, },
"mikrotik": { "mikrotik": {
@@ -459,7 +460,7 @@
"layers": "Layers" "layers": "Layers"
}, },
"medusa": { "medusa": {
"wanted": "Wanted", "wanted": "Gewild",
"queued": "Queued", "queued": "Queued",
"series": "Series" "series": "Series"
}, },
@@ -588,13 +589,13 @@
"switches_on": "Switches On" "switches_on": "Switches On"
}, },
"freshrss": { "freshrss": {
"subscriptions": "Subscriptions", "subscriptions": "Abonnementen",
"unread": "Unread" "unread": "Ongelezen"
}, },
"channelsdvrserver": { "channelsdvrserver": {
"shows": "Shows", "shows": "Shows",
"recordings": "Recordings", "recordings": "Recordings",
"scheduled": "Scheduled", "scheduled": "Geplanned",
"passes": "Passes" "passes": "Passes"
}, },
"whatsupdocker": { "whatsupdocker": {
@@ -603,25 +604,25 @@
}, },
"tailscale": { "tailscale": {
"address": "Address", "address": "Address",
"expires": "Expires", "expires": "Verloopt",
"never": "Never", "never": "Nooit",
"last_seen": "Last Seen", "last_seen": "Laatst Gezien",
"now": "Now", "now": "Nu",
"years": "{{number}}y", "years": "{{number}}y",
"weeks": "{{number}}w", "weeks": "{{number}}w",
"days": "{{number}}d", "days": "{{number}}d",
"hours": "{{number}}h", "hours": "{{number}}h",
"minutes": "{{number}}m", "minutes": "{{number}}m",
"seconds": "{{number}}s", "seconds": "{{number}}s",
"ago": "{{value}} Ago" "ago": "{{value}} Geleden"
}, },
"qnap": { "qnap": {
"cpuUsage": "CPU Usage", "cpuUsage": "CPU Verbruik",
"memUsage": "MEM Usage", "memUsage": "MEM Gebruik",
"systemTempC": "System Temp", "systemTempC": "Systeem Temperatuur",
"poolUsage": "Pool Usage", "poolUsage": "Pool Gebruik",
"volumeUsage": "Volume Usage", "volumeUsage": "Volume Usage",
"invalid": "Invalid" "invalid": "ongeldig"
}, },
"pfsense": { "pfsense": {
"load": "Load Avg", "load": "Load Avg",
@@ -635,21 +636,21 @@
}, },
"caddy": { "caddy": {
"upstreams": "Upstreams", "upstreams": "Upstreams",
"requests": "Current requests", "requests": "Momentele verzoeken",
"requests_failed": "Failed requests" "requests_failed": "Gefaalde verzoeken"
}, },
"evcc": { "evcc": {
"pv_power": "Production", "pv_power": "Productie",
"battery_soc": "Battery", "battery_soc": "Battery",
"grid_power": "Grid", "grid_power": "Grid",
"home_power": "Consumption", "home_power": "Consumption",
"charge_power": "Charger", "charge_power": "Oplader",
"watt_hour": "Wh" "watt_hour": "Wh"
}, },
"pialert": { "pialert": {
"total": "Total", "total": "Total",
"connected": "Connected", "connected": "Verbonden",
"new_devices": "New Devices", "new_devices": "Nieuwe Apparaten",
"down_alerts": "Down Alerts" "down_alerts": "Down Alerts"
}, },
"jdownloader": { "jdownloader": {
@@ -718,5 +719,19 @@
"authors": "Authors", "authors": "Authors",
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
},
"uptimerobot": {
"uptime": "Uptime",
"status": "Status",
"up": "Up",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@@ -254,7 +254,8 @@
"write": "Write", "write": "Write",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Mem",
"swap": "Swap" "swap": "Swap",
"_temp": "Temp"
}, },
"changedetectionio": { "changedetectionio": {
"diffsDetected": "Wykryto różnic", "diffsDetected": "Wykryto różnic",
@@ -718,5 +719,19 @@
"authors": "Authors", "authors": "Authors",
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@@ -254,7 +254,8 @@
"write": "Write", "write": "Write",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Mem",
"swap": "Swap" "swap": "Swap",
"_temp": "Temp"
}, },
"changedetectionio": { "changedetectionio": {
"totalObserved": "Observados", "totalObserved": "Observados",
@@ -718,5 +719,19 @@
"authors": "Authors", "authors": "Authors",
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@@ -267,7 +267,8 @@
"write": "Write", "write": "Write",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Mem",
"swap": "Swap" "swap": "Swap",
"_temp": "Temp"
}, },
"changedetectionio": { "changedetectionio": {
"totalObserved": "Total Observado", "totalObserved": "Total Observado",
@@ -727,5 +728,19 @@
"authors": "Authors", "authors": "Authors",
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
},
"uptimerobot": {
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown",
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up"
} }
} }

View File

@@ -20,12 +20,12 @@
"mem": "MEM", "mem": "MEM",
"cpu": "CPU", "cpu": "CPU",
"offline": "Offline", "offline": "Offline",
"error": "Error", "error": "Eroare",
"unknown": "Unknown", "unknown": "Necunoscut",
"running": "Running", "running": "Rulează",
"starting": "Starting", "starting": "Începe",
"unhealthy": "Unhealthy", "unhealthy": "Unhealthy",
"not_found": "Not Found", "not_found": "Negăsit",
"exited": "Exited", "exited": "Exited",
"partial": "Partial", "partial": "Partial",
"healthy": "Healthy" "healthy": "Healthy"
@@ -254,7 +254,8 @@
"write": "Write", "write": "Write",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Mem",
"swap": "Swap" "swap": "Swap",
"_temp": "Temp"
}, },
"changedetectionio": { "changedetectionio": {
"totalObserved": "Total Observed", "totalObserved": "Total Observed",
@@ -718,5 +719,19 @@
"authors": "Authors", "authors": "Authors",
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"sitesDown": "Sites Down",
"paused": "Paused",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@@ -18,7 +18,7 @@
"load": "Загрузка", "load": "Загрузка",
"cpu": "ЦП", "cpu": "ЦП",
"mem": "ОЗУ", "mem": "ОЗУ",
"temp": "Темпер.", "temp": "Температура",
"max": "Макс.", "max": "Макс.",
"uptime": "Работает", "uptime": "Работает",
"months": "мес", "months": "мес",
@@ -254,7 +254,8 @@
"write": "Write", "write": "Write",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Mem",
"swap": "Swap" "swap": "Swap",
"_temp": "Temp"
}, },
"changedetectionio": { "changedetectionio": {
"totalObserved": "Всего наблюдаемых", "totalObserved": "Всего наблюдаемых",
@@ -718,5 +719,19 @@
"authors": "Authors", "authors": "Authors",
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@@ -2,18 +2,18 @@
"docker": { "docker": {
"rx": "RX", "rx": "RX",
"tx": "TX", "tx": "TX",
"mem": "MEM", "mem": "RAM",
"cpu": "CPU", "cpu": "CPU",
"offline": "Offline", "offline": "Offline",
"error": "Error", "error": "Chyba",
"unknown": "Unknown", "unknown": "Neznáme",
"running": "Running", "running": "Beží",
"starting": "Starting", "starting": "Spúšťa sa",
"unhealthy": "Unhealthy", "unhealthy": "Nezdravý",
"not_found": "Not Found", "not_found": "Nenájdené",
"exited": "Exited", "exited": "Ukončené",
"partial": "Partial", "partial": "Čiastočný",
"healthy": "Healthy" "healthy": "Zdravý"
}, },
"rutorrent": { "rutorrent": {
"active": "Active", "active": "Active",
@@ -21,10 +21,10 @@
"download": "Download" "download": "Download"
}, },
"tdarr": { "tdarr": {
"queue": "Queue", "queue": "Fronta",
"processed": "Processed", "processed": "Spracované",
"errored": "Errored", "errored": "Chybné",
"saved": "Saved" "saved": "Uložené"
}, },
"strelaysrv": { "strelaysrv": {
"numActiveSessions": "Sessions", "numActiveSessions": "Sessions",
@@ -144,74 +144,74 @@
"bibitrate": "{{value, rate(bits: true; binary: true)}}" "bibitrate": "{{value, rate(bits: true; binary: true)}}"
}, },
"widget": { "widget": {
"api_error": "API Error", "api_error": "Chyba API",
"missing_type": "Missing Widget Type: {{type}}", "missing_type": "Chýba typ widgetu: {{type}}",
"information": "Information", "information": "Informácia",
"status": "Status", "status": "Stav",
"url": "URL", "url": "URL",
"raw_error": "Raw Error", "raw_error": "Nevyriešená chyba",
"response_data": "Response Data" "response_data": "Dáta odpovede"
}, },
"weather": { "weather": {
"current": "Current Location", "current": "Aktuálna poloha",
"allow": "Click to allow", "allow": "Klikni pre povolenie",
"updating": "Updating", "updating": "Prebieha aktualizácia",
"wait": "Please wait" "wait": "Počkajte prosím"
}, },
"search": { "search": {
"placeholder": "Search…" "placeholder": "Hľadať…"
}, },
"resources": { "resources": {
"cpu": "CPU", "cpu": "CPU",
"mem": "MEM", "mem": "RAM",
"total": "Total", "total": "Celkovo",
"free": "Free", "free": "Voľné",
"used": "Used", "used": "Využité",
"load": "Load", "load": "Záťaž",
"temp": "TEMP", "temp": "TEPLOTA",
"max": "Max", "max": "Max.",
"uptime": "UP", "uptime": "BEŽÍ",
"months": "mo", "months": "mes.",
"days": "d", "days": "d",
"hours": "h", "hours": "h",
"minutes": "m" "minutes": "m"
}, },
"unifi": { "unifi": {
"users": "Users", "users": "Používatelia",
"uptime": "System Uptime", "uptime": "Doba prevádzky",
"days": "Days", "days": "D",
"wan": "WAN", "wan": "WAN",
"lan": "LAN", "lan": "LAN",
"wlan": "WLAN", "wlan": "WLAN",
"devices": "Devices", "devices": "Zariadenia",
"lan_devices": "LAN Devices", "lan_devices": "Zariadenia LAN",
"wlan_devices": "WLAN Devices", "wlan_devices": "Zariadenia WLAN",
"lan_users": "LAN Users", "lan_users": "Používatelia LAN",
"wlan_users": "WLAN Users", "wlan_users": "Používatelia WLAN",
"up": "UP", "up": "BEŽÍ",
"down": "DOWN", "down": "NEBEŽÍ",
"wait": "Please wait", "wait": "Počkajte prosím",
"empty_data": "Subsystem status unknown" "empty_data": "Stav podsystému neznámy"
}, },
"ping": { "ping": {
"error": "Error", "error": "Chyba",
"ping": "Ping" "ping": "Odozva"
}, },
"emby": { "emby": {
"playing": "Playing", "playing": "Prehrávané",
"transcoding": "Transcoding", "transcoding": "Prekódovávané",
"bitrate": "Bitrate", "bitrate": "Prenosová rýchlosť",
"no_active": "No Active Streams", "no_active": "Žiadny aktívny stream",
"movies": "Movies", "movies": "Filmy",
"series": "Series", "series": "Seriály",
"episodes": "Episodes", "episodes": "Epizódy",
"songs": "Songs" "songs": "Skladby"
}, },
"flood": { "flood": {
"download": "Download", "download": "Sťahovanie",
"upload": "Upload", "upload": "Odosielanie",
"leech": "Leech", "leech": "Leechovanie",
"seed": "Seed" "seed": "Seedovanie"
}, },
"changedetectionio": { "changedetectionio": {
"totalObserved": "Total Observed", "totalObserved": "Total Observed",
@@ -276,70 +276,70 @@
"queued": "Queued", "queued": "Queued",
"series": "Series", "series": "Series",
"queue": "Queue", "queue": "Queue",
"unknown": "Unknown" "unknown": "Neznáme"
}, },
"radarr": { "radarr": {
"wanted": "Wanted", "wanted": "Chcené",
"missing": "Missing", "missing": "Chýbajúce",
"queued": "Queued", "queued": "Vo fronte",
"movies": "Movies", "movies": "Filmy",
"queue": "Queue", "queue": "Fronta",
"unknown": "Unknown" "unknown": "Neznáme"
}, },
"lidarr": { "lidarr": {
"wanted": "Wanted", "wanted": "Chcené",
"queued": "Queued", "queued": "Vo fronte",
"artists": "Artists" "artists": "Interpreti"
}, },
"readarr": { "readarr": {
"wanted": "Wanted", "wanted": "Chcené",
"queued": "Queued", "queued": "Vo fronte",
"books": "Books" "books": "Knihy"
}, },
"bazarr": { "bazarr": {
"missingEpisodes": "Missing Episodes", "missingEpisodes": "Chýbajúce epizódy",
"missingMovies": "Missing Movies" "missingMovies": "Chýbajúce filmy"
}, },
"ombi": { "ombi": {
"pending": "Pending", "pending": "Čakajúce",
"approved": "Approved", "approved": "Schválené",
"available": "Available" "available": "Dostupné"
}, },
"jellyseerr": { "jellyseerr": {
"pending": "Pending", "pending": "Čakajúce",
"approved": "Approved", "approved": "Schválené",
"available": "Available" "available": "Dostupné"
}, },
"overseerr": { "overseerr": {
"pending": "Pending", "pending": "Čakajúce",
"processing": "Processing", "processing": "Spracovávané",
"approved": "Approved", "approved": "Schválené",
"available": "Available" "available": "Dostupné"
}, },
"pihole": { "pihole": {
"queries": "Queries", "queries": "Dopyty",
"blocked": "Blocked", "blocked": "Zablokované",
"gravity": "Gravity", "gravity": "Gravitácia",
"blocked_percent": "Blocked %" "blocked_percent": "Blokované %"
}, },
"adguard": { "adguard": {
"queries": "Queries", "queries": "Dopyty",
"blocked": "Blocked", "blocked": "Blokované",
"filtered": "Filtered", "filtered": "Filtrované",
"latency": "Latency" "latency": "Odozva"
}, },
"speedtest": { "speedtest": {
"upload": "Upload", "upload": "Odosielanie",
"download": "Download", "download": "Sťahovanie",
"ping": "Ping" "ping": "Ping"
}, },
"portainer": { "portainer": {
"running": "Running", "running": "Spustené",
"stopped": "Stopped", "stopped": "Zastavené",
"total": "Total" "total": "Celkovo"
}, },
"traefik": { "traefik": {
"routers": "Routers", "routers": "Routery",
"services": "Services", "services": "Services",
"middleware": "Middleware" "middleware": "Middleware"
}, },
@@ -418,7 +418,8 @@
"write": "Write", "write": "Write",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Mem",
"swap": "Swap" "swap": "Swap",
"_temp": "Temp"
}, },
"quicklaunch": { "quicklaunch": {
"bookmark": "Bookmark", "bookmark": "Bookmark",
@@ -588,8 +589,8 @@
"switches_on": "Switches On" "switches_on": "Switches On"
}, },
"freshrss": { "freshrss": {
"subscriptions": "Subscriptions", "subscriptions": "Odbery",
"unread": "Unread" "unread": "Neprečítané"
}, },
"channelsdvrserver": { "channelsdvrserver": {
"shows": "Shows", "shows": "Shows",
@@ -602,18 +603,18 @@
"updates": "Updates" "updates": "Updates"
}, },
"tailscale": { "tailscale": {
"address": "Address", "address": "Adresa",
"years": "{{number}}y", "years": "{{number}}r",
"expires": "Expires", "expires": "Vyprší",
"never": "Never", "never": "Nikdy",
"last_seen": "Last Seen", "last_seen": "Naposledy videné",
"now": "Now", "now": "Teraz",
"weeks": "{{number}}w", "weeks": "{{number}}t",
"days": "{{number}}d", "days": "{{number}}d",
"hours": "{{number}}h", "hours": "{{number}}h",
"minutes": "{{number}}m", "minutes": "{{number}}m",
"seconds": "{{number}}s", "seconds": "{{number}}s",
"ago": "{{value}} Ago" "ago": "Pred {{value}}"
}, },
"qnap": { "qnap": {
"cpuUsage": "CPU Usage", "cpuUsage": "CPU Usage",
@@ -634,23 +635,23 @@
"wanIP": "WAN IP" "wanIP": "WAN IP"
}, },
"caddy": { "caddy": {
"upstreams": "Upstreams", "upstreams": "Odosielanie dát",
"requests": "Current requests", "requests": "Current requests",
"requests_failed": "Failed requests" "requests_failed": "Failed requests"
}, },
"evcc": { "evcc": {
"pv_power": "Production", "pv_power": "Produkcia",
"battery_soc": "Battery", "battery_soc": "Batéria",
"grid_power": "Grid", "grid_power": "Mriežka",
"home_power": "Consumption", "home_power": "Spotreba",
"charge_power": "Charger", "charge_power": "Nabíjačka",
"watt_hour": "Wh" "watt_hour": "Wh"
}, },
"pialert": { "pialert": {
"total": "Total", "total": "Celkovo",
"connected": "Connected", "connected": "Pripojené",
"new_devices": "New Devices", "new_devices": "Nové zariadenia",
"down_alerts": "Down Alerts" "down_alerts": "Upozornenia o výpadkoch"
}, },
"jdownloader": { "jdownloader": {
"downloadCount": "Queue Count", "downloadCount": "Queue Count",
@@ -718,5 +719,19 @@
"authors": "Authors", "authors": "Authors",
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@@ -169,7 +169,7 @@
"bitrate": "Pasovna širina", "bitrate": "Pasovna širina",
"playing": "Predvaja", "playing": "Predvaja",
"no_active": "Ni aktivne vsebine", "no_active": "Ni aktivne vsebine",
"plex_connection_error": "Check Plex Connection" "plex_connection_error": "Preveri Plex povezavo"
}, },
"flood": { "flood": {
"download": "Prenos", "download": "Prenos",
@@ -365,12 +365,13 @@
"warn": "Opoz.", "warn": "Opoz.",
"total": "Skupaj", "total": "Skupaj",
"used": "V uporabi", "used": "V uporabi",
"crit": "Crit", "crit": "Krit.",
"read": "Read", "read": "Prebrano",
"write": "Write", "write": "Zapisano",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Mem",
"swap": "Swap" "swap": "Swap",
"_temp": "Temp"
}, },
"authentik": { "authentik": {
"users": "Uporabniki", "users": "Uporabniki",
@@ -663,60 +664,74 @@
"totalFiles": "Datoteke" "totalFiles": "Datoteke"
}, },
"gamedig": { "gamedig": {
"name": "Name", "name": "Naziv",
"map": "Map", "map": "Zemljevid",
"currentPlayers": "Current players", "currentPlayers": "Igralcev",
"players": "Players", "players": "Igralci",
"maxPlayers": "Max players", "maxPlayers": "Maks igralcev",
"bots": "Bots", "bots": "Boti",
"ping": "Ping", "ping": "Ping",
"status": "Status", "status": "Status",
"online": "Online", "online": "Na spletu",
"offline": "Offline" "offline": "Nepovezano"
}, },
"azuredevops": { "azuredevops": {
"result": "Result", "result": "Rezultati",
"status": "Status", "status": "Status",
"buildId": "Build ID", "buildId": "ID gradnje",
"succeeded": "Succeeded", "succeeded": "Uspešnih",
"notStarted": "Not Started", "notStarted": "Ni zagnano",
"failed": "Failed", "failed": "Neuspešno",
"canceled": "Canceled", "canceled": "Preklicano",
"inProgress": "In Progress", "inProgress": "V delu",
"totalPrs": "Total PRs", "totalPrs": "Skupaj PR",
"myPrs": "My PRs", "myPrs": "Moji PR",
"approved": "Approved" "approved": "Odobreno"
}, },
"urbackup": { "urbackup": {
"ok": "Ok", "ok": "V redu",
"errored": "Errors", "errored": "Napake",
"noRecent": "Out of Date", "noRecent": "Zastarano",
"totalUsed": "Used Storage" "totalUsed": "Shramba v uporabi"
}, },
"openmediavault": { "openmediavault": {
"downloading": "Downloading", "downloading": "Prenašanje",
"total": "Total", "total": "Skupaj",
"running": "Running", "running": "V teku",
"stopped": "Stopped", "stopped": "Ustavljeno",
"passed": "Passed", "passed": "Opravljeno",
"failed": "Failed" "failed": "Neuspešno"
}, },
"mealie": { "mealie": {
"recipes": "Recipes", "recipes": "Recepti",
"users": "Users", "users": "Uporabniki",
"categories": "Categories", "categories": "Kategorije",
"tags": "Tags" "tags": "Značke"
}, },
"atsumeru": { "atsumeru": {
"series": "Series", "series": "Serije",
"archives": "Archives", "archives": "Arhivi",
"chapters": "Chapters", "chapters": "Poglavja",
"categories": "Categories" "categories": "Kategorije"
}, },
"calibreweb": { "calibreweb": {
"books": "Books", "books": "Knjige",
"authors": "Authors", "authors": "Avtorji",
"categories": "Categories", "categories": "Kategorije",
"series": "Series" "series": "Serije"
},
"uptimerobot": {
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"unknown": "Unknown",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"seemsdown": "Seems Down",
"down": "Down"
} }
} }

View File

@@ -254,7 +254,8 @@
"write": "Write", "write": "Write",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Mem",
"swap": "Swap" "swap": "Swap",
"_temp": "Temp"
}, },
"changedetectionio": { "changedetectionio": {
"totalObserved": "Total Observed", "totalObserved": "Total Observed",
@@ -718,5 +719,19 @@
"authors": "Authors", "authors": "Authors",
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@@ -254,7 +254,8 @@
"write": "Write", "write": "Write",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Mem",
"swap": "Swap" "swap": "Swap",
"_temp": "Temp"
}, },
"changedetectionio": { "changedetectionio": {
"totalObserved": "Total Observed", "totalObserved": "Total Observed",
@@ -718,5 +719,19 @@
"authors": "Authors", "authors": "Authors",
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"paused": "Paused",
"sitesDown": "Sites Down",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@@ -254,7 +254,8 @@
"write": "Write", "write": "Write",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Mem",
"swap": "Swap" "swap": "Swap",
"_temp": "Temp"
}, },
"changedetectionio": { "changedetectionio": {
"totalObserved": "మొత్తం గమనించబడింది", "totalObserved": "మొత్తం గమనించబడింది",
@@ -718,5 +719,19 @@
"authors": "Authors", "authors": "Authors",
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@@ -330,7 +330,8 @@
"write": "Write", "write": "Write",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Mem",
"swap": "Swap" "swap": "Swap",
"_temp": "Temp"
}, },
"quicklaunch": { "quicklaunch": {
"bookmark": "Bookmark", "bookmark": "Bookmark",
@@ -718,5 +719,19 @@
"authors": "Authors", "authors": "Authors",
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@@ -254,7 +254,8 @@
"write": "Write", "write": "Write",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Mem",
"swap": "Swap" "swap": "Swap",
"_temp": "Temp"
}, },
"changedetectionio": { "changedetectionio": {
"totalObserved": "Toplam Gözlenen", "totalObserved": "Toplam Gözlenen",
@@ -718,5 +719,19 @@
"authors": "Authors", "authors": "Authors",
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@@ -378,7 +378,8 @@
"write": "Написати", "write": "Написати",
"gpu": "GPU", "gpu": "GPU",
"mem": "Пам'ять", "mem": "Пам'ять",
"swap": "Обмін" "swap": "Обмін",
"_temp": "Temp"
}, },
"quicklaunch": { "quicklaunch": {
"bookmark": "Закладка", "bookmark": "Закладка",
@@ -718,5 +719,19 @@
"authors": "Authors", "authors": "Authors",
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@@ -254,7 +254,8 @@
"write": "Write", "write": "Write",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Mem",
"swap": "Swap" "swap": "Swap",
"_temp": "Temp"
}, },
"changedetectionio": { "changedetectionio": {
"totalObserved": "Total Observed", "totalObserved": "Total Observed",
@@ -718,5 +719,19 @@
"authors": "Authors", "authors": "Authors",
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
},
"uptimerobot": {
"up": "Up",
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@@ -254,7 +254,8 @@
"write": "Write", "write": "Write",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Mem",
"swap": "Swap" "swap": "Swap",
"_temp": "Temp"
}, },
"changedetectionio": { "changedetectionio": {
"totalObserved": "Total Observed", "totalObserved": "Total Observed",
@@ -718,5 +719,19 @@
"authors": "Authors", "authors": "Authors",
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@@ -254,7 +254,8 @@
"write": "Write", "write": "Write",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mem", "mem": "Mem",
"swap": "Swap" "swap": "Swap",
"_temp": "Temp"
}, },
"changedetectionio": { "changedetectionio": {
"totalObserved": "观察到的总数", "totalObserved": "观察到的总数",
@@ -659,8 +660,8 @@
"downloadTotalBytes": "Size" "downloadTotalBytes": "Size"
}, },
"kavita": { "kavita": {
"seriesCount": "Series", "seriesCount": "系列",
"totalFiles": "Files" "totalFiles": "文件"
}, },
"gamedig": { "gamedig": {
"name": "Name", "name": "Name",
@@ -714,9 +715,23 @@
"categories": "Categories" "categories": "Categories"
}, },
"calibreweb": { "calibreweb": {
"books": "Books", "books": "书籍",
"authors": "Authors", "authors": "作者",
"categories": "Categories", "categories": "分类",
"series": "Series" "series": "丛书"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@@ -254,7 +254,8 @@
"write": "寫入", "write": "寫入",
"gpu": "GPU", "gpu": "GPU",
"mem": "記憶體", "mem": "記憶體",
"swap": "Swap" "swap": "Swap",
"_temp": "Temp"
}, },
"changedetectionio": { "changedetectionio": {
"totalObserved": "總監測數", "totalObserved": "總監測數",
@@ -718,5 +719,19 @@
"authors": "Authors", "authors": "Authors",
"categories": "Categories", "categories": "Categories",
"series": "Series" "series": "Series"
},
"uptimerobot": {
"status": "Status",
"uptime": "Uptime",
"lastDown": "Last Downtime",
"downDuration": "Downtime Duration",
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
} }
} }

View File

@@ -5,44 +5,65 @@ import { MdKeyboardArrowDown } from "react-icons/md";
import ErrorBoundary from "components/errorboundry"; import ErrorBoundary from "components/errorboundry";
import List from "components/bookmarks/list"; import List from "components/bookmarks/list";
import ResolvedIcon from "components/resolvedicon";
export default function BookmarksGroup({ group, disableCollapse }) { export default function BookmarksGroup({ bookmarks, layout, disableCollapse }) {
const panel = useRef(); const panel = useRef();
return ( return (
<div key={group.name} className="flex-1"> <div
<Disclosure defaultOpen> key={bookmarks.name}
{({ open }) => ( className={classNames(
<> "bookmark-group",
<Disclosure.Button disabled={disableCollapse} className="flex w-full select-none items-center group"> layout?.style === "row" ? "basis-full" : "basis-full md:basis-1/4 lg:basis-1/5 xl:basis-1/6",
<h2 className="text-theme-800 dark:text-theme-300 text-xl font-medium">{group.name}</h2> layout?.header === false ? "flex-1 px-1 -my-1" : "flex-1 p-1"
<MdKeyboardArrowDown className={classNames( )}
disableCollapse ? 'hidden' : '', >
'transition-all opacity-0 group-hover:opacity-100 ml-auto text-theme-800 dark:text-theme-300 text-xl', <Disclosure defaultOpen>
open ? '' : 'rotate-90' {({ open }) => (
)} /> <>
</Disclosure.Button> {layout?.header !== false && (
<Transition <Disclosure.Button disabled={disableCollapse} className="flex w-full select-none items-center group">
// Otherwise the transition group does display: none and cancels animation {layout?.icon && (
className="!block" <div className="flex-shrink-0 mr-2 w-7 h-7 bookmark-group-icon">
unmount={false} <ResolvedIcon icon={layout.icon} />
beforeLeave={() => { </div>
panel.current.style.height = `${panel.current.scrollHeight}px`; )}
setTimeout(() => {panel.current.style.height = `0`}, 1); <h2 className="text-theme-800 dark:text-theme-300 text-xl font-medium bookmark-group-name">{bookmarks.name}</h2>
}} <MdKeyboardArrowDown
beforeEnter={() => { className={classNames(
panel.current.style.height = `0px`; disableCollapse ? "hidden" : "",
setTimeout(() => {panel.current.style.height = `${panel.current.scrollHeight}px`}, 1); "transition-all opacity-0 group-hover:opacity-100 ml-auto text-theme-800 dark:text-theme-300 text-xl",
}} open ? "" : "rotate-180"
> )}
<Disclosure.Panel className="transition-all overflow-hidden duration-300 ease-out" ref={panel} static> />
<ErrorBoundary> </Disclosure.Button>
<List bookmarks={group.bookmarks} /> )}
</ErrorBoundary> <Transition
</Disclosure.Panel> // Otherwise the transition group does display: none and cancels animation
</Transition> className="!block"
</> unmount={false}
)} beforeLeave={() => {
</Disclosure> panel.current.style.height = `${panel.current.scrollHeight}px`;
setTimeout(() => {
panel.current.style.height = `0`;
}, 1);
}}
beforeEnter={() => {
panel.current.style.height = `0px`;
setTimeout(() => {
panel.current.style.height = `${panel.current.scrollHeight}px`;
}, 1);
}}
>
<Disclosure.Panel className="transition-all overflow-hidden duration-300 ease-out" ref={panel} static>
<ErrorBoundary>
<List bookmarks={bookmarks.bookmarks} layout={layout} />
</ErrorBoundary>
</Disclosure.Panel>
</Transition>
</>
)}
</Disclosure>
</div> </div>
); );
} }

View File

@@ -9,18 +9,18 @@ export default function Item({ bookmark }) {
const { settings } = useContext(SettingsContext); const { settings } = useContext(SettingsContext);
return ( return (
<li key={bookmark.name}> <li key={bookmark.name} id={bookmark.id} className="bookmark" data-name={bookmark.name}>
<a <a
href={bookmark.href} href={bookmark.href}
title={bookmark.name} title={bookmark.name}
target={bookmark.target ?? settings.target ?? "_blank"} target={bookmark.target ?? settings.target ?? "_blank"}
className="block w-full text-left cursor-pointer transition-all h-15 mb-3 rounded-md font-medium text-theme-700 dark:text-theme-200 dark:hover:text-theme-300 shadow-md shadow-theme-900/10 dark:shadow-theme-900/20 bg-theme-100/20 hover:bg-theme-300/20 dark:bg-white/5 dark:hover:bg-white/10" className={classNames(
settings.cardBlur !== undefined && `backdrop-blur${settings.cardBlur.length ? '-' : ""}${settings.cardBlur}`,
"block w-full text-left cursor-pointer transition-all h-15 mb-3 rounded-md font-medium text-theme-700 dark:text-theme-200 dark:hover:text-theme-300 shadow-md shadow-theme-900/10 dark:shadow-theme-900/20 bg-theme-100/20 hover:bg-theme-300/20 dark:bg-white/5 dark:hover:bg-white/10"
)}
> >
<div className="flex"> <div className="flex">
<div className={classNames( <div className="flex-shrink-0 flex items-center justify-center w-11 bg-theme-500/10 dark:bg-theme-900/50 text-theme-700 hover:text-theme-700 dark:text-theme-200 text-sm font-medium rounded-l-md bookmark-icon">
settings.cardBlur !== undefined && `backdrop-blur${settings.cardBlur.length ? '-' : ""}${settings.cardBlur}`,
"flex-shrink-0 flex items-center justify-center w-11 bg-theme-500/10 dark:bg-theme-900/50 text-theme-700 hover:text-theme-700 dark:text-theme-200 text-sm font-medium rounded-l-md"
)}>
{bookmark.icon && {bookmark.icon &&
<div className="flex-shrink-0 w-5 h-5"> <div className="flex-shrink-0 w-5 h-5">
<ResolvedIcon icon={bookmark.icon} alt={bookmark.abbr} /> <ResolvedIcon icon={bookmark.icon} alt={bookmark.abbr} />
@@ -28,12 +28,9 @@ export default function Item({ bookmark }) {
} }
{!bookmark.icon && bookmark.abbr} {!bookmark.icon && bookmark.abbr}
</div> </div>
<div className={classNames( <div className="flex-1 flex items-center justify-between rounded-r-md bookmark-text">
settings.cardBlur !== undefined && `backdrop-blur${settings.cardBlur.length ? '-' : ""}${settings.cardBlur}`, <div className="flex-1 grow pl-3 py-2 text-xs bookmark-name">{bookmark.name}</div>
"flex-1 flex items-center justify-between rounded-r-md" <div className="px-2 py-2 truncate text-theme-500 dark:text-theme-300 text-xs bookmark-hostname">{hostname}</div>
)}>
<div className="flex-1 grow pl-3 py-2 text-xs">{bookmark.name}</div>
<div className="px-2 py-2 truncate text-theme-500 dark:text-theme-300 text-xs">{hostname}</div>
</div> </div>
</div> </div>
</a> </a>

View File

@@ -1,8 +1,17 @@
import classNames from "classnames";
import { columnMap } from "../../utils/layout/columns";
import Item from "components/bookmarks/item"; import Item from "components/bookmarks/item";
export default function List({ bookmarks }) { export default function List({ bookmarks, layout }) {
return ( return (
<ul className="mt-3 flex flex-col"> <ul
className={classNames(
layout?.style === "row" ? `grid ${columnMap[layout?.columns]} gap-x-2` : "flex flex-col",
"mt-3 bookmark-list"
)}
>
{bookmarks.map((bookmark) => ( {bookmarks.map((bookmark) => (
<Item key={`${bookmark.name}-${bookmark.href}`} bookmark={bookmark} /> <Item key={`${bookmark.name}-${bookmark.href}`} bookmark={bookmark} />
))} ))}

View File

@@ -0,0 +1,10 @@
import useSWR from "swr"
export default function FileContent({ path, loadingValue, errorValue, emptyValue = '' }) {
const fetcher = (url) => fetch(url).then((res) => res.text())
const { data, error, isLoading } = useSWR(`/api/config/${ path }`, fetcher)
if (error) return (errorValue)
if (isLoading) return (loadingValue)
return (data || emptyValue)
}

View File

@@ -61,7 +61,6 @@ export default function QuickLaunch({servicesAndBookmarks, searchString, setSear
} }
} }
function handleItemHover(event) { function handleItemHover(event) {
setCurrentItemIndex(parseInt(event.target?.dataset?.index, 10)); setCurrentItemIndex(parseInt(event.target?.dataset?.index, 10));
} }
@@ -71,6 +70,16 @@ export default function QuickLaunch({servicesAndBookmarks, searchString, setSear
openCurrentItem(event.metaKey); openCurrentItem(event.metaKey);
} }
function handleItemKeyDown(event) {
if (!isOpen) return;
// native button handles other keys
if (event.key === "Escape") {
closeAndReset();
event.preventDefault();
}
}
useEffect(() => { useEffect(() => {
if (searchString.length === 0) setResults([]); if (searchString.length === 0) setResults([]);
else { else {
@@ -162,10 +171,10 @@ export default function QuickLaunch({servicesAndBookmarks, searchString, setSear
{results.length > 0 && <ul className="max-h-[60vh] overflow-y-auto m-2"> {results.length > 0 && <ul className="max-h-[60vh] overflow-y-auto m-2">
{results.map((r, i) => ( {results.map((r, i) => (
<li key={r.container ?? r.app ?? `${r.name}-${r.href}`}> <li key={r.container ?? r.app ?? `${r.name}-${r.href}`}>
<button type="button" data-index={i} onMouseEnter={handleItemHover} className={classNames( <button type="button" data-index={i} onMouseEnter={handleItemHover} onClick={handleItemClick} onKeyDown={handleItemKeyDown} className={classNames(
"flex flex-row w-full items-center justify-between rounded-md text-sm md:text-xl py-2 px-4 cursor-pointer text-theme-700 dark:text-theme-200", "flex flex-row w-full items-center justify-between rounded-md text-sm md:text-xl py-2 px-4 cursor-pointer text-theme-700 dark:text-theme-200",
i === currentItemIndex && "bg-theme-300/50 dark:bg-theme-700/50", i === currentItemIndex && "bg-theme-300/50 dark:bg-theme-700/50",
)} onClick={handleItemClick}> )}>
<div className="flex flex-row items-center mr-4 pointer-events-none"> <div className="flex flex-row items-center mr-4 pointer-events-none">
{(r.icon || r.abbr) && <div className="w-5 text-xs mr-4"> {(r.icon || r.abbr) && <div className="w-5 text-xs mr-4">
{r.icon && <ResolvedIcon icon={r.icon} />} {r.icon && <ResolvedIcon icon={r.icon} />}

View File

@@ -14,6 +14,7 @@ export default function ServicesGroup({ group, services, layout, fiveColumns, di
<div <div
key={services.name} key={services.name}
className={classNames( className={classNames(
"services-group",
layout?.style === "row" ? "basis-full" : "basis-full md:basis-1/2 lg:basis-1/3 xl:basis-1/4", layout?.style === "row" ? "basis-full" : "basis-full md:basis-1/2 lg:basis-1/3 xl:basis-1/4",
layout?.style !== "row" && fiveColumns ? "3xl:basis-1/5" : "", layout?.style !== "row" && fiveColumns ? "3xl:basis-1/5" : "",
layout?.header === false ? "flex-1 px-1 -my-1" : "flex-1 p-1", layout?.header === false ? "flex-1 px-1 -my-1" : "flex-1 p-1",
@@ -25,15 +26,15 @@ export default function ServicesGroup({ group, services, layout, fiveColumns, di
{ layout?.header !== false && { layout?.header !== false &&
<Disclosure.Button disabled={disableCollapse} className="flex w-full select-none items-center group"> <Disclosure.Button disabled={disableCollapse} className="flex w-full select-none items-center group">
{layout?.icon && {layout?.icon &&
<div className="flex-shrink-0 mr-2 w-7 h-7"> <div className="flex-shrink-0 mr-2 w-7 h-7 service-group-icon">
<ResolvedIcon icon={layout.icon} /> <ResolvedIcon icon={layout.icon} />
</div> </div>
} }
<h2 className="flex text-theme-800 dark:text-theme-300 text-xl font-medium">{services.name}</h2> <h2 className="flex text-theme-800 dark:text-theme-300 text-xl font-medium service-group-name">{services.name}</h2>
<MdKeyboardArrowDown className={classNames( <MdKeyboardArrowDown className={classNames(
disableCollapse ? 'hidden' : '', disableCollapse ? 'hidden' : '',
'transition-all opacity-0 group-hover:opacity-100 ml-auto text-theme-800 dark:text-theme-300 text-xl', 'transition-all opacity-0 group-hover:opacity-100 ml-auto text-theme-800 dark:text-theme-300 text-xl',
open ? '' : 'rotate-90' open ? '' : 'rotate-180'
)} /> )} />
</Disclosure.Button> </Disclosure.Button>
} }

View File

@@ -29,28 +29,30 @@ export default function Item({ service, group }) {
} }
}; };
return ( return (
<li key={service.name}> <li key={service.name} id={service.id} className="service" data-name={service.name || ""}>
<div <div
className={classNames( className={classNames(
settings.cardBlur !== undefined && `backdrop-blur${settings.cardBlur.length ? '-' : ""}${settings.cardBlur}`, settings.cardBlur !== undefined && `backdrop-blur${settings.cardBlur.length ? '-' : ""}${settings.cardBlur}`,
hasLink && "cursor-pointer", hasLink && "cursor-pointer",
'transition-all h-15 mb-2 p-1 rounded-md font-medium text-theme-700 dark:text-theme-200 dark:hover:text-theme-300 shadow-md shadow-theme-900/10 dark:shadow-theme-900/20 bg-theme-100/20 hover:bg-theme-300/20 dark:bg-white/5 dark:hover:bg-white/10 relative overflow-clip' "transition-all h-15 mb-2 p-1 rounded-md font-medium text-theme-700 dark:text-theme-200 dark:hover:text-theme-300 shadow-md shadow-theme-900/10 dark:shadow-theme-900/20 bg-theme-100/20 hover:bg-theme-300/20 dark:bg-white/5 dark:hover:bg-white/10 relative overflow-clip service-card"
)} )}
> >
<div className="flex select-none z-0"> <div className="flex select-none z-0 service-title">
{service.icon && {service.icon &&
(hasLink ? ( (hasLink ? (
<a <a
href={service.href} href={service.href}
target={service.target ?? settings.target ?? "_blank"} target={service.target ?? settings.target ?? "_blank"}
rel="noreferrer" rel="noreferrer"
className="flex-shrink-0 flex items-center justify-center w-12 " className="flex-shrink-0 flex items-center justify-center w-12 service-icon"
> >
<ResolvedIcon icon={service.icon} /> <ResolvedIcon icon={service.icon} />
</a> </a>
) : ( ) : (
<div className="flex-shrink-0 flex items-center justify-center w-12 "> <div className="flex-shrink-0 flex items-center justify-center w-12 service-icon">
<ResolvedIcon icon={service.icon} /> <ResolvedIcon icon={service.icon} />
</div> </div>
))} ))}
@@ -60,25 +62,25 @@ export default function Item({ service, group }) {
href={service.href} href={service.href}
target={service.target ?? settings.target ?? "_blank"} target={service.target ?? settings.target ?? "_blank"}
rel="noreferrer" rel="noreferrer"
className="flex-1 flex items-center justify-between rounded-r-md " className="flex-1 flex items-center justify-between rounded-r-md service-title-text"
> >
<div className="flex-1 px-2 py-2 text-sm text-left z-10"> <div className="flex-1 px-2 py-2 text-sm text-left z-10 service-name">
{service.name} {service.name}
<p className="text-theme-500 dark:text-theme-300 text-xs font-light">{service.description}</p> <p className="text-theme-500 dark:text-theme-300 text-xs font-light service-description">{service.description}</p>
</div> </div>
</a> </a>
) : ( ) : (
<div className="flex-1 flex items-center justify-between rounded-r-md "> <div className="flex-1 flex items-center justify-between rounded-r-md service-title-text">
<div className="flex-1 px-2 py-2 text-sm text-left z-10"> <div className="flex-1 px-2 py-2 text-sm text-left z-10 service-name">
{service.name} {service.name}
<p className="text-theme-500 dark:text-theme-300 text-xs font-light">{service.description}</p> <p className="text-theme-500 dark:text-theme-300 text-xs font-light service-description">{service.description}</p>
</div> </div>
</div> </div>
)} )}
<div className="absolute top-0 right-0 w-1/2 flex flex-row justify-end gap-2 mr-2 z-30"> <div className="absolute top-0 right-0 flex flex-row justify-end gap-2 mr-2 z-30 service-tags">
{service.ping && ( {service.ping && (
<div className="flex-shrink-0 flex items-center justify-center cursor-pointer"> <div className="flex-shrink-0 flex items-center justify-center service-tag service-ping">
<Ping group={group} service={service.name} /> <Ping group={group} service={service.name} />
<span className="sr-only">Ping status</span> <span className="sr-only">Ping status</span>
</div> </div>
@@ -88,7 +90,7 @@ export default function Item({ service, group }) {
<button <button
type="button" type="button"
onClick={() => (statsOpen ? closeStats() : setStatsOpen(true))} onClick={() => (statsOpen ? closeStats() : setStatsOpen(true))}
className="flex-shrink-0 flex items-center justify-center cursor-pointer" className="flex-shrink-0 flex items-center justify-center cursor-pointer service-tag service-container-stats"
> >
<Status service={service} /> <Status service={service} />
<span className="sr-only">View container stats</span> <span className="sr-only">View container stats</span>
@@ -98,7 +100,7 @@ export default function Item({ service, group }) {
<button <button
type="button" type="button"
onClick={() => (statsOpen ? closeStats() : setStatsOpen(true))} onClick={() => (statsOpen ? closeStats() : setStatsOpen(true))}
className="flex-shrink-0 flex items-center justify-center cursor-pointer" className="flex-shrink-0 flex items-center justify-center cursor-pointer service-tag service-app"
> >
<KubernetesStatus service={service} /> <KubernetesStatus service={service} />
<span className="sr-only">View container stats</span> <span className="sr-only">View container stats</span>
@@ -111,7 +113,7 @@ export default function Item({ service, group }) {
<div <div
className={classNames( className={classNames(
showStats || (statsOpen && !statsClosing) ? "max-h-[110px] opacity-100" : " max-h-[0] opacity-0", showStats || (statsOpen && !statsClosing) ? "max-h-[110px] opacity-100" : " max-h-[0] opacity-0",
"w-full overflow-hidden transition-all duration-300 ease-in-out" "w-full overflow-hidden transition-all duration-300 ease-in-out service-stats"
)} )}
> >
{(showStats || statsOpen) && <Docker service={{ widget: { container: service.container, server: service.server } }} />} {(showStats || statsOpen) && <Docker service={{ widget: { container: service.container, server: service.server } }} />}
@@ -121,7 +123,7 @@ export default function Item({ service, group }) {
<div <div
className={classNames( className={classNames(
showStats || (statsOpen && !statsClosing) ? "max-h-[55px] opacity-100" : " max-h-[0] opacity-0", showStats || (statsOpen && !statsClosing) ? "max-h-[55px] opacity-100" : " max-h-[0] opacity-0",
"w-full overflow-hidden transition-all duration-300 ease-in-out" "w-full overflow-hidden transition-all duration-300 ease-in-out service-stats"
)} )}
> >
{(showStats || statsOpen) && <Kubernetes service={{ widget: { namespace: service.namespace, app: service.app, podSelector: service.podSelector } }} />} {(showStats || statsOpen) && <Kubernetes service={{ widget: { namespace: service.namespace, app: service.app, podSelector: service.podSelector } }} />}

View File

@@ -6,14 +6,14 @@ export default function KubernetesStatus({ service }) {
const { data, error } = useSWR(`/api/kubernetes/status/${service.namespace}/${service.app}?${podSelectorString}`); const { data, error } = useSWR(`/api/kubernetes/status/${service.namespace}/${service.app}?${podSelectorString}`);
if (error) { if (error) {
<div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden" title={t("docker.error")}> <div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden k8s-status-error" title={t("docker.error")}>
<div className="text-[8px] font-bold text-rose-500/80 uppercase">{t("docker.error")}</div> <div className="text-[8px] font-bold text-rose-500/80 uppercase">{t("docker.error")}</div>
</div> </div>
} }
if (data && data.status === "running") { if (data && data.status === "running") {
return ( return (
<div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden" title={data.health ?? data.status}> <div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden k8s-status" title={data.health ?? data.status}>
<div className="text-[8px] font-bold text-emerald-500/80 uppercase">{data.health ?? data.status}</div> <div className="text-[8px] font-bold text-emerald-500/80 uppercase">{data.health ?? data.status}</div>
</div> </div>
); );
@@ -21,14 +21,14 @@ export default function KubernetesStatus({ service }) {
if (data && (data.status === "not found" || data.status === "down" || data.status === "partial")) { if (data && (data.status === "not found" || data.status === "down" || data.status === "partial")) {
return ( return (
<div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden" title={data.status}> <div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden k8s-status-warning" title={data.status}>
<div className="text-[8px] font-bold text-orange-400/50 dark:text-orange-400/80 uppercase">{data.status}</div> <div className="text-[8px] font-bold text-orange-400/50 dark:text-orange-400/80 uppercase">{data.status}</div>
</div> </div>
); );
} }
return ( return (
<div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden"> <div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden k8s-status-unknown">
<div className="text-[8px] font-bold text-black/20 dark:text-white/40 uppercase">{t("docker.unknown")}</div> <div className="text-[8px] font-bold text-black/20 dark:text-white/40 uppercase">{t("docker.unknown")}</div>
</div> </div>
); );

View File

@@ -1,25 +1,15 @@
import classNames from "classnames"; import classNames from "classnames";
import Item from "components/services/item"; import { columnMap } from "../../utils/layout/columns";
const columnMap = [ import Item from "components/services/item";
"grid-cols-1 md:grid-cols-1 lg:grid-cols-1",
"grid-cols-1 md:grid-cols-1 lg:grid-cols-1",
"grid-cols-1 md:grid-cols-2 lg:grid-cols-2",
"grid-cols-1 md:grid-cols-2 lg:grid-cols-3",
"grid-cols-1 md:grid-cols-2 lg:grid-cols-4",
"grid-cols-1 md:grid-cols-2 lg:grid-cols-5",
"grid-cols-1 md:grid-cols-2 lg:grid-cols-6",
"grid-cols-1 md:grid-cols-2 lg:grid-cols-7",
"grid-cols-1 md:grid-cols-2 lg:grid-cols-8",
];
export default function List({ group, services, layout }) { export default function List({ group, services, layout }) {
return ( return (
<ul <ul
className={classNames( className={classNames(
layout?.style === "row" ? `grid ${columnMap[layout?.columns]} gap-x-2` : "flex flex-col", layout?.style === "row" ? `grid ${columnMap[layout?.columns]} gap-x-2` : "flex flex-col",
"mt-3" "mt-3 services-list"
)} )}
> >
{services.map((service) => ( {services.map((service) => (

View File

@@ -9,7 +9,7 @@ export default function Ping({ group, service }) {
if (error) { if (error) {
return ( return (
<div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden"> <div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden ping-error">
<div className="text-[8px] font-bold text-rose-500 uppercase">{t("ping.error")}</div> <div className="text-[8px] font-bold text-rose-500 uppercase">{t("ping.error")}</div>
</div> </div>
); );
@@ -17,7 +17,7 @@ export default function Ping({ group, service }) {
if (!data) { if (!data) {
return ( return (
<div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden"> <div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden ping-ping">
<div className="text-[8px] font-bold text-black/20 dark:text-white/40 uppercase">{t("ping.ping")}</div> <div className="text-[8px] font-bold text-black/20 dark:text-white/40 uppercase">{t("ping.ping")}</div>
</div> </div>
); );
@@ -27,14 +27,14 @@ export default function Ping({ group, service }) {
if (data.status > 403) { if (data.status > 403) {
return ( return (
<div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden" title={statusText}> <div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden ping-status-invalid" title={statusText}>
<div className="text-[8px] font-bold text-rose-500/80">{data.status}</div> <div className="text-[8px] font-bold text-rose-500/80">{data.status}</div>
</div> </div>
); );
} }
return ( return (
<div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden" title={statusText}> <div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden ping-status-valid" title={statusText}>
<div className="text-[8px] font-bold text-emerald-500/80">{t("common.ms", { value: data.latency, style: "unit", unit: "millisecond", maximumFractionDigits: 0 })}</div> <div className="text-[8px] font-bold text-emerald-500/80">{t("common.ms", { value: data.latency, style: "unit", unit: "millisecond", maximumFractionDigits: 0 })}</div>
</div> </div>
); );

View File

@@ -7,7 +7,7 @@ export default function Status({ service }) {
const { data, error } = useSWR(`/api/docker/status/${service.container}/${service.server || ""}`); const { data, error } = useSWR(`/api/docker/status/${service.container}/${service.server || ""}`);
if (error) { if (error) {
<div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden" title={t("docker.error")}> <div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden docker-error" title={t("docker.error")}>
<div className="text-[8px] font-bold text-rose-500/80 uppercase">{t("docker.error")}</div> <div className="text-[8px] font-bold text-rose-500/80 uppercase">{t("docker.error")}</div>
</div> </div>
} }
@@ -18,7 +18,7 @@ export default function Status({ service }) {
if (data.status?.includes("running")) { if (data.status?.includes("running")) {
if (data.health === "starting") { if (data.health === "starting") {
return ( return (
<div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden" title={t("docker.starting")}> <div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden docker-starting" title={t("docker.starting")}>
<div className="text-[8px] font-bold text-blue-500/80 uppercase">{t("docker.starting")}</div> <div className="text-[8px] font-bold text-blue-500/80 uppercase">{t("docker.starting")}</div>
</div> </div>
); );
@@ -26,7 +26,7 @@ export default function Status({ service }) {
if (data.health === "unhealthy") { if (data.health === "unhealthy") {
return ( return (
<div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden" title={t("docker.unhealthy")}> <div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden docker-unhealthy" title={t("docker.unhealthy")}>
<div className="text-[8px] font-bold text-orange-400/50 dark:text-orange-400/80 uppercase">{t("docker.unhealthy")}</div> <div className="text-[8px] font-bold text-orange-400/50 dark:text-orange-400/80 uppercase">{t("docker.unhealthy")}</div>
</div> </div>
); );
@@ -39,7 +39,7 @@ export default function Status({ service }) {
} }
return ( return (
<div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden" title={statusLabel}> <div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden docker-status" title={statusLabel}>
<div className="text-[8px] font-bold text-emerald-500/80 uppercase">{statusLabel}</div> <div className="text-[8px] font-bold text-emerald-500/80 uppercase">{statusLabel}</div>
</div> </div>
); );
@@ -50,7 +50,7 @@ export default function Status({ service }) {
else if (data.status === "exited") statusLabel = t("docker.exited") else if (data.status === "exited") statusLabel = t("docker.exited")
else statusLabel = data.status.replace("partial", t("docker.partial")) else statusLabel = data.status.replace("partial", t("docker.partial"))
return ( return (
<div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden" title={statusLabel}> <div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden docker-status-warning" title={statusLabel}>
<div className="text-[8px] font-bold text-orange-400/50 dark:text-orange-400/80 uppercase">{statusLabel}</div> <div className="text-[8px] font-bold text-orange-400/50 dark:text-orange-400/80 uppercase">{statusLabel}</div>
</div> </div>
); );
@@ -58,7 +58,7 @@ export default function Status({ service }) {
} }
return ( return (
<div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden"> <div className="w-auto px-1.5 py-0.5 text-center bg-theme-500/10 dark:bg-theme-900/50 rounded-b-[3px] overflow-hidden docker-status-unknown">
<div className="text-[8px] font-bold text-black/20 dark:text-white/40 uppercase">{t("docker.unknown")}</div> <div className="text-[8px] font-bold text-black/20 dark:text-white/40 uppercase">{t("docker.unknown")}</div>
</div> </div>
); );

View File

@@ -17,7 +17,7 @@ export default function Widget({ service }) {
} }
return ( return (
<div className="bg-theme-200/50 dark:bg-theme-900/20 rounded m-1 flex-1 flex flex-col items-center justify-center p-1"> <div className="bg-theme-200/50 dark:bg-theme-900/20 rounded m-1 flex-1 flex flex-col items-center justify-center p-1 service-missing">
<div className="font-thin text-sm">{t("widget.missing_type", { type: service.widget.type })}</div> <div className="font-thin text-sm">{t("widget.missing_type", { type: service.widget.type })}</div>
</div> </div>
); );

View File

@@ -8,7 +8,8 @@ export default function Block({ value, label }) {
<div <div
className={classNames( className={classNames(
"bg-theme-200/50 dark:bg-theme-900/20 rounded m-1 flex-1 flex flex-col items-center justify-center text-center p-1", "bg-theme-200/50 dark:bg-theme-900/20 rounded m-1 flex-1 flex flex-col items-center justify-center text-center p-1",
value === undefined ? "animate-pulse" : "" value === undefined ? "animate-pulse" : "",
"service-block"
)} )}
> >
<div className="font-thin text-sm">{value === undefined || value === null ? "-" : value}</div> <div className="font-thin text-sm">{value === undefined || value === null ? "-" : value}</div>

View File

@@ -36,5 +36,5 @@ export default function Container({ error = false, children, service }) {
})); }));
} }
return <div className="relative flex flex-row w-full">{visibleChildren}</div>; return <div className="relative flex flex-row w-full service-container">{visibleChildren}</div>;
} }

31
src/components/tab.jsx Normal file
View File

@@ -0,0 +1,31 @@
import { useContext } from "react";
import classNames from "classnames";
import { TabContext } from "utils/contexts/tab";
export function slugify(tabName) {
return tabName !== undefined ? encodeURIComponent(tabName.toString().replace(/\s+/g, '-').toLowerCase()) : ''
}
export default function Tab({ tab }) {
const { activeTab, setActiveTab } = useContext(TabContext);
return (
<li key={tab} role="presentation"
className={classNames(
"text-theme-700 dark:text-theme-200 relative h-8 w-full rounded-md flex m-1",
)}>
<button id={`${tab}-tab`} type="button" role="tab"
aria-controls={`#${tab}`} aria-selected={activeTab === slugify(tab) ? "true" : "false"}
className={classNames(
"h-full w-full rounded-md",
activeTab === slugify(tab) ? "bg-theme-300/20 dark:bg-white/10" : "hover:bg-theme-100/20 dark:hover:bg-white/5",
)}
onClick={() => {
setActiveTab(slugify(tab));
window.location.hash = `#${slugify(tab)}`;
}}
>{tab}</button>
</li>
);
}

View File

@@ -38,7 +38,7 @@ export default function ColorToggle() {
} }
return ( return (
<div className="w-full self-center"> <div id="color" className="w-full self-center">
<Popover className="relative flex items-center"> <Popover className="relative flex items-center">
<Popover.Button className="outline-none"> <Popover.Button className="outline-none">
<IoColorPalette <IoColorPalette

View File

@@ -10,7 +10,7 @@ export default function Revalidate() {
}; };
return ( return (
<div className="rounded-full flex align-middle self-center mr-3"> <div id="revalidate" className="rounded-full flex align-middle self-center mr-3">
<MdRefresh onClick={() => revalidate()} className="text-theme-800 dark:text-theme-200 w-6 h-6 cursor-pointer" /> <MdRefresh onClick={() => revalidate()} className="text-theme-800 dark:text-theme-200 w-6 h-6 cursor-pointer" />
</div> </div>
); );

View File

@@ -11,7 +11,7 @@ export default function ThemeToggle() {
} }
return ( return (
<div className="rounded-full flex self-end"> <div id="theme" className="rounded-full flex self-end">
<MdLightMode className="text-theme-800 dark:text-theme-200 w-5 h-5 m-1.5" /> <MdLightMode className="text-theme-800 dark:text-theme-200 w-5 h-5 m-1.5" />
{theme === "dark" ? ( {theme === "dark" ? (
<MdToggleOn <MdToggleOn

View File

@@ -25,7 +25,7 @@ export default function Version() {
const latestRelease = releaseData?.[0]; const latestRelease = releaseData?.[0];
return ( return (
<div className="flex flex-row items-center"> <div id="version" className="flex flex-row items-center">
<span className="text-xs text-theme-500 dark:text-theme-400"> <span className="text-xs text-theme-500 dark:text-theme-400">
{version === "main" || version === "dev" || version === "nightly" ? ( {version === "main" || version === "dev" || version === "nightly" ? (
<> <>

View File

@@ -30,7 +30,7 @@ export default function DateTime({ options }) {
}, [date, setDate, dateLocale, format]); }, [date, setDate, dateLocale, format]);
return ( return (
<Container options={options}> <Container options={options} additionalClassNames="information-widget-datetime">
<Raw> <Raw>
<div className="flex flex-row items-center grow justify-end"> <div className="flex flex-row items-center grow justify-end">
<span className={`text-theme-800 dark:text-theme-200 tabular-nums ${textSizes[textSize || "lg"]}`}> <span className={`text-theme-800 dark:text-theme-200 tabular-nums ${textSizes[textSize || "lg"]}`}>

View File

@@ -3,6 +3,7 @@ import { useContext } from "react";
import { FaMemory, FaRegClock, FaThermometerHalf } from "react-icons/fa"; import { FaMemory, FaRegClock, FaThermometerHalf } from "react-icons/fa";
import { FiCpu, FiHardDrive } from "react-icons/fi"; import { FiCpu, FiHardDrive } from "react-icons/fi";
import { useTranslation } from "next-i18next"; import { useTranslation } from "next-i18next";
import classNames from "classnames";
import Error from "../widget/error"; import Error from "../widget/error";
import Resource from "../widget/resource"; import Resource from "../widget/resource";
@@ -32,9 +33,9 @@ export default function Widget({ options }) {
} }
if (!data) { if (!data) {
return <Resources options={options}> return <Resources options={options} additionalClassNames="information-widget-glances">
<Resource icon={FiCpu} label={t("glances.wait")} percentage="0" /> { options.cpu !== false && <Resource icon={FiCpu} label={t("glances.wait")} percentage="0" /> }
<Resource icon={FaMemory} label={t("glances.wait")} percentage="0" /> { options.mem !== false && <Resource icon={FaMemory} label={t("glances.wait")} percentage="0" /> }
{ options.cputemp && <Resource icon={FaThermometerHalf} label={t("glances.wait")} percentage="0" /> } { options.cputemp && <Resource icon={FaThermometerHalf} label={t("glances.wait")} percentage="0" /> }
{ options.disk && !Array.isArray(options.disk) && <Resource key={options.disk} icon={FiHardDrive} label={t("glances.wait")} percentage="0" /> } { options.disk && !Array.isArray(options.disk) && <Resource key={options.disk} icon={FiHardDrive} label={t("glances.wait")} percentage="0" /> }
{ options.disk && Array.isArray(options.disk) && options.disk.map((disk) => <Resource key={`disk_${disk}`} icon={FiHardDrive} label={t("glances.wait")} percentage="0" /> ) } { options.disk && Array.isArray(options.disk) && options.disk.map((disk) => <Resource key={`disk_${disk}`} icon={FiHardDrive} label={t("glances.wait")} percentage="0" /> ) }
@@ -69,9 +70,11 @@ export default function Widget({ options }) {
: [data.fs.find((d) => d.mnt_point === options.disk)].filter((d) => d); : [data.fs.find((d) => d.mnt_point === options.disk)].filter((d) => d);
} }
const addedClasses = classNames('information-widget-glances', { 'expanded': options.expanded })
return ( return (
<Resources options={options} target={settings.target ?? "_blank"}> <Resources options={options} target={settings.target ?? "_blank"} additionalClassNames={addedClasses}>
<Resource {options.cpu !== false && <Resource
icon={FiCpu} icon={FiCpu}
value={t("common.number", { value={t("common.number", {
value: data.cpu.total, value: data.cpu.total,
@@ -89,8 +92,8 @@ export default function Widget({ options }) {
expandedLabel={t("glances.load")} expandedLabel={t("glances.load")}
percentage={data.cpu.total} percentage={data.cpu.total}
expanded={options.expanded} expanded={options.expanded}
/> />}
<Resource {options.mem !== false && <Resource
icon={FaMemory} icon={FaMemory}
value={t("common.bytes", { value={t("common.bytes", {
value: data.mem.free, value: data.mem.free,
@@ -106,7 +109,7 @@ export default function Widget({ options }) {
expandedLabel={t("glances.total")} expandedLabel={t("glances.total")}
percentage={data.mem.percent} percentage={data.mem.percent}
expanded={options.expanded} expanded={options.expanded}
/> />}
{disks.map((disk) => ( {disks.map((disk) => (
<Resource key={`disk_${disk.mnt_point ?? disk.device_name}`} <Resource key={`disk_${disk.mnt_point ?? disk.device_name}`}
icon={FiHardDrive} icon={FiHardDrive}

View File

@@ -14,7 +14,7 @@ const textSizes = {
export default function Greeting({ options }) { export default function Greeting({ options }) {
if (options.text) { if (options.text) {
return <Container options={options}> return <Container options={options} additionalClassNames="information-widget-greeting">
<Raw> <Raw>
<span className={`text-theme-800 dark:text-theme-200 mr-3 ${textSizes[options.text_size || "xl"]}`}> <span className={`text-theme-800 dark:text-theme-200 mr-3 ${textSizes[options.text_size || "xl"]}`}>
{options.text} {options.text}

View File

@@ -36,7 +36,7 @@ export default function Widget({ options }) {
} }
if (!data) { if (!data) {
return <Container options={options}> return <Container options={options} additionalClassNames="information-widget-kubernetes">
<Raw> <Raw>
<div className="flex flex-row self-center flex-wrap justify-between"> <div className="flex flex-row self-center flex-wrap justify-between">
{cluster.show && {cluster.show &&
@@ -50,7 +50,7 @@ export default function Widget({ options }) {
</Container>; </Container>;
} }
return <Container options={options}> return <Container options={options} additionalClassNames="information-widget-kubernetes">
<Raw> <Raw>
<div className="flex flex-row self-center flex-wrap justify-between"> <div className="flex flex-row self-center flex-wrap justify-between">
{cluster.show && {cluster.show &&

View File

@@ -5,14 +5,14 @@ import ResolvedIcon from "components/resolvedicon"
export default function Logo({ options }) { export default function Logo({ options }) {
return ( return (
<Container options={options}> <Container options={options} additionalClassNames={`information-widget-logo ${ options.icon ? 'resolved' : 'fallback'}`}>
<Raw> <Raw>
{options.icon ? {options.icon ?
<div className="mr-3"> <div className="resolved mr-3">
<ResolvedIcon icon={options.icon} width={48} height={48} /> <ResolvedIcon icon={options.icon} width={48} height={48} />
</div> : </div> :
// fallback to homepage logo // fallback to homepage logo
<div className="w-12 h-12"> <div className="fallback w-12 h-12">
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 1024 1024" viewBox="0 0 1024 1024"

View File

@@ -17,14 +17,14 @@ export default function Longhorn({ options }) {
} }
if (!data) { if (!data) {
return <Container options={options}> return <Container options={options} additionalClassNames="infomation-widget-longhorn">
<Raw> <Raw>
<div className="flex flex-row self-center flex-wrap justify-between" /> <div className="flex flex-row self-center flex-wrap justify-between" />
</Raw> </Raw>
</Container>; </Container>;
} }
return <Container options={options}> return <Container options={options} additionalClassNames="infomation-widget-longhorn">
<Raw> <Raw>
<div className="flex flex-row self-center flex-wrap justify-between"> <div className="flex flex-row self-center flex-wrap justify-between">
{data.nodes {data.nodes

View File

@@ -8,6 +8,7 @@ export default function Node({ data, expanded, labels }) {
const { t } = useTranslation(); const { t } = useTranslation();
return <Resource return <Resource
additionalClassNames="information-widget-longhorn-node"
icon={FaThermometerHalf} icon={FaThermometerHalf}
value={t("common.bytes", { value: data.node.available })} value={t("common.bytes", { value: data.node.available })}
label={t("resources.free")} label={t("resources.free")}

View File

@@ -24,7 +24,7 @@ function Widget({ options }) {
} }
if (!data) { if (!data) {
return <Container options={options}> return <Container options={options} additionalClassNames="information-widget-openmeteo">
<PrimaryText>{t("weather.updating")}</PrimaryText> <PrimaryText>{t("weather.updating")}</PrimaryText>
<SecondaryText>{t("weather.wait")}</SecondaryText> <SecondaryText>{t("weather.wait")}</SecondaryText>
<WidgetIcon icon={WiCloudDown} size="l" /> <WidgetIcon icon={WiCloudDown} size="l" />
@@ -35,7 +35,7 @@ function Widget({ options }) {
const condition = data.current_weather.weathercode; const condition = data.current_weather.weathercode;
const timeOfDay = data.current_weather.time > data.daily.sunrise[0] && data.current_weather.time < data.daily.sunset[0] ? "day" : "night"; const timeOfDay = data.current_weather.time > data.daily.sunrise[0] && data.current_weather.time < data.daily.sunset[0] ? "day" : "night";
return <Container options={options}> return <Container options={options} additionalClassNames="information-widget-openmeteo">
<PrimaryText> <PrimaryText>
{options.label && `${options.label}, `} {options.label && `${options.label}, `}
{t("common.number", { {t("common.number", {
@@ -81,7 +81,7 @@ export default function OpenMeteo({ options }) {
// if (!requesting && !location) requestLocation(); // if (!requesting && !location) requestLocation();
if (!location) { if (!location) {
return <ContainerButton options={options} callback={requestLocation} > return <ContainerButton options={options} callback={requestLocation} additionalClassNames="information-widget-openmeteo-location-button">
<PrimaryText>{t("weather.current")}</PrimaryText> <PrimaryText>{t("weather.current")}</PrimaryText>
<SecondaryText>{t("weather.allow")}</SecondaryText> <SecondaryText>{t("weather.allow")}</SecondaryText>
<WidgetIcon icon={ requesting ? MdLocationSearching : MdLocationDisabled} size="m" pulse /> <WidgetIcon icon={ requesting ? MdLocationSearching : MdLocationDisabled} size="m" pulse />

View File

@@ -24,7 +24,7 @@ function Widget({ options }) {
} }
if (!data) { if (!data) {
return <Container options={options}> return <Container options={options} additionalClassNames="information-widget-openweathermap">
<PrimaryText>{t("weather.updating")}</PrimaryText> <PrimaryText>{t("weather.updating")}</PrimaryText>
<SecondaryText>{t("weather.wait")}</SecondaryText> <SecondaryText>{t("weather.wait")}</SecondaryText>
<WidgetIcon icon={WiCloudDown} size="l" /> <WidgetIcon icon={WiCloudDown} size="l" />
@@ -36,7 +36,7 @@ function Widget({ options }) {
const condition = data.weather[0].id; const condition = data.weather[0].id;
const timeOfDay = data.dt > data.sys.sunrise && data.dt < data.sys.sunset ? "day" : "night"; const timeOfDay = data.dt > data.sys.sunrise && data.dt < data.sys.sunset ? "day" : "night";
return <Container options={options}> return <Container options={options} additionalClassNames="information-widget-openweathermap">
<PrimaryText>{options.label && `${options.label}, ` }{t("common.number", { value: data.main.temp, style: "unit", unit })}</PrimaryText> <PrimaryText>{options.label && `${options.label}, ` }{t("common.number", { value: data.main.temp, style: "unit", unit })}</PrimaryText>
<SecondaryText>{data.weather[0].description}</SecondaryText> <SecondaryText>{data.weather[0].description}</SecondaryText>
<WidgetIcon icon={mapIcon(condition, timeOfDay)} size="xl" /> <WidgetIcon icon={mapIcon(condition, timeOfDay)} size="xl" />

View File

@@ -1,6 +1,6 @@
export default function UsageBar({ percent }) { export default function UsageBar({ percent, additionalClassNames='' }) {
return ( return (
<div className="mt-0.5 w-full bg-theme-800/30 rounded-full h-1 dark:bg-theme-200/20"> <div className={`mt-0.5 w-full bg-theme-800/30 rounded-full h-1 dark:bg-theme-200/20 ${additionalClassNames}`}>
<div <div
className="bg-theme-800/70 h-1 rounded-full dark:bg-theme-200/50 transition-all duration-1000" className="bg-theme-800/70 h-1 rounded-full dark:bg-theme-200/50 transition-all duration-1000"
style={{ style={{

View File

@@ -103,7 +103,7 @@ export default function Search({ options }) {
localStorage.setItem(localStorageKey, provider.name); localStorage.setItem(localStorageKey, provider.name);
} }
return <ContainerForm options={options} callback={submitCallback} additionalClassNames="grow" > return <ContainerForm options={options} callback={submitCallback} additionalClassNames="grow information-widget-search" >
<Raw> <Raw>
<div className="flex-col relative h-8 my-4 min-w-fit"> <div className="flex-col relative h-8 my-4 min-w-fit">
<div className="flex absolute inset-y-0 left-0 items-center pl-3 pointer-events-none w-full text-theme-800 dark:text-white" /> <div className="flex absolute inset-y-0 left-0 items-center pl-3 pointer-events-none w-full text-theme-800 dark:text-white" />

View File

@@ -25,7 +25,7 @@ export default function Widget({ options }) {
const defaultSite = options.site ? statsData?.data.find(s => s.desc === options.site) : statsData?.data?.find(s => s.name === "default"); const defaultSite = options.site ? statsData?.data.find(s => s.desc === options.site) : statsData?.data?.find(s => s.name === "default");
if (!defaultSite) { if (!defaultSite) {
return <Container options={options}> return <Container options={options} additionalClassNames="information-widget-unifi-console">
<PrimaryText>{t("unifi.wait")}</PrimaryText> <PrimaryText>{t("unifi.wait")}</PrimaryText>
<WidgetIcon icon={SiUbiquiti} /> <WidgetIcon icon={SiUbiquiti} />
</Container>; </Container>;
@@ -43,7 +43,7 @@ export default function Widget({ options }) {
const dataEmpty = !(wan.show || lan.show || wlan.show || uptime); const dataEmpty = !(wan.show || lan.show || wlan.show || uptime);
return <Container options={options}> return <Container options={options} additionalClassNames="information-widget-unifi-console">
<Raw> <Raw>
<div className="flex-none flex flex-row items-center mr-3 py-1.5"> <div className="flex-none flex flex-row items-center mr-3 py-1.5">
<div className="flex flex-col"> <div className="flex flex-col">

View File

@@ -24,7 +24,7 @@ function Widget({ options }) {
} }
if (!data) { if (!data) {
return <Container options={options}> return <Container options={options} additionalClassNames="information-widget-weather">
<PrimaryText>{t("weather.updating")}</PrimaryText> <PrimaryText>{t("weather.updating")}</PrimaryText>
<SecondaryText>{t("weather.wait")}</SecondaryText> <SecondaryText>{t("weather.wait")}</SecondaryText>
<WidgetIcon icon={WiCloudDown} size="l" /> <WidgetIcon icon={WiCloudDown} size="l" />
@@ -35,7 +35,7 @@ function Widget({ options }) {
const condition = data.current.condition.code; const condition = data.current.condition.code;
const timeOfDay = data.current.is_day ? "day" : "night"; const timeOfDay = data.current.is_day ? "day" : "night";
return <Container options={options}> return <Container options={options} additionalClassNames="information-widget-weather">
<PrimaryText> <PrimaryText>
{options.label && `${options.label}, `} {options.label && `${options.label}, `}
{t("common.number", { {t("common.number", {

View File

@@ -9,11 +9,14 @@ export function getAllClasses(options, additionalClassNames = '') {
if (options?.style?.header === "boxedWidgets") { if (options?.style?.header === "boxedWidgets") {
if (options?.style?.cardBlur !== undefined) { if (options?.style?.cardBlur !== undefined) {
// eslint-disable-next-line no-param-reassign // eslint-disable-next-line no-param-reassign
additionalClassNames = additionalClassNames.concat(additionalClassNames, ` backdrop-blur${options.style.cardBlur.length ? '-' : ""}${options.style.cardBlur}`) additionalClassNames = [
additionalClassNames,
`backdrop-blur${options.style.cardBlur.length ? '-' : ""}${options.style.cardBlur}`
].join(' ')
} }
return classNames( return classNames(
"flex flex-col justify-center first:ml-0 ml-2 mr-2", "flex flex-col justify-center ml-2 mr-2",
"mt-2 m:mb-0 rounded-md shadow-md shadow-theme-900/10 dark:shadow-theme-900/20 bg-theme-100/20 dark:bg-white/5 p-2 pl-3 pr-3", "mt-2 m:mb-0 rounded-md shadow-md shadow-theme-900/10 dark:shadow-theme-900/20 bg-theme-100/20 dark:bg-white/5 p-2 pl-3 pr-3",
additionalClassNames additionalClassNames
); );
@@ -32,9 +35,9 @@ export function getAllClasses(options, additionalClassNames = '') {
export function getInnerBlock(children) { export function getInnerBlock(children) {
// children won't be an array if it's Raw component // children won't be an array if it's Raw component
return Array.isArray(children) && <div className="flex flex-row items-center justify-end"> return Array.isArray(children) && <div className="flex flex-row items-center justify-end widget-inner">
<div className="flex flex-col items-center">{children.find(child => child.type === WidgetIcon)}</div> <div className="flex flex-col items-center widget-inner-icon">{children.find(child => child.type === WidgetIcon)}</div>
<div className="flex flex-col ml-3 text-left"> <div className="flex flex-col ml-3 text-left widget-inner-text">
{children.find(child => child.type === PrimaryText)} {children.find(child => child.type === PrimaryText)}
{children.find(child => child.type === SecondaryText)} {children.find(child => child.type === SecondaryText)}
</div> </div>
@@ -51,7 +54,7 @@ export function getBottomBlock(children) {
export default function Container({ children = [], options, additionalClassNames = '' }) { export default function Container({ children = [], options, additionalClassNames = '' }) {
return ( return (
<div className={getAllClasses(options, additionalClassNames)}> <div className={getAllClasses(options, `${ additionalClassNames } widget-container`)}>
{getInnerBlock(children)} {getInnerBlock(children)}
{getBottomBlock(children)} {getBottomBlock(children)}
</div> </div>

View File

@@ -2,7 +2,7 @@ import { getAllClasses, getInnerBlock, getBottomBlock } from "./container";
export default function ContainerButton ({ children = [], options, additionalClassNames = '', callback }) { export default function ContainerButton ({ children = [], options, additionalClassNames = '', callback }) {
return ( return (
<button type="button" onClick={callback} className={getAllClasses(options, additionalClassNames)}> <button type="button" onClick={callback} className={`${ getAllClasses(options, additionalClassNames) } information-widget-container-button`}>
{getInnerBlock(children)} {getInnerBlock(children)}
{getBottomBlock(children)} {getBottomBlock(children)}
</button> </button>

View File

@@ -2,7 +2,7 @@ import { getAllClasses, getInnerBlock, getBottomBlock } from "./container";
export default function ContainerForm ({ children = [], options, additionalClassNames = '', callback }) { export default function ContainerForm ({ children = [], options, additionalClassNames = '', callback }) {
return ( return (
<form type="button" onSubmit={callback} className={getAllClasses(options, additionalClassNames)}> <form type="button" onSubmit={callback} className={`${ getAllClasses(options, additionalClassNames) } information-widget-form`}>
{getInnerBlock(children)} {getInnerBlock(children)}
{getBottomBlock(children)} {getBottomBlock(children)}
</form> </form>

View File

@@ -2,7 +2,7 @@ import { getAllClasses, getInnerBlock, getBottomBlock } from "./container";
export default function ContainerLink ({ children = [], options, additionalClassNames = '', target }) { export default function ContainerLink ({ children = [], options, additionalClassNames = '', target }) {
return ( return (
<a href={options.url} target={target} className={getAllClasses(options, additionalClassNames)}> <a href={options.url} target={target} className={`${ getAllClasses(options, additionalClassNames) } information-widget-link`}>
{getInnerBlock(children)} {getInnerBlock(children)}
{getBottomBlock(children)} {getBottomBlock(children)}
</a> </a>

View File

@@ -8,7 +8,7 @@ import WidgetIcon from "./widget_icon";
export default function Error({ options }) { export default function Error({ options }) {
const { t } = useTranslation(); const { t } = useTranslation();
return <Container options={options}> return <Container options={options} additionalClassNames="information-widget-error">
<PrimaryText>{t("widget.api_error")}</PrimaryText> <PrimaryText>{t("widget.api_error")}</PrimaryText>
<WidgetIcon icon={BiError} size="l" /> <WidgetIcon icon={BiError} size="l" />
</Container>; </Container>;

View File

@@ -1,5 +1,5 @@
export default function PrimaryText({ children }) { export default function PrimaryText({ children }) {
return ( return (
<span className="text-theme-800 dark:text-theme-200 text-sm">{children}</span> <span className="primary-text text-theme-800 dark:text-theme-200 text-sm">{children}</span>
); );
} }

View File

@@ -1,11 +1,11 @@
import UsageBar from "../resources/usage-bar"; import UsageBar from "../resources/usage-bar";
export default function Resource({ children, icon, value, label, expandedValue = "", expandedLabel = "", percentage, expanded = false }) { export default function Resource({ children, icon, value, label, expandedValue = "", expandedLabel = "", percentage, expanded = false, additionalClassNames='' }) {
const Icon = icon; const Icon = icon;
return <div className="flex-none flex flex-row items-center mr-3 py-1.5"> return <div className={`flex-none flex flex-row items-center mr-3 py-1.5 information-widget-resource ${ additionalClassNames }`}>
<Icon className="text-theme-800 dark:text-theme-200 w-5 h-5"/> <Icon className="text-theme-800 dark:text-theme-200 w-5 h-5 resource-icon"/>
<div className="flex flex-col ml-3 text-left min-w-[85px]"> <div className={ `flex flex-col ml-3 text-left min-w-[85px] ${ expanded ? ' expanded' : ''}`}>
<div className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between"> <div className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between">
<div className="pl-0.5">{value}</div> <div className="pl-0.5">{value}</div>
<div className="pr-1">{label}</div> <div className="pr-1">{label}</div>
@@ -15,7 +15,7 @@ export default function Resource({ children, icon, value, label, expandedValue =
<div className="pr-1">{expandedLabel}</div> <div className="pr-1">{expandedLabel}</div>
</div> </div>
} }
{ percentage >= 0 && <UsageBar percent={percentage} /> } { percentage >= 0 && <UsageBar percent={percentage} additionalClassNames="resource-usage" /> }
{ children } { children }
</div> </div>
</div>; </div>;

View File

@@ -1,12 +1,15 @@
import classNames from "classnames";
import ContainerLink from "./container_link"; import ContainerLink from "./container_link";
import Resource from "./resource"; import Resource from "./resource";
import Raw from "./raw"; import Raw from "./raw";
import WidgetLabel from "./widget_label"; import WidgetLabel from "./widget_label";
export default function Resources({ options, children, target }) { export default function Resources({ options, children, target, additionalClassNames }) {
const widgetParts = [].concat(...children); const widgetParts = [].concat(...children);
const addedClassNames = classNames('information-widget-resources', additionalClassNames);
return <ContainerLink options={options} target={target}> return <ContainerLink options={options} target={target} additionalClassNames={ addedClassNames }>
<Raw> <Raw>
<div className="flex flex-row self-center flex-wrap justify-between"> <div className="flex flex-row self-center flex-wrap justify-between">
{ widgetParts.filter(child => child && child.type === Resource) } { widgetParts.filter(child => child && child.type === Resource) }

View File

@@ -1,5 +1,5 @@
export default function SecondaryText({ children }) { export default function SecondaryText({ children }) {
return ( return (
<span className="text-theme-800 dark:text-theme-200 text-xs">{children}</span> <span className="secondary-text text-theme-800 dark:text-theme-200 text-xs">{children}</span>
); );
} }

View File

@@ -1,6 +1,6 @@
export default function WidgetIcon({ icon, size = "s", pulse = false }) { export default function WidgetIcon({ icon, size = "s", pulse = false }) {
const Icon = icon; const Icon = icon;
let additionalClasses = "text-theme-800 dark:text-theme-200 "; let additionalClasses = "information-widget-icon text-theme-800 dark:text-theme-200 ";
switch (size) { switch (size) {
case "m": additionalClasses += "w-6 h-6 "; break; case "m": additionalClasses += "w-6 h-6 "; break;

View File

@@ -1,3 +1,3 @@
export default function WidgetLabel({ label = "" }) { export default function WidgetLabel({ label = "" }) {
return <div className="pt-1 text-center text-theme-800 dark:text-theme-200 text-xs">{label}</div> return <div className="information-widget-label pt-1 text-center text-theme-800 dark:text-theme-200 text-xs">{label}</div>
} }

View File

@@ -11,6 +11,7 @@ import nextI18nextConfig from "../../next-i18next.config";
import { ColorProvider } from "utils/contexts/color"; import { ColorProvider } from "utils/contexts/color";
import { ThemeProvider } from "utils/contexts/theme"; import { ThemeProvider } from "utils/contexts/theme";
import { SettingsProvider } from "utils/contexts/settings"; import { SettingsProvider } from "utils/contexts/settings";
import { TabProvider } from "utils/contexts/tab";
function MyApp({ Component, pageProps }) { function MyApp({ Component, pageProps }) {
return ( return (
@@ -26,7 +27,9 @@ function MyApp({ Component, pageProps }) {
<ColorProvider> <ColorProvider>
<ThemeProvider> <ThemeProvider>
<SettingsProvider> <SettingsProvider>
<Component {...pageProps} /> <TabProvider>
<Component {...pageProps} />
</TabProvider>
</SettingsProvider> </SettingsProvider>
</ThemeProvider> </ThemeProvider>
</ColorProvider> </ColorProvider>

View File

@@ -9,7 +9,7 @@ export default function Document() {
content="A highly customizable homepage (or startpage / application dashboard) with Docker and service API integrations." content="A highly customizable homepage (or startpage / application dashboard) with Docker and service API integrations."
/> />
<meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-capable" content="yes" />
<link rel="manifest" href="/site.webmanifest?v=4" /> <link rel="manifest" href="/site.webmanifest?v=4" crossOrigin="use-credentials" />
<link rel="mask-icon" href="/safari-pinned-tab.svg?v=4" color="#1e9cd7" /> <link rel="mask-icon" href="/safari-pinned-tab.svg?v=4" color="#1e9cd7" />
</Head> </Head>
<body> <body>

View File

@@ -0,0 +1,35 @@
import path from "path";
import fs from "fs";
import { CONF_DIR } from "utils/config/config";
import createLogger from "utils/logger";
const logger = createLogger("configFileService");
/**
* @param {import("next").NextApiRequest} req
* @param {import("next").NextApiResponse} res
*/
export default async function handler(req, res) {
const { path: relativePath } = req.query;
// only two supported files, for now
if (!['custom.css', 'custom.js'].includes(relativePath))
{
return res.status(422).end('Unsupported file');
}
const filePath = path.join(CONF_DIR, relativePath);
try {
// Read the content of the file or return empty content
const fileContent = fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf-8') : '';
// hard-coded since we only support two known files for now
const mimeType = (relativePath === 'custom.css') ? 'text/css' : 'text/javascript';
res.setHeader('Content-Type', mimeType);
return res.status(200).send(fileContent);
} catch (error) {
logger.error(error);
return res.status(500).end('Internal Server Error');
}
}

View File

@@ -4,7 +4,7 @@ import { readFileSync } from "fs";
import checkAndCopyConfig, { CONF_DIR } from "utils/config/config"; import checkAndCopyConfig, { CONF_DIR } from "utils/config/config";
const configs = ["docker.yaml", "settings.yaml", "services.yaml", "bookmarks.yaml", "widgets.yaml"]; const configs = ["docker.yaml", "settings.yaml", "services.yaml", "bookmarks.yaml", "widgets.yaml", "custom.css", "custom.js"];
function hash(buffer) { function hash(buffer) {
const hashSum = createHash("sha256"); const hashSum = createHash("sha256");

View File

@@ -4,10 +4,13 @@ import Head from "next/head";
import dynamic from "next/dynamic"; import dynamic from "next/dynamic";
import classNames from "classnames"; import classNames from "classnames";
import { useTranslation } from "next-i18next"; import { useTranslation } from "next-i18next";
import { useEffect, useContext, useState } from "react"; import { useEffect, useContext, useState, useMemo } from "react";
import { BiError } from "react-icons/bi"; import { BiError } from "react-icons/bi";
import { serverSideTranslations } from "next-i18next/serverSideTranslations"; import { serverSideTranslations } from "next-i18next/serverSideTranslations";
import { useRouter } from "next/router";
import Tab, { slugify } from "components/tab";
import FileContent from "components/filecontent";
import ServicesGroup from "components/services/group"; import ServicesGroup from "components/services/group";
import BookmarksGroup from "components/bookmarks/group"; import BookmarksGroup from "components/bookmarks/group";
import Widget from "components/widgets/widget"; import Widget from "components/widgets/widget";
@@ -18,6 +21,7 @@ import { getSettings } from "utils/config/config";
import { ColorContext } from "utils/contexts/color"; import { ColorContext } from "utils/contexts/color";
import { ThemeContext } from "utils/contexts/theme"; import { ThemeContext } from "utils/contexts/theme";
import { SettingsContext } from "utils/contexts/settings"; import { SettingsContext } from "utils/contexts/settings";
import { TabContext } from "utils/contexts/tab";
import { bookmarksResponse, servicesResponse, widgetsResponse } from "utils/config/api-response"; import { bookmarksResponse, servicesResponse, widgetsResponse } from "utils/config/api-response";
import ErrorBoundary from "components/errorboundry"; import ErrorBoundary from "components/errorboundry";
import themes from "utils/styles/themes"; import themes from "utils/styles/themes";
@@ -157,10 +161,10 @@ function Index({ initialSettings, fallback }) {
const headerStyles = { const headerStyles = {
boxed: boxed:
"m-4 mb-0 sm:m-8 sm:mb-0 rounded-md shadow-md shadow-theme-900/10 dark:shadow-theme-900/20 bg-theme-100/20 dark:bg-white/5 p-3", "m-6 mb-0 sm:m-9 sm:mb-0 rounded-md shadow-md shadow-theme-900/10 dark:shadow-theme-900/20 bg-theme-100/20 dark:bg-white/5 p-3",
underlined: "m-4 mb-0 sm:m-8 sm:mb-1 border-b-2 pb-4 border-theme-800 dark:border-theme-200/50", underlined: "m-6 mb-0 sm:m-9 sm:mb-1 border-b-2 pb-4 border-theme-800 dark:border-theme-200/50",
clean: "m-4 mb-0 sm:m-8 sm:mb-0", clean: "m-6 mb-0 sm:m-9 sm:mb-0",
boxedWidgets: "m-4 mb-0 sm:m-8 sm:mb-0 sm:mt-1", boxedWidgets: "m-6 mb-0 sm:m-9 sm:mb-0 sm:mt-1",
}; };
function Home({ initialSettings }) { function Home({ initialSettings }) {
@@ -168,6 +172,8 @@ function Home({ initialSettings }) {
const { theme, setTheme } = useContext(ThemeContext); const { theme, setTheme } = useContext(ThemeContext);
const { color, setColor } = useContext(ColorContext); const { color, setColor } = useContext(ColorContext);
const { settings, setSettings } = useContext(SettingsContext); const { settings, setSettings } = useContext(SettingsContext);
const { activeTab, setActiveTab } = useContext(TabContext);
const { asPath } = useRouter();
useEffect(() => { useEffect(() => {
setSettings(initialSettings); setSettings(initialSettings);
@@ -209,12 +215,12 @@ function Home({ initialSettings }) {
searchProvider = searchProviders[searchWidget.options?.provider]; searchProvider = searchProviders[searchWidget.options?.provider];
} }
} }
const headerStyle = initialSettings?.headerStyle || "underlined"; const headerStyle = settings?.headerStyle || "underlined";
useEffect(() => { useEffect(() => {
function handleKeyDown(e) { function handleKeyDown(e) {
if (e.target.tagName === "BODY") { if (e.target.tagName === "BODY" || e.target.id === "inner_wrapper") {
if (String.fromCharCode(e.keyCode).match(/(\w|\s)/g) && !(e.altKey || e.ctrlKey || e.metaKey || e.shiftKey)) { if (e.key.match(/(\w|\s)/g) && !(e.altKey || e.ctrlKey || e.metaKey || e.shiftKey || e.code === "Tab")) {
setSearching(true); setSearching(true);
} else if (e.key === "Escape") { } else if (e.key === "Escape") {
setSearchString(""); setSearchString("");
@@ -230,15 +236,110 @@ function Home({ initialSettings }) {
} }
}) })
const tabs = useMemo( () => [
...new Set(
Object.keys(settings.layout ?? {}).map(
(groupName) => settings.layout[groupName]?.tab?.toString()
).filter(group => group)
)
], [settings.layout]);
useEffect(() => {
if (!activeTab) {
const initialTab = decodeURI(asPath.substring(asPath.indexOf("#") + 1));
setActiveTab(initialTab === '/' ? slugify(tabs['0']) : initialTab)
}
})
const servicesAndBookmarksGroups = useMemo(() => {
const tabGroupFilter = g => g && [activeTab, ''].includes(slugify(settings.layout?.[g.name]?.tab));
const undefinedGroupFilter = g => settings.layout?.[g.name] === undefined;
const layoutGroups = Object.keys(settings.layout ?? {}).map(
(groupName) => services?.find(g => g.name === groupName) ?? bookmarks?.find(b => b.name === groupName)
).filter(tabGroupFilter);
if (!settings.layout && JSON.stringify(settings.layout) !== JSON.stringify(initialSettings.layout)) {
// wait for settings to populate (if different from initial settings), otherwise all the widgets will be requested initially even if we are on a single tab
return <div />;
}
const serviceGroups = services?.filter(tabGroupFilter).filter(undefinedGroupFilter);
const bookmarkGroups = bookmarks.filter(tabGroupFilter).filter(undefinedGroupFilter);
return <>
{tabs.length > 0 && <div key="tabs" id="tabs" className="m-6 sm:m-9 sm:mt-4 sm:mb-0">
<ul className={classNames(
"sm:flex rounded-md bg-theme-100/20 dark:bg-white/5",
settings.cardBlur !== undefined && `backdrop-blur${settings.cardBlur.length ? '-': "" }${settings.cardBlur}`
)} id="myTab" data-tabs-toggle="#myTabContent" role="tablist" >
{tabs.map(tab => <Tab key={tab} tab={tab} />)}
</ul>
</div>}
{layoutGroups.length > 0 && <div key="layoutGroups" id="layout-groups" className="flex flex-wrap m-4 sm:m-8 sm:mt-4 items-start mb-2">
{layoutGroups.map((group) => (
group.services ?
(<ServicesGroup
key={group.name}
group={group.name}
services={group}
layout={settings.layout?.[group.name]}
fiveColumns={settings.fiveColumns}
disableCollapse={settings.disableCollapse}
/>) :
(<BookmarksGroup
key={group.name}
bookmarks={group}
layout={settings.layout?.[group.name]}
disableCollapse={settings.disableCollapse}
/>)
)
)}
</div>}
{serviceGroups?.length > 0 && <div key="services" id="services" className="flex flex-wrap m-4 sm:m-8 sm:mt-4 items-start mb-2">
{serviceGroups.map((group) => (
<ServicesGroup
key={group.name}
group={group.name}
services={group}
layout={settings.layout?.[group.name]}
fiveColumns={settings.fiveColumns}
disableCollapse={settings.disableCollapse}
/>
))}
</div>}
{bookmarkGroups?.length > 0 && <div key="bookmarks" id="bookmarks" className="flex flex-wrap m-4 sm:m-8 sm:mt-4 items-start mb-2">
{bookmarkGroups.map((group) => (
<BookmarksGroup
key={group.name}
bookmarks={group}
layout={settings.layout?.[group.name]}
disableCollapse={settings.disableCollapse}
/>
))}
</div>}
</>
}, [
tabs,
activeTab,
services,
bookmarks,
settings.layout,
settings.fiveColumns,
settings.disableCollapse,
settings.cardBlur,
initialSettings.layout
]);
return ( return (
<> <>
<Head> <Head>
<title>{initialSettings.title || "Homepage"}</title> <title>{settings.title || "Homepage"}</title>
{initialSettings.base && <base href={initialSettings.base} />} {settings.base && <base href={settings.base} />}
{initialSettings.favicon ? ( {settings.favicon ? (
<> <>
<link rel="apple-touch-icon" sizes="180x180" href={initialSettings.favicon} /> <link rel="apple-touch-icon" sizes="180x180" href={settings.favicon} />
<link rel="icon" href={initialSettings.favicon} /> <link rel="icon" href={settings.favicon} />
</> </>
) : ( ) : (
<> <>
@@ -248,84 +349,78 @@ function Home({ initialSettings }) {
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png?v=4" /> <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png?v=4" />
</> </>
)} )}
<meta <meta name="msapplication-TileColor" content={themes[settings.color || "slate"][settings.theme || "dark"]} />
name="msapplication-TileColor" <meta name="theme-color" content={themes[settings.color || "slate"][settings.theme || "dark"]} />
content={themes[initialSettings.color || "slate"][initialSettings.theme || "dark"]}
/>
<meta name="theme-color" content={themes[initialSettings.color || "slate"][initialSettings.theme || "dark"]} />
</Head> </Head>
<link rel="preload" href="/api/config/custom.css" as="fetch" crossOrigin="anonymous" />
<style data-name="custom.css">
<FileContent path="custom.css"
loadingValue="/* Loading custom CSS... */"
errorValue="/* Failed to load custom CSS... */"
emptyValue="/* No custom CSS */"
/>
</style>
<link rel="preload" href="/api/config/custom.js" as="fetch" crossOrigin="anonymous" />
<script data-name="custom.js" src="/api/config/custom.js" async />
<div className="relative container m-auto flex flex-col justify-start z-10 h-full"> <div className="relative container m-auto flex flex-col justify-start z-10 h-full">
<QuickLaunch
servicesAndBookmarks={servicesAndBookmarks}
searchString={searchString}
setSearchString={setSearchString}
isOpen={searching}
close={setSearching}
searchProvider={settings.quicklaunch?.hideInternetSearch ? null : searchProvider}
/>
<div <div
id="information-widgets"
className={classNames( className={classNames(
"flex flex-row flex-wrap justify-between", "flex flex-row flex-wrap justify-between",
headerStyles[headerStyle], headerStyles[headerStyle],
initialSettings.cardBlur !== undefined && headerStyle === "boxed" && `backdrop-blur${initialSettings.cardBlur.length ? '-' : ""}${initialSettings.cardBlur}` settings.cardBlur !== undefined && headerStyle === "boxed" && `backdrop-blur${settings.cardBlur.length ? '-' : ""}${settings.cardBlur}`
)} )}
> >
<QuickLaunch <div id="widgets-wrap"
servicesAndBookmarks={servicesAndBookmarks} style={{width: 'calc(100% + 1rem)'}}
searchString={searchString} className={classNames(
setSearchString={setSearchString} "flex flex-row w-full flex-wrap justify-between -ml-2 -mr-2"
isOpen={searching} )}
close={setSearching} >
searchProvider={settings.quicklaunch?.hideInternetSearch ? null : searchProvider} {widgets && (
/> <>
{widgets && (
<>
{widgets
.filter((widget) => !rightAlignedWidgets.includes(widget.type))
.map((widget, i) => (
<Widget key={i} widget={widget} style={{ header: headerStyle, isRightAligned: false, cardBlur: initialSettings.cardBlur }} />
))}
<div className={classNames(
"m-auto flex flex-wrap grow sm:basis-auto justify-between md:justify-end",
headerStyle === "boxedWidgets" ? "sm:ml-4" : "sm:ml-2"
)}>
{widgets {widgets
.filter((widget) => rightAlignedWidgets.includes(widget.type)) .filter((widget) => !rightAlignedWidgets.includes(widget.type))
.map((widget, i) => ( .map((widget, i) => (
<Widget key={i} widget={widget} style={{ header: headerStyle, isRightAligned: true, cardBlur: initialSettings.cardBlur }} /> <Widget key={i} widget={widget} style={{ header: headerStyle, isRightAligned: false, cardBlur: settings.cardBlur }} />
))} ))}
</div>
</> <div id="information-widgets-right" className={classNames(
)} "m-auto flex flex-wrap grow sm:basis-auto justify-between md:justify-end",
headerStyle === "boxedWidgets" ? "sm:ml-4" : "sm:ml-2"
)}>
{widgets
.filter((widget) => rightAlignedWidgets.includes(widget.type))
.map((widget, i) => (
<Widget key={i} widget={widget} style={{ header: headerStyle, isRightAligned: true, cardBlur: settings.cardBlur }} />
))}
</div>
</>
)}
</div>
</div> </div>
{services?.length > 0 && ( {servicesAndBookmarksGroups}
<div className="flex flex-wrap p-4 sm:p-8 sm:pt-4 items-start pb-2">
{services.map((group) => (
<ServicesGroup
key={group.name}
group={group.name}
services={group}
layout={initialSettings.layout?.[group.name]}
fiveColumns={settings.fiveColumns}
disableCollapse={settings.disableCollapse} />
))}
</div>
)}
{bookmarks?.length > 0 && ( <div id="footer" className="flex flex-col mt-auto p-8 w-full">
<div className={`grow flex flex-wrap pt-0 p-4 sm:p-8 gap-2 grid-cols-1 lg:grid-cols-2 lg:grid-cols-${Math.min(6, bookmarks.length)}`}> <div id="style" className="flex w-full justify-end">
{bookmarks.map((group) => ( {!settings?.color && <ColorToggle />}
<BookmarksGroup
key={group.name}
group={group}
disableCollapse={settings.disableCollapse} />
))}
</div>
)}
<div className="flex flex-col mt-auto p-8 w-full">
<div className="flex w-full justify-end">
{!initialSettings?.color && <ColorToggle />}
<Revalidate /> <Revalidate />
{!initialSettings?.theme && <ThemeToggle />} {!settings.theme && <ThemeToggle />}
</div> </div>
<div className="flex mt-4 w-full justify-end"> <div id="version" className="flex mt-4 w-full justify-end">
{!initialSettings?.hideVersion && <Version />} {!settings.hideVersion && <Version />}
</div> </div>
</div> </div>
</div> </div>
@@ -375,6 +470,7 @@ export default function Wrapper({ initialSettings, fallback }) {
> >
<div <div
id="inner_wrapper" id="inner_wrapper"
tabIndex="-1"
className={classNames( className={classNames(
'fixed overflow-auto w-full h-full', 'fixed overflow-auto w-full h-full',
backgroundBlur && `backdrop-blur${initialSettings.background.blur.length ? '-' : ""}${initialSettings.background.blur}`, backgroundBlur && `backdrop-blur${initialSettings.background.blur.length ? '-' : ""}${initialSettings.background.blur}`,

Some files were not shown because too many files have changed in this diff Show More