Compare commits

..

110 Commits

Author SHA1 Message Date
shamoon
8ec488efbd Revert "Fix: subdirectory deployment (#2205)"
This revers commit b8eda91005
2023-10-18 11:44:26 -07:00
shamoon
9e3bc8e64f Update prettier package to v3 2023-10-18 09:49:33 -07:00
shamoon
29827b1c70 Add pre-commit to ci 2023-10-18 09:49:33 -07:00
shamoon
f48cf0dc9f Add instructions to dev docs for pre-commit 2023-10-18 09:49:33 -07:00
shamoon
19c25713c4 Run pre-commit hooks over existing codebase
Co-Authored-By: Ben Phelps <ben@phelps.io>
2023-10-18 09:49:33 -07:00
shamoon
fa50bbad9c Add pre-commit with prettier 2023-10-18 09:49:33 -07:00
Ben Phelps
8e6a169b50 New translations common.json (German) (#2208) 2023-10-18 09:00:58 -07:00
shamoon
4248db7f21 k8s: Support app ingress annotation (#2198) 2023-10-18 08:57:10 -07:00
Isidro Osoria
b8eda91005 Fix: subdirectory deployment (#2205) 2023-10-18 08:49:42 -07:00
Ben Phelps
5f7891d8db New translations common.json (French) (#2206) 2023-10-17 23:29:26 -07:00
Ben Phelps
b14abc2642 New Crowdin updates (#2144)
* New translations common.json (Dutch)

* New translations common.json (Dutch)

* New translations common.json (Polish)

* New translations common.json (Danish)

* New translations common.json (French)

* New translations common.json (German)

* New translations common.json (Chinese Simplified)

* New translations common.json (Chinese Simplified)

* New translations common.json (Dutch)

* New translations common.json (Dutch)

* New translations common.json (German)

* New translations common.json (German)

* New translations common.json (German)

* New translations common.json (Spanish)

* New translations common.json (Danish)

* New translations common.json (Italian)

* New translations common.json (Dutch)

* New translations common.json (Dutch)

* New translations common.json (Japanese)

* New translations common.json (Japanese)
2023-10-17 22:55:01 -07:00
icyleaf
8ea2ccf110 Enhancement: support dot-notated field properties in docker labels (#2195) 2023-10-17 22:54:17 -07:00
shamoon
cbad95bf9c Fix dot status when exited (#2204) 2023-10-17 17:47:51 -07:00
shamoon
47db8be7bb Fix glances network calculation (#2201) 2023-10-17 13:31:02 -07:00
Preetham Kulai
2f4985b977 Enhancement: mjpeg stream widget placeholder image (#2192)
* added placeholder image on stream load error

* updated placeholder image to tv static animation

* Revert "updated placeholder image to tv static animation"

This reverts commit f0efdd8833.

* Inline animated tv static image

---------

Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
2023-10-16 13:12:28 -07:00
karpaterna
8d34dc5725 Documentation: add defaultinterval option for coinmarketcap (#2191) 2023-10-15 10:09:48 -07:00
shamoon
31c33f4f32 Specify src in jsconfig 2023-10-14 12:44:37 -07:00
shamoon
ef3e98285e Fix references to podSelector in k8s manifests (#2187) 2023-10-13 19:34:19 -07:00
smoothlystable
e012ea6050 Changedetection.io: Skip checking for diff if watch never had a change (#2186)
* Only check diff in there has ever been a change

* Code style

---------

Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
2023-10-13 09:02:36 -07:00
Ado Nishimura
dcc2f3e8f3 Fix: proxmox CPU/MEM NaN when cluster has offline nodes (#2185) 2023-10-13 03:49:16 -07:00
shamoon
94718db22b Fix troubleshooting indentation 2023-10-12 13:12:11 -07:00
shamoon
c591049a1a Fix glances doc image assets 2023-10-12 11:53:15 -07:00
shamoon
fd04e93d68 Update k8s deployment with specific files (#2178) 2023-10-12 08:35:08 -07:00
patopesto
29b7d5756c Fix: possible sonarr widget queue duplicates (#2171) 2023-10-09 21:05:29 -07:00
shamoon
596e5c9b84 Fix glances fs metric for disks with colon (#2170) 2023-10-09 19:43:03 -07:00
shamoon
7ea1d0dd47 Fix calculation for docker container memory usage (#2167) 2023-10-08 10:26:20 -07:00
shamoon
4a04347518 Update README.md 2023-10-08 07:22:43 -07:00
shamoon
7bbb35db13 Update README.md 2023-10-08 06:46:20 -07:00
shamoon
d1d81e5753 Fix: emby / jellyfin isVideoDirect (#2156) 2023-10-07 20:58:05 -07:00
shamoon
4c2ecb9b0e Add hdhomerun 2023-10-06 21:01:37 -07:00
Ben Phelps
1066d17f70 Update translations.md (#2142)
Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
2023-10-06 13:16:20 +00:00
shamoon
462a8e001f Change weblate links to crowdin 2023-10-06 00:04:51 -07:00
Ben Phelps
0eab49a449 New translations common.json (Yue) (#2132) 2023-10-05 23:56:05 +00:00
shamoon
24121cd5f0 run ci on merge_group 2023-10-05 15:17:05 -07:00
Lavender Shannon
8aeded4774 Update gluetun.md (#2137)
Fixed link to control server documentation
2023-10-05 22:14:37 +00:00
Denis Papec
40522fbb96 Fix: Quicklaunch shows also services without a url (#2136)
* Fix: Quicklaunch show only services with a link

Signed-off-by: Denis Papec <denis.papec@gmail.com>

* Revert "Fix: Quicklaunch show only services with a link"

This reverts commit 30ee825611.

* Filter only bookmarks and services with href

---------

Signed-off-by: Denis Papec <denis.papec@gmail.com>
Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
2023-10-05 22:14:25 +00:00
Ben Phelps
76cbb6e2ed Revert "New Crowdin updates (#2124)" (#2131)
This reverts commit b29c0f809c.
2023-10-05 10:02:01 -07:00
Ben Phelps
b29c0f809c New Crowdin updates (#2124) 2023-10-05 09:49:10 -07:00
shamoon
4f41be512c Include tailwind bg-black/white, greedy ping regex, adjust position 2023-10-05 09:28:43 -07:00
shamoon
b765330b4a Fix: dot visibility in some cases, translation strings (#2129) 2023-10-05 07:19:20 -07:00
Ben Phelps
ed3055ae1b Update Crowdin configuration file 2023-10-05 11:19:02 +03:00
Ben Phelps
5460f89cc9 Update Crowdin configuration file 2023-10-05 11:07:44 +03:00
Ben Phelps
29018873f5 Update Crowdin configuration file 2023-10-05 10:37:26 +03:00
Anonymous
11cacfb823 Translated using Weblate (Basque)
Currently translated at 6.2% (34 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/eu/
2023-10-05 09:29:21 +02:00
Anonymous
eddec4adc2 Translated using Weblate (Indonesian)
Currently translated at 4.4% (24 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/id/
2023-10-05 09:29:21 +02:00
Anonymous
2faf51b4c0 Translated using Weblate (Slovenian)
Currently translated at 95.9% (521 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/sl/
2023-10-05 09:29:21 +02:00
Anonymous
891c387062 Translated using Weblate (Greek)
Currently translated at 33.3% (181 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/el/
2023-10-05 09:29:21 +02:00
Anonymous
3b2b6cc064 Translated using Weblate (Korean)
Currently translated at 31.8% (173 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ko/
2023-10-05 09:29:20 +02:00
Anonymous
83a5d1b17a Translated using Weblate (Slovak)
Currently translated at 23.7% (129 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/sk/
2023-10-05 09:29:20 +02:00
Anonymous
29b0240abd Translated using Weblate (Thai)
Currently translated at 8.8% (48 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/th/
2023-10-05 09:29:20 +02:00
Anonymous
8ad1f9f422 Translated using Weblate (Latvian)
Currently translated at 21.7% (118 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/lv/
2023-10-05 09:29:20 +02:00
Anonymous
ea15a1b9e5 Translated using Weblate (Japanese)
Currently translated at 93.1% (506 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ja/
2023-10-05 09:29:20 +02:00
Anonymous
691ed78e75 Translated using Weblate (Ukrainian)
Currently translated at 93.1% (506 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/uk/
2023-10-05 09:29:20 +02:00
Anonymous
5f58cb285d Translated using Weblate (Esperanto)
Currently translated at 26.7% (145 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/eo/
2023-10-05 09:29:20 +02:00
Anonymous
a6696700b7 Translated using Weblate (Hindi)
Currently translated at 1.8% (10 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/hi/
2023-10-05 09:29:19 +02:00
Anonymous
985ca4ae84 Translated using Weblate (Malay)
Currently translated at 46.4% (252 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ms/
2023-10-05 09:29:19 +02:00
Anonymous
ebda0f7b70 Translated using Weblate (Danish)
Currently translated at 95.9% (521 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/da/
2023-10-05 09:29:19 +02:00
Anonymous
8e7723b51d Translated using Weblate (Czech)
Currently translated at 81.7% (444 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/cs/
2023-10-05 09:29:19 +02:00
Anonymous
24635268a0 Translated using Weblate (Arabic)
Currently translated at 48.2% (262 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ar/
2023-10-05 09:29:19 +02:00
Anonymous
729c161271 Translated using Weblate (Serbian)
Currently translated at 1.8% (10 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/sr/
2023-10-05 09:29:19 +02:00
Anonymous
69af86eebe Translated using Weblate (Turkish)
Currently translated at 72.3% (393 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/tr/
2023-10-05 09:29:18 +02:00
Anonymous
369a996f1f Translated using Weblate (Bulgarian)
Currently translated at 14.9% (81 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/bg/
2023-10-05 09:29:18 +02:00
Anonymous
b7b63abee0 Translated using Weblate (Telugu)
Currently translated at 39.7% (216 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/te/
2023-10-05 09:29:18 +02:00
Anonymous
4ba47c426a Translated using Weblate (Finnish)
Currently translated at 32.5% (177 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fi/
2023-10-05 09:29:17 +02:00
Anonymous
29d54b032c Translated using Weblate (Yue (Traditional))
Currently translated at 21.7% (118 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/yue_Hant/
2023-10-05 09:29:17 +02:00
Anonymous
8791aa8d0d Translated using Weblate (Portuguese (Brazil))
Currently translated at 84.8% (461 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pt_BR/
2023-10-05 09:29:17 +02:00
Anonymous
337ada148c Translated using Weblate (Romanian)
Currently translated at 28.7% (156 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ro/
2023-10-05 09:29:17 +02:00
Anonymous
2c8348f5b5 Translated using Weblate (Hebrew)
Currently translated at 18.6% (101 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/he/
2023-10-05 09:29:17 +02:00
Anonymous
0eeaa99fe3 Translated using Weblate (Hungarian)
Currently translated at 86.7% (471 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/hu/
2023-10-05 09:29:16 +02:00
Anonymous
38d2cc7bd7 Translated using Weblate (Croatian)
Currently translated at 86.5% (470 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/hr/
2023-10-05 09:29:16 +02:00
Anonymous
759dc9f3d2 Translated using Weblate (Swedish)
Currently translated at 24.3% (132 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/sv/
2023-10-05 09:29:16 +02:00
Anonymous
72d9a614fd Translated using Weblate (Polish)
Currently translated at 68.8% (374 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pl/
2023-10-05 09:29:16 +02:00
Anonymous
3d209bf572 Translated using Weblate (Catalan)
Currently translated at 48.0% (261 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ca/
2023-10-05 09:29:16 +02:00
Anonymous
3268db1298 Translated using Weblate (Chinese (Traditional))
Currently translated at 98.3% (534 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hant/
2023-10-05 09:29:16 +02:00
Anonymous
ab4a28d04a Translated using Weblate (Dutch)
Currently translated at 98.3% (534 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nl/
2023-10-05 09:29:15 +02:00
Anonymous
3c1644e18f Translated using Weblate (Vietnamese)
Currently translated at 8.2% (45 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/vi/
2023-10-05 09:29:15 +02:00
Anonymous
e1f6ddaeab Translated using Weblate (Norwegian Bokmål)
Currently translated at 14.9% (81 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nb_NO/
2023-10-05 09:29:15 +02:00
Anonymous
826bad8ff4 Translated using Weblate (Italian)
Currently translated at 99.4% (540 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/it/
2023-10-05 09:29:15 +02:00
Anonymous
8aa2bbcdd3 Translated using Weblate (Chinese (Simplified))
Currently translated at 82.8% (450 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hans/
2023-10-05 09:29:15 +02:00
Anonymous
aece2954df Translated using Weblate (Russian)
Currently translated at 79.1% (430 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ru/
2023-10-05 09:29:15 +02:00
Anonymous
5fbdbce79c Translated using Weblate (Portuguese)
Currently translated at 76.4% (415 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pt/
2023-10-05 09:29:14 +02:00
Anonymous
ce2bfd9d21 Translated using Weblate (French)
Currently translated at 99.6% (541 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2023-10-05 09:29:14 +02:00
Anonymous
df4cc6086c Translated using Weblate (Spanish)
Currently translated at 99.6% (541 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2023-10-05 09:29:14 +02:00
Anonymous
2c632e2b3e Translated using Weblate (German)
Currently translated at 99.0% (538 of 543 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/de/
2023-10-05 09:29:14 +02:00
shamoon
6de20f0ab6 Update homepage-move.md 2023-10-05 00:26:41 -07:00
shamoon
7434d597c9 Update migration docs 2023-10-05 00:22:51 -07:00
shamoon
59dbc79656 Remove deprecated notification 2023-10-04 23:55:03 -07:00
shamoon
b475f89d85 Migrate more URLs 2023-10-04 23:24:59 -07:00
shamoon
7f9ae3d01b Updating more repo URLs 2023-10-04 23:15:59 -07:00
shamoon
b12d27551a Update repo in docs 2023-10-04 23:12:53 -07:00
shamoon
3cf88d290f Merge branch 'feature-move-notification' 2023-10-04 22:47:11 -07:00
shamoon
9f030d1540 Update ping.jsx 2023-10-04 22:46:31 -07:00
shamoon
e8f6d81d13 Update ping.jsx 2023-10-04 22:37:53 -07:00
shamoon
571f627b3b Enhancement: statusStyle improvements (#2119) 2023-10-04 22:12:57 -07:00
shamoon
861ab32ca3 Update links 2023-10-03 18:55:02 -07:00
shamoon
aa5d24b9e4 Support notification re deprecated repo 2023-10-03 16:17:17 -07:00
shamoon
7adfe2ffd9 Documentation: correct ping statusStyle info 2023-10-01 01:54:06 -07:00
しぐれ
f8d2bb8611 Documentation: remove extra Service Widgets section (#2096) 2023-10-01 01:54:06 -07:00
Gino Cicatiello
892ebb8bd9 Translated using Weblate (Italian)
Currently translated at 99.8% (540 of 541 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/it/
2023-10-01 01:54:06 -07:00
Nonoss117
456fe6afc2 Translated using Weblate (French)
Currently translated at 100.0% (541 of 541 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2023-10-01 01:54:06 -07:00
Antonio Sanchez Castellón
ce3fb1abc1 Translated using Weblate (Spanish)
Currently translated at 100.0% (541 of 541 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2023-10-01 01:54:06 -07:00
shamoon
a1e023e240 CI: filter ci by paths, docs ci test vs build, update PR template 2023-10-01 01:54:06 -07:00
Denis Papec
56f46ae85c Enhancement: go to current day when clicking calendar month name (#2091) 2023-09-30 10:01:14 -07:00
Denis Papec
67ebe29db7 Skip workflows if it is fork (#2092)
Signed-off-by: Denis Papec <denis.papec@gmail.com>
2023-09-30 09:59:41 -07:00
Nagy László Zoltán
0c2671ea00 Update services/glances.md with correct info/glances link (#2087) 2023-09-30 07:27:12 -07:00
Ben Phelps
7a6470381b update build for insiders 2023-09-30 15:06:56 +03:00
Ben Phelps
86d3fc4fbb enable social cards, allow building docs without insiders 2023-09-30 15:06:25 +03:00
Ben Phelps
ceeb007ca0 ignore mkdocs cache 2023-09-30 14:39:51 +03:00
shamoon
87113eaac4 Add social icons to footer 2023-09-29 22:38:17 -07:00
shamoon
25cd09a117 Update .gitignore 2023-09-29 17:02:18 -07:00
454 changed files with 9530 additions and 7599 deletions

View File

@@ -11,13 +11,13 @@ body:
- type: markdown - type: markdown
attributes: attributes:
value: | value: |
Have a question? 👉 [Start a new discussion](https://github.com/benphelps/homepage/discussions/new) or [ask in chat](https://discord.gg/SaPGSzrEZC). Have a question? 👉 [Start a new discussion](https://github.com/gethomepage/homepage/discussions/new) or [ask in chat](https://discord.gg/SaPGSzrEZC).
Before opening an issue, please double check: Before opening an issue, please double check:
- [The troubleshooting guide](https://gethomepage.dev/en/more/troubleshooting/). - [The troubleshooting guide](https://gethomepage.dev/latest/more/troubleshooting/).
- [The homepage documentation](https://gethomepage.dev/) - [The homepage documentation](https://gethomepage.dev/)
- [Existing issues](https://github.com/benphelps/homepage/search?q=&type=issues) and [discussions](https://github.com/benphelps/homepage/search?q=&type=discussions). - [Existing issues](https://github.com/gethomepage/homepage/search?q=&type=issues) and [discussions](https://github.com/gethomepage/homepage/search?q=&type=discussions).
- type: textarea - type: textarea
id: description id: description
attributes: attributes:
@@ -78,7 +78,7 @@ body:
id: troubleshooting id: troubleshooting
attributes: attributes:
label: Troubleshooting label: Troubleshooting
description: Please include output from your [troubleshooting tests](https://gethomepage.dev/en/more/troubleshooting/#service-widget-errors). If this is a service widget issue and you do not include any information here your issue will be closed. If it is not, indicate e.g. 'n/a' description: Please include output from your [troubleshooting tests](https://gethomepage.dev/latest/more/troubleshooting/#service-widget-errors). If this is a service widget issue and you do not include any information here your issue will be closed. If it is not, indicate e.g. 'n/a'
validations: validations:
required: true required: true
- type: textarea - type: textarea
@@ -93,7 +93,7 @@ body:
options: options:
- label: Check [the documentation](https://gethomepage.dev/) - label: Check [the documentation](https://gethomepage.dev/)
required: true required: true
- label: Follow [the troubleshooting guide](https://gethomepage.dev/en/more/troubleshooting/) (please include output above if applicable). - label: Follow [the troubleshooting guide](https://gethomepage.dev/latest/more/troubleshooting/) (please include output above if applicable).
required: true required: true
- label: Search [existing issues](https://github.com/benphelps/homepage/search?q=&type=issues) and [discussions](https://github.com/benphelps/homepage/search?q=&type=discussions). - label: Search [existing issues](https://github.com/gethomepage/homepage/search?q=&type=issues) and [discussions](https://github.com/gethomepage/homepage/search?q=&type=discussions).
required: true required: true

View File

@@ -1,11 +1,11 @@
blank_issues_enabled: false blank_issues_enabled: false
contact_links: contact_links:
- name: 🤔 Questions and Help - name: 🤔 Questions and Help
url: https://github.com/benphelps/homepage/discussions url: https://github.com/gethomepage/homepage/discussions
about: This issue tracker is for bugs only, not general support questions. Please refer to our Discussions. about: This issue tracker is for bugs only, not general support questions. Please refer to our Discussions.
- name: 💬 Chat - name: 💬 Chat
url: https://discord.gg/k4ruYNrudu url: https://discord.gg/k4ruYNrudu
about: Want to discuss homepage with others? Check out our chat. about: Want to discuss homepage with others? Check out our chat.
- name: 🚀 Feature Request - name: 🚀 Feature Request
url: https://github.com/benphelps/homepage/discussions/new?category=feature-requests url: https://github.com/gethomepage/homepage/discussions/new?category=feature-requests
about: Remember to search for existing feature requests and "up-vote" any you like about: Remember to search for existing feature requests and "up-vote" any you like

View File

@@ -3,10 +3,10 @@
<!-- <!--
Please include a summary of the change. Screenshots and / or videos can also be helpful if appropriate. Please include a summary of the change. Screenshots and / or videos can also be helpful if appropriate.
*** Please see the development guidelines for new widgets: https://gethomepage.dev/en/more/development/#service-widget-guidelines *** Please see the development guidelines for new widgets: https://gethomepage.dev/latest/more/development/#service-widget-guidelines
*** If you do not follow these guidelines your PR will likely be closed without review. *** If you do not follow these guidelines your PR will likely be closed without review.
New service widgets should include example(s) of relevant relevant API output as well as a PR to the docs for the new widget. New service widgets should include example(s) of relevant relevant API output as well updates to the docs for the new widget.
--> -->
Closes # (issue) Closes # (issue)
@@ -20,11 +20,12 @@ What type of change does your PR introduce to Homepage?
- [ ] New service widget - [ ] New service widget
- [ ] Bug fix (non-breaking change which fixes an issue) - [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality) - [ ] New feature (non-breaking change which adds functionality)
- [ ] Documentation only
- [ ] Other (please explain) - [ ] Other (please explain)
## Checklist: ## Checklist:
- [ ] If adding a service widget or a change that requires it, I have added corresponding documentation. - [ ] If adding a service widget or a change that requires it, I have added corresponding documentation changes.
- [ ] If adding a new widget I have reviewed the [guidelines](https://gethomepage.dev/en/more/development/#service-widget-guidelines). - [ ] If adding a new widget I have reviewed the [guidelines](https://gethomepage.dev/latest/more/development/#service-widget-guidelines).
- [ ] If applicable, I have checked that all tests pass with e.g. `pnpm lint`. - [ ] I have checked that all code style checks pass using pre-commit hooks and linting checks with `pnpm lint` (see development guidelines).
- [ ] If applicable, I have tested my code for new features & regressions on both mobile & desktop devices, using the latest version of major browsers. - [ ] If applicable, I have tested my code for new features & regressions on both mobile & desktop devices, using the latest version of major browsers.

View File

@@ -12,8 +12,15 @@ on:
branches: [ "main" ] branches: [ "main" ]
# Publish semver tags as releases. # Publish semver tags as releases.
tags: [ 'v*.*.*' ] tags: [ 'v*.*.*' ]
paths-ignore:
- 'docs/**'
- 'mkdocs.yml'
pull_request: pull_request:
branches: [ "main" ] branches: [ "main" ]
paths-ignore:
- 'docs/**'
- 'mkdocs.yml'
merge_group:
env: env:
# Use docker.io for Docker Hub if empty # Use docker.io for Docker Hub if empty
@@ -23,9 +30,28 @@ env:
jobs: jobs:
build: pre-commit:
name: Linting Checks
runs-on: ubuntu-22.04
steps:
-
name: Checkout repository
uses: actions/checkout@v4
-
name: Install python
uses: actions/setup-python@v4
with:
python-version: 3.x
-
name: Check files
uses: pre-commit/action@v3.0.0
build:
name: Docker Build & Push
if: github.repository == 'gethomepage/homepage'
runs-on: self-hosted runs-on: self-hosted
needs:
- pre-commit
permissions: permissions:
contents: read contents: read
packages: write packages: write

View File

@@ -4,14 +4,65 @@ on:
push: push:
tags: [ 'v*.*.*' ] tags: [ 'v*.*.*' ]
branches: ['main'] branches: ['main']
paths:
- 'docs/**'
- 'mkdocs.yml'
pull_request:
paths:
- 'docs/**'
- 'mkdocs.yml'
merge_group:
workflow_dispatch: workflow_dispatch:
permissions: permissions:
contents: write contents: write
jobs: jobs:
deploy: pre-commit:
name: Linting Checks
runs-on: ubuntu-22.04
steps:
-
name: Checkout repository
uses: actions/checkout@v4
-
name: Install python
uses: actions/setup-python@v4
with:
python-version: 3.x
-
name: Check files
uses: pre-commit/action@v3.0.0
test:
name: Test Build
if: github.repository == 'gethomepage/homepage' && github.event_name == 'pull_request'
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs:
- pre-commit
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version: 3.x
- run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
- uses: actions/cache@v3
with:
key: mkdocs-material-${{ env.cache_id }}
path: .cache
restore-keys: |
mkdocs-material-
- run: sudo apt-get install pngquant
- run: pip install mike
- run: pip install mkdocs-material
- name: Test Docs Build
run: MKINSIDERS=false mkdocs build
deploy:
name: Build & Deploy
if: github.repository == 'gethomepage/homepage' && github.event_name != 'pull_request'
runs-on: ubuntu-latest
needs:
- pre-commit
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:
@@ -39,11 +90,11 @@ jobs:
git checkout gh-pages git checkout gh-pages
git pull origin gh-pages git pull origin gh-pages
git checkout main git checkout main
- name: Mike Deploy for Main - name: Docs Deploy for Main
if: github.ref == 'refs/heads/main' if: github.ref == 'refs/heads/main'
run: mike deploy --update --push ${{github.ref_name}} run: MKINSIDERS=true mike deploy --update --push ${{github.ref_name}}
- name: Mike Deploy for Tags - name: Docs Deploy for Tags
if: github.ref != 'refs/heads/main' if: github.ref != 'refs/heads/main'
run: mike deploy --update --push ${{github.ref_name}} latest run: MKINSIDERS=true mike deploy --update --push ${{github.ref_name}} latest
env: env:
GH_TOKEN: ${{ secrets.GH_TOKEN }} GH_TOKEN: ${{ secrets.GH_TOKEN }}

4
.gitignore vendored
View File

@@ -48,3 +48,7 @@ next-env.d.ts
# MkDocs documentation # MkDocs documentation
site*/ site*/
.cache/
# venv
.venv/

19
.pre-commit-config.yaml Normal file
View File

@@ -0,0 +1,19 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.2.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
exclude: "(^mkdocs\\.yml$)"
- id: check-added-large-files
- repo: https://github.com/pre-commit/mirrors-prettier
rev: 'v3.0.3'
hooks:
- id: prettier
types_or:
- javascript
- markdown
- jsx

1
.prettierrc Normal file
View File

@@ -0,0 +1 @@
{}

View File

@@ -17,23 +17,23 @@ diverse, inclusive, and healthy community.
Examples of behavior that contributes to a positive environment for our Examples of behavior that contributes to a positive environment for our
community include: community include:
* Demonstrating empathy and kindness toward other people - Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences - Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback - Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes, - Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience and learning from the experience
* Focusing on what is best not just for us as individuals, but for the - Focusing on what is best not just for us as individuals, but for the
overall community overall community
Examples of unacceptable behavior include: Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or - The use of sexualized language or imagery, and sexual attention or
advances of any kind advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks - Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment - Public or private harassment
* Publishing others' private information, such as a physical or email - Publishing others' private information, such as a physical or email
address, without their explicit permission address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a - Other conduct which could reasonably be considered inappropriate in a
professional setting professional setting
## Enforcement Responsibilities ## Enforcement Responsibilities

View File

@@ -1,4 +1,5 @@
# Contributing to Homepage # Contributing to Homepage
We love your input! We want to make contributing to this project as easy and transparent as possible, whether it's: We love your input! We want to make contributing to this project as easy and transparent as possible, whether it's:
- Reporting a bug - Reporting a bug
@@ -8,15 +9,19 @@ We love your input! We want to make contributing to this project as easy and tra
- Becoming a maintainer - Becoming a maintainer
## We Develop with Github ## We Develop with Github
We use github to host code, to track issues and feature requests, as well as accept pull requests. We use github to host code, to track issues and feature requests, as well as accept pull requests.
## Any contributions you make will be under the GNU General Public License v3.0 ## Any contributions you make will be under the GNU General Public License v3.0
In short, when you submit code changes, your submissions are understood to be under the same [GNU General Public License v3.0](https://choosealicense.com/licenses/gpl-3.0/) that covers the project. Feel free to contact the maintainers if that's a concern. In short, when you submit code changes, your submissions are understood to be under the same [GNU General Public License v3.0](https://choosealicense.com/licenses/gpl-3.0/) that covers the project. Feel free to contact the maintainers if that's a concern.
## Report bugs using Github's [issues](https://github.com/benphelps/homepage/issues) ## Report bugs using Github's [issues](https://github.com/gethomepage/homepage/issues)
We use GitHub issues to track public bugs. Report a bug by [opening a new issue](https://github.com/benphelps/homepage/issues/new); it's that easy!
We use GitHub issues to track public bugs. Report a bug by [opening a new issue](https://github.com/gethomepage/homepage/issues/new); it's that easy!
## Write bug reports with detail, background, and sample configurations ## Write bug reports with detail, background, and sample configurations
Homepage includes a lot of configuration options and is often deploying in larger systems. Please include as much information (configurations, deployment method, Docker & API versions, etc) as you can when reporting an issue. Homepage includes a lot of configuration options and is often deploying in larger systems. Please include as much information (configurations, deployment method, Docker & API versions, etc) as you can when reporting an issue.
**Great Bug Reports** tend to have: **Great Bug Reports** tend to have:
@@ -29,16 +34,20 @@ Homepage includes a lot of configuration options and is often deploying in large
- What actually happens - What actually happens
- Notes (possibly including why you think this might be happening, or stuff you tried that didn't work) - Notes (possibly including why you think this might be happening, or stuff you tried that didn't work)
People *love* thorough bug reports. I'm not even kidding. People _love_ thorough bug reports. I'm not even kidding.
## Development Guidelines ## Development Guidelines
Please see the [documentation regarding development](https://gethomepage.dev/en/more/development/) and specifically the [guidelines for new service widgets](https://gethomepage.dev/en/more/development/#service-widget-guidelines) if you are considering making one.
Please see the [documentation regarding development](https://gethomepage.dev/latest/more/development/) and specifically the [guidelines for new service widgets](https://gethomepage.dev/latest/more/development/#service-widget-guidelines) if you are considering making one.
## Use a Consistent Coding Style ## Use a Consistent Coding Style
This project follows the [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript), please follow it when submitting pull requests.
Please see information in the docs regarding [code formatting with pre-commit hooks](https://gethomepage.dev/latest/more/development.md#code-formatting-with-pre-commit-hooks).
## License ## License
By contributing, you agree that your contributions will be licensed under its GNU General Public License. By contributing, you agree that your contributions will be licensed under its GNU General Public License.
## References ## References
This document was adapted from the open-source contribution guidelines for [Facebook's Draft](https://github.com/facebook/draft-js/blob/main/CONTRIBUTING.md) This document was adapted from the open-source contribution guidelines for [Facebook's Draft](https://github.com/facebook/draft-js/blob/main/CONTRIBUTING.md)

View File

@@ -36,9 +36,9 @@ RUN npm run telemetry \
FROM docker.io/node:18-alpine AS runner FROM docker.io/node:18-alpine AS runner
LABEL org.opencontainers.image.title "Homepage" LABEL org.opencontainers.image.title "Homepage"
LABEL org.opencontainers.image.description "A self-hosted services landing page, with docker and service integrations." LABEL org.opencontainers.image.description "A self-hosted services landing page, with docker and service integrations."
LABEL org.opencontainers.image.url="https://github.com/benphelps/homepage" LABEL org.opencontainers.image.url="https://github.com/gethomepage/homepage"
LABEL org.opencontainers.image.documentation='https://github.com/benphelps/homepage/wiki' LABEL org.opencontainers.image.documentation='https://github.com/gethomepage/homepage/wiki'
LABEL org.opencontainers.image.source='https://github.com/benphelps/homepage' LABEL org.opencontainers.image.source='https://github.com/gethomepage/homepage'
LABEL org.opencontainers.image.licenses='Apache-2.0' LABEL org.opencontainers.image.licenses='Apache-2.0'
ENV NODE_ENV production ENV NODE_ENV production

View File

@@ -14,12 +14,14 @@
</p> </p>
<p align="center"> <p align="center">
<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> <a href="https://github.com/gethomepage/homepage/actions/workflows/docker-publish.yml"><img alt="GitHub Workflow Status (with event)" src="https://img.shields.io/github/actions/workflow/status/gethomepage/homepage/docker-publish.yml"></a>
&nbsp; &nbsp;
<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://crowdin.com/project/gethomepage" target="_blank"><img src="https://badges.crowdin.net/gethomepage/localized.svg"></a>
&nbsp; &nbsp;
<a href="https://discord.gg/k4ruYNrudu"><img alt="Discord" src="https://img.shields.io/discord/1019316731635834932"></a> <a href="https://discord.gg/k4ruYNrudu"><img alt="Discord" src="https://img.shields.io/discord/1019316731635834932"></a>
&nbsp; &nbsp;
<a href="http://gethomepage.dev/latest/" title="Docs"><img title="Docs" src="https://github.com/gethomepage/homepage/actions/workflows/docs-publish.yml/badge.svg"/></a>
&nbsp;
<a href="https://paypal.me/phelpsben" title="Donate"><img alt="GitHub Sponsors" src="https://img.shields.io/github/sponsors/benphelps"></a> <a href="https://paypal.me/phelpsben" title="Donate"><img alt="GitHub Sponsors" src="https://img.shields.io/github/sponsors/benphelps"></a>
</p> </p>
@@ -39,19 +41,19 @@ With features like quick search, bookmarks, weather support, a wide range of int
## Docker Integration ## Docker Integration
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. 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/latest/installation/docker/) page for more information.
## Service Widgets ## Service Widgets
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. 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/latest/configs/service-widgets/) page for more information.
## Information Widgets ## 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. 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/latest/configs/widgets/) page for more information.
## Customization ## 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. Homepage is highly customizable, with support for custom themes, custom CSS & JS, custom layouts, formatting, localization and more. See the [Settings](https://gethomepage.dev/latest/configs/settings/) page for more information.
# Getting Started # Getting Started
@@ -65,7 +67,7 @@ Using docker compose:
version: "3.3" version: "3.3"
services: services:
homepage: homepage:
image: ghcr.io/benphelps/homepage:latest image: ghcr.io/gethomepage/homepage:latest
container_name: homepage container_name: homepage
environment: environment:
PUID: 1000 -- optional, your user id PUID: 1000 -- optional, your user id
@@ -88,7 +90,7 @@ docker run --name homepage \
-v /path/to/config:/app/config \ -v /path/to/config:/app/config \
-v /var/run/docker.sock:/var/run/docker.sock:ro \ -v /var/run/docker.sock:/var/run/docker.sock:ro \
--restart unless-stopped \ --restart unless-stopped \
ghcr.io/benphelps/homepage:latest ghcr.io/gethomepage/homepage:latest
``` ```
## With Node ## With Node
@@ -96,7 +98,7 @@ docker run --name homepage \
First, clone the repository: First, clone the repository:
```bash ```bash
git clone https://github.com/benphelps/homepage.git git clone https://github.com/gethomepage/homepage.git
``` ```
Then install dependencies and build the production bundle (I'm using pnpm here, you can use npm or yarn if you like): Then install dependencies and build the production bundle (I'm using pnpm here, you can use npm or yarn if you like):
@@ -122,7 +124,7 @@ pnpm dev
# Configuration # Configuration
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. Please refer 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
@@ -144,6 +146,8 @@ This is a [Next.js](https://nextjs.org/) application, see their documentation fo
# Documentation # Documentation
The homepage documentation is available at [https://gethomepage.dev/](https://gethomepage.dev/).
Homepage uses Material for MkDocs for documentation. To run the documentation locally, first install the dependencies: Homepage uses Material for MkDocs for documentation. To run the documentation locally, first install the dependencies:
```bash ```bash
@@ -158,9 +162,9 @@ mkdocs serve # or build, to build the static site
# Support & Suggestions # Support & Suggestions
If you have any questions, suggestions, or general issues, please start a discussion on the [Discussions](https://github.com/benphelps/homepage/discussions) page. If you have any questions, suggestions, or general issues, please start a discussion on the [Discussions](https://github.com/gethomepage/homepage/discussions) page.
For bug reports, please open an issue on the [Issues](https://github.com/benphelps/homepage/issues) page. For bug reports, please open an issue on the [Issues](https://github.com/gethomepage/homepage/issues) page.
## Contributing & Contributers ## Contributing & Contributers

3
crowdin.yml Normal file
View File

@@ -0,0 +1,3 @@
files:
- source: /public/locales/en/*.json
translation: /public/locales/%osx_locale%/%original_file_name%

View File

@@ -49,7 +49,7 @@ dockerproxy:
restart: unless-stopped restart: unless-stopped
homepage: homepage:
image: ghcr.io/benphelps/homepage:latest image: ghcr.io/gethomepage/homepage:latest
container_name: homepage container_name: homepage
volumes: volumes:
- /path/to/config:/app/config - /path/to/config:/app/config
@@ -76,7 +76,7 @@ If you'd rather use the socket directly, first make sure that you're passing the
```yaml ```yaml
homepage: homepage:
image: ghcr.io/benphelps/homepage:latest image: ghcr.io/gethomepage/homepage:latest
container_name: homepage container_name: homepage
volumes: volumes:
- /path/to/config:/app/config - /path/to/config:/app/config
@@ -153,6 +153,23 @@ labels:
- homepage.widget.fields=["field1","field2"] # optional - homepage.widget.fields=["field1","field2"] # optional
``` ```
You can add specify fields for e.g. the [CustomAPI](/widgets/services/customapi) widget by using array-style dot notation:
```yaml
labels:
- homepage.group=Media
- homepage.name=Emby
- homepage.icon=emby.png
- homepage.href=http://emby.home/
- homepage.description=Media server
- homepage.widget.type=customapi
- homepage.widget.url=http://argus.service/api/v1/service/summary/emby
- homepage.widget.field[0].label=Deployed Version
- homepage.widget.field[0].field.status=deployed_version
- homepage.widget.field[1].label=Latest Version
- homepage.widget.field[1].field.status=latest_version
```
## Docker Swarm ## Docker Swarm
Docker swarm is supported and Docker services are specified with the same `server` and `container` notation. To enable swarm support you will need to include a `swarm` setting in your docker.yaml, e.g. Docker swarm is supported and Docker services are specified with the same `server` and `container` notation. To enable swarm support you will need to include a `swarm` setting in your docker.yaml, e.g.

View File

@@ -36,7 +36,7 @@ Inside of the service you'd like to connect to a pod:
The `app` field is used to create a label selector, in this example case it would match pods with the label: `app.kubernetes.io/name=emby`. The `app` field is used to create a label selector, in this example case it would match pods with the label: `app.kubernetes.io/name=emby`.
Sometimes this is insufficient for complex or atypical application deployments. In these cases, the `podSelector` field can be used. Any field selector can be used with it, so it allows for some very powerful selection capabilities. Sometimes this is insufficient for complex or atypical application deployments. In these cases, the `pod-selector` field can be used. Any field selector can be used with it, so it allows for some very powerful selection capabilities.
For instance, it can be utilized to roll multiple underlying deployments under one application to see a high-level aggregate: For instance, it can be utilized to roll multiple underlying deployments under one application to see a high-level aggregate:
@@ -47,7 +47,7 @@ For instance, it can be utilized to roll multiple underlying deployments under o
description: Matrix Synapse Powered Chat description: Matrix Synapse Powered Chat
app: matrix-element app: matrix-element
namespace: comms namespace: comms
podSelector: >- pod-selector: >-
app.kubernetes.io/instance in ( app.kubernetes.io/instance in (
matrix-element, matrix-element,
matrix-media-repo, matrix-media-repo,
@@ -58,7 +58,7 @@ For instance, it can be utilized to roll multiple underlying deployments under o
!!! note !!! note
A blank string as a podSelector does not deactivate it, but will actually select all pods in the namespace. This is a useful way to capture the resource usage of a complex application siloed to a single namespace, like Longhorn. A blank string as a pod-selector does not deactivate it, but will actually select all pods in the namespace. This is a useful way to capture the resource usage of a complex application siloed to a single namespace, like Longhorn.
## Automatic Service Discovery ## Automatic Service Discovery
@@ -77,7 +77,7 @@ metadata:
gethomepage.dev/name: Emby gethomepage.dev/name: Emby
gethomepage.dev/widget.type: "emby" gethomepage.dev/widget.type: "emby"
gethomepage.dev/widget.url: "https://emby.example.com" gethomepage.dev/widget.url: "https://emby.example.com"
gethomepage.dev/podSelector: "" gethomepage.dev/pod-selector: ""
gethomepage.dev/weight: 10 # optional gethomepage.dev/weight: 10 # optional
spec: spec:
rules: rules:
@@ -110,10 +110,11 @@ metadata:
gethomepage.dev/description: Media Server gethomepage.dev/description: Media Server
gethomepage.dev/group: Media gethomepage.dev/group: Media
gethomepage.dev/icon: emby.png gethomepage.dev/icon: emby.png
gethomepage.dev/app: emby-app # optional, may be needed if app.kubernetes.io/name != ingress metadata.name
gethomepage.dev/name: Emby gethomepage.dev/name: Emby
gethomepage.dev/widget.type: "emby" gethomepage.dev/widget.type: "emby"
gethomepage.dev/widget.url: "https://emby.example.com" gethomepage.dev/widget.url: "https://emby.example.com"
gethomepage.dev/podSelector: "" gethomepage.dev/pod-selector: ""
gethomepage.dev/weight: 10 # optional gethomepage.dev/weight: 10 # optional
spec: spec:
entryPoints: entryPoints:

View File

@@ -121,11 +121,9 @@ Services may have an optional `ping` property that allows you to monitor the ava
ping: http://some.other.host/ ping: http://some.other.host/
``` ```
<img width="1038" alt="Ping" src="https://github.com/benphelps/homepage/assets/88257202/7bc13bd3-0d0b-44e3-888c-a20e069a3233"> <img width="1038" alt="Ping" src="https://github.com/gethomepage/homepage/assets/88257202/7bc13bd3-0d0b-44e3-888c-a20e069a3233">
You can also apply different styles to the ping indicator by using the `statusStyle` property. The default is no value, and displays the response time in ms, but you can also use `dot` or `simple`. `dot` showing a green dot for a successful ping, and `simple` showing either ONLINE or OFFLINE to match the status style of Docker containers. You can also apply different styles to the ping indicator by using the `statusStyle` property, see [settings](settings.md#status-style).
<!-- TODO: Insert images of the new status styles there -->
## Docker Integration ## Docker Integration
@@ -147,7 +145,7 @@ Services may be connected to a Docker container, either running on the local mac
container: other-container container: other-container
``` ```
<img width="1038" alt="Service Containers" src="https://github.com/benphelps/homepage/assets/88257202/4c685783-52c6-4e55-afb3-affe9baac09b"> <img width="1038" alt="Service Containers" src="https://github.com/gethomepage/homepage/assets/88257202/4c685783-52c6-4e55-afb3-affe9baac09b">
**Clicking on the status label of a service with Docker integration enabled will expand the container stats, where you can see CPU, Memory, and Network activity.** **Clicking on the status label of a service with Docker integration enabled will expand the container stats, where you can see CPU, Memory, and Network activity.**
@@ -155,7 +153,7 @@ Services may be connected to a Docker container, either running on the local mac
This can also be controlled with `showStats`. See [show docker stats](docker.md#show-docker-stats) for more information This can also be controlled with `showStats`. See [show docker stats](docker.md#show-docker-stats) for more information
<img width="1038" alt="Docker Stats Expanded" src="https://github.com/benphelps/homepage/assets/88257202/f95fd595-449e-48ae-af67-fd89618904ec"> <img width="1038" alt="Docker Stats Expanded" src="https://github.com/gethomepage/homepage/assets/88257202/f95fd595-449e-48ae-af67-fd89618904ec">
## Service Integrations ## Service Integrations

View File

@@ -380,6 +380,30 @@ or per-service (`services.yaml`) with:
If you have both set the per-service settings take precedence. If you have both set the per-service settings take precedence.
## Status Style
You can choose from the following styles for docker or k8s status and ping: `dot` or `basic`
- The default is no value, and displays the ping response time in ms and the docker / k8s container status
- `dot` shows a green dot for a successful ping or healthy status.
- `basic` shows either UP or DOWN for ping
For example:
```yaml
statusStyle: "dot"
```
or per-service (`services.yaml`) with:
```yaml
- Example Service:
...
statusStyle: 'dot'
```
If you have both set, the per-service settings take precedence.
## Hide Widget Error Messages ## Hide Widget Error Messages
Hide the visible API error messages either globally in `settings.yaml`: Hide the visible API error messages either globally in `settings.yaml`:

View File

@@ -9,7 +9,7 @@ Using docker compose:
version: "3.3" version: "3.3"
services: services:
homepage: homepage:
image: ghcr.io/benphelps/homepage:latest image: ghcr.io/gethomepage/homepage:latest
container_name: homepage container_name: homepage
ports: ports:
- 3000:3000 - 3000:3000
@@ -30,7 +30,7 @@ In the docker compose example below, the environment variables `$PUID` and `$PGI
version: "3.3" version: "3.3"
services: services:
homepage: homepage:
image: ghcr.io/benphelps/homepage:latest image: ghcr.io/gethomepage/homepage:latest
container_name: homepage container_name: homepage
ports: ports:
- 3000:3000 - 3000:3000
@@ -45,7 +45,7 @@ services:
### With Docker Run ### With 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 -p 3000:3000 -v /path/to/config:/app/config -v /var/run/docker.sock:/var/run/docker.sock ghcr.io/gethomepage/homepage:latest
``` ```
### Using Environment Secrets ### Using Environment Secrets

View File

@@ -291,17 +291,39 @@ spec:
enableServiceLinks: true enableServiceLinks: true
containers: containers:
- name: homepage - name: homepage
image: "ghcr.io/benphelps/homepage:latest" image: "ghcr.io/gethomepage/homepage:latest"
imagePullPolicy: Always imagePullPolicy: Always
ports: ports:
- name: http - name: http
containerPort: 3000 containerPort: 3000
protocol: TCP protocol: TCP
volumeMounts: volumeMounts:
- name: homepage-config - mountPath: /app/config/custom.js
mountPath: /app/config name: homepage-config
- name: logs subPath: custom.js
mountPath: /app/config/logs - mountPath: /app/config/custom.css
name: homepage-config
subPath: custom.css
- mountPath: /app/config/bookmarks.yaml
name: homepage-config
subPath: bookmarks.yaml
- mountPath: /app/config/docker.yaml
name: homepage-config
subPath: docker.yaml
- mountPath: /app/config/kubernetes.yaml
name: homepage-config
subPath: kubernetes.yaml
- mountPath: /app/config/services.yaml
name: homepage-config
subPath: services.yaml
- mountPath: /app/config/settings.yaml
name: homepage-config
subPath: settings.yaml
- mountPath: /app/config/widgets.yaml
name: homepage-config
subPath: widgets.yaml
- mountPath: /app/config/logs
name: logs
volumes: volumes:
- name: homepage-config - name: homepage-config
configMap: configMap:

View File

@@ -6,7 +6,7 @@ description: Install and run homepage from source
First, clone the repository: First, clone the repository:
```bash ```bash
git clone https://github.com/benphelps/homepage.git git clone https://github.com/gethomepage/homepage.git
``` ```
Then install dependencies and build the production bundle (I'm using pnpm here, you can use npm or yarn if you like): Then install dependencies and build the production bundle (I'm using pnpm here, you can use npm or yarn if you like):

View File

@@ -31,6 +31,15 @@ Once dependencies have been installed you can lint your code with
pnpm lint pnpm lint
``` ```
## Code formatting with pre-commit hooks
To ensure a consistent style and formatting across the project source, the project utilizes Git [`pre-commit`](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) hooks to perform some formatting and linting before a commit is allowed.
That way, everyone uses the same style and some common issues can be caught early on.
Once installed, hooks will run when you commit. If the formatting isn't quite right or a linter catches something, the commit will be rejected.
You'll need to look at the output and fix the issue. Some hooks will format failing files, so all you need to do is `git add` those files again
and retry your commit.
## Service Widget Guidelines ## Service Widget Guidelines
To ensure cohesiveness of various widgets, the following should be used as a guide for developing new widgets: To ensure cohesiveness of various widgets, the following should be used as a guide for developing new widgets:

View File

@@ -0,0 +1,8 @@
---
title: Homepage Move
description: Homepage Container Deprecation
---
As of v0.7.2 homepage migrated from benphelps/homepage to an "organization" repository located at [gethomepage/homepage](https://github.com/gethomepage/homepage/). The reason for this was to setup the project for longevity and allow for community maintenance.
Migrating your installation should be as simple as changing `image: ghcr.io/benphelps/homepage:latest` to `image: ghcr.io/gethomepage/homepage:latest`.

View File

@@ -3,12 +3,17 @@ title: Translations
description: Contributing Translations description: Contributing Translations
--- ---
Homepage is developed in English, most other supported languages are provided via Google Translate. When a i18n key is not found, the fallback language is English. Homepage is developed in English, component contributions must be in English. All translations are community provided, so a huge thanks go out to all those who have helped out so far!
## Support Translations ## Support Translations
If you'd like to lend a hand in translating Homepage into more languages, or to improve existing translations, the process is very simple. If you'd like to lend a hand in translating Homepage into more languages, or to improve existing translations, the process is very simple:
Everything can be done from a simple to use web interface here: https://hosted.weblate.org/projects/homepage/homepage/ 1. Create a free account at [Crowdin](https://crowdin.com/join)
2. Visit the [Homepage project](https://crowdin.com/project/gethomepage)
3. Select the language you'd like to translate
4. Start translating!
When creating a new language, it can take 5 to 10 minutes before you'll see translatable strings added, but the process _is_ automatic. Once the strings are added, you can then start translating them. ## Adding a new language
If you'd like to add a new language, please [create a new Discussion on Crowdin](https://crowdin.com/project/gethomepage/discussions), and we'll add it to the project.

View File

@@ -17,7 +17,7 @@ hide:
All service widgets work essentially the same, that is, homepage makes a proxied call to an API made available by that service. The majority of the time widgets don't work it is a configuration issue. Of course, sometimes things do break. Some basic steps to try: All service widgets work essentially the same, that is, homepage makes a proxied call to an API made available by that service. The majority of the time widgets don't work it is a configuration issue. Of course, sometimes things do break. Some basic steps to try:
1. Ensure that you follow the rule mentioned on https://gethomepage.dev/en/configs/service-widgets/. **Unless otherwise noted, URLs should not end with a / or other API path. Each widget will handle the path on its own.**. This is very important as including a trailing slash can result in an error. 1. Ensure that you follow the rule mentioned on https://gethomepage.dev/latest/configs/service-widgets/. **Unless otherwise noted, URLs should not end with a / or other API path. Each widget will handle the path on its own.**. This is very important as including a trailing slash can result in an error.
2. Verify the homepage installation can connect to the IP address or host you are using for the widget `url`. This is most simply achieved by pinging the server from the homepage machine, in Docker this means _from inside the container_ itself, e.g.: 2. Verify the homepage installation can connect to the IP address or host you are using for the widget `url`. This is most simply achieved by pinging the server from the homepage machine, in Docker this means _from inside the container_ itself, e.g.:
@@ -29,7 +29,9 @@ All service widgets work essentially the same, that is, homepage makes a proxied
3. If you have verified that homepage can in fact reach the service then you can also check the API output using e.g. `curl`, which is often helpful if you do need to file a bug report. Again, depending on your networking setup this may need to be run from _inside the container_ as IP / hostname resolution can differ inside vs outside. 3. If you have verified that homepage can in fact reach the service then you can also check the API output using e.g. `curl`, which is often helpful if you do need to file a bug report. Again, depending on your networking setup this may need to be run from _inside the container_ as IP / hostname resolution can differ inside vs outside.
_Note: `curl` is not installed in the base image by default but can be added inside the container with `apk add curl`._ !!! note
`curl` is not installed in the base image by default but can be added inside the container with `apk add curl`.
The exact API endpoints and authentication vary of course, but in many cases instructions can be found by searching the web or if you feel comfortable looking at the homepage source code (e.g. `src/widgets/{widget}/widget.js`). The exact API endpoints and authentication vary of course, but in many cases instructions can be found by searching the web or if you feel comfortable looking at the homepage source code (e.g. `src/widgets/{widget}/widget.js`).

View File

@@ -13,6 +13,7 @@ widget:
currency: GBP # Optional currency: GBP # Optional
symbols: [BTC, LTC, ETH] symbols: [BTC, LTC, ETH]
key: apikeyapikeyapikeyapikeyapikey key: apikeyapikeyapikeyapikeyapikey
defaultinterval: 7d # Optional
``` ```
You can also specify slugs instead of symbols (since symbols aren't garaunteed to be unique). If you supply both, slugs will be used. For example: You can also specify slugs instead of symbols (since symbols aren't garaunteed to be unique). If you supply both, slugs will be used. For example:

View File

@@ -3,9 +3,9 @@ title: Glances
description: Glances Widget Configuration description: Glances Widget Configuration
--- ---
<img width="1614" alt="glances" src="https://github.com/benphelps/homepage-docs/assets/82196/25648c97-2c1b-4db0-b5a5-f1509806079c"> <img width="1614" alt="glances" src="https://github-production-user-asset-6210df.s3.amazonaws.com/82196/257382012-25648c97-2c1b-4db0-b5a5-f1509806079c.png">
_(Find the Glances information widget [here](../services/glances.md))_ _(Find the Glances information widget [here](../info/glances.md))_
The Glances widget allows you to monitor the resources (cpu, memory, diskio, sensors & processes) of host or another machine. You can have multiple instances by adding another service block. The Glances widget allows you to monitor the resources (cpu, memory, diskio, sensors & processes) of host or another machine. You can have multiple instances by adding another service block.
@@ -59,7 +59,7 @@ The metric field in the configuration determines the type of system monitoring d
All widgets offer an alternative to the full or "graph" view, which is the compact, or "graphless" view. All widgets offer an alternative to the full or "graph" view, which is the compact, or "graphless" view.
<img width="970" alt="Screenshot 2023-09-06 at 1 51 48PM" src="https://github.com/benphelps/homepage-docs/assets/82196/cc6b9adc-4218-4274-96ca-36c3e64de5d0"> <img width="970" alt="Screenshot 2023-09-06 at 1 51 48PM" src="https://github-production-user-asset-6210df.s3.amazonaws.com/82196/265985295-cc6b9adc-4218-4274-96ca-36c3e64de5d0.png">
To switch to the alternative "graphless" view, simply passs `chart: false` as an option to the widget, like so: To switch to the alternative "graphless" view, simply passs `chart: false` as an option to the widget, like so:

View File

@@ -3,7 +3,7 @@ title: Gluetun
description: Gluetun Widget Configuration description: Gluetun Widget Configuration
--- ---
Requires [HTTP control server options](https://github.com/qdm12/gluetun/wiki/HTTP-control-server-options) to be enabled. Requires [HTTP control server options](https://github.com/qdm12/gluetun-wiki/blob/main/setup/advanced/control-server.md) to be enabled.
Allowed fields: `["public_ip", "region", "country"]`. Allowed fields: `["public_ip", "region", "country"]`.

View File

@@ -0,0 +1,12 @@
---
title: HDHomerun
description: HDHomerun Widget Configuration
---
Allowed fields: `["channels", "hd"]`.
```yaml
widget:
type: hdhomerun
url: http://hdhomerun.host.or.ip
```

View File

@@ -3,7 +3,7 @@ title: MJPEG
description: MJPEG Stream Widget Configuration description: MJPEG Stream Widget Configuration
--- ---
![camera-preview](https://github.com/benphelps/homepage-docs/assets/82196/dc375ae3-0670-489f-8db6-83ff1f423d12) ![camera-preview](https://github.com/gethomepage/homepage-docs/assets/82196/dc375ae3-0670-489f-8db6-83ff1f423d12)
Pass the stream URL from a service like [µStreamer](https://github.com/pikvm/ustreamer) or [camera-streamer](https://github.com/ayufan/camera-streamer). Pass the stream URL from a service like [µStreamer](https://github.com/pikvm/ustreamer) or [camera-streamer](https://github.com/ayufan/camera-streamer).

View File

@@ -3,7 +3,7 @@ title: Syncthing Relay Server
description: Syncthing Relay Server Widget Configuration description: Syncthing Relay Server Widget Configuration
--- ---
Pulls stats from the [relay server](https://docs.syncthing.net/users/strelaysrv.html). [See here](https://github.com/benphelps/homepage/pull/230#issuecomment-1253053472) for more information on configuration. Pulls stats from the [relay server](https://docs.syncthing.net/users/strelaysrv.html). [See here](https://github.com/gethomepage/homepage/pull/230#issuecomment-1253053472) for more information on configuration.
Allowed fields: `["numActiveSessions", "numConnections", "bytesProxied"]`. Allowed fields: `["numActiveSessions", "numConnections", "bytesProxied"]`.

View File

@@ -1,5 +1,6 @@
{ {
"compilerOptions": { "compilerOptions": {
"baseUrl": "./src/", "baseUrl": "./src/",
} },
"include": ["src/**/*"]
} }

1
k3d/.gitignore vendored
View File

@@ -1,2 +1 @@
kubeconfig kubeconfig

View File

@@ -11,7 +11,7 @@ All the commands in the document should be run from the `k3d` directory.
## Requisite Tools ## Requisite Tools
| Tool | Description | | Tool | Description |
|-------------------------------------------------------------|----------------------------------------------------------| | ----------------------------------------------------------- | -------------------------------------------------------- |
| [docker](https://docker.io) | Docker container runtime | | [docker](https://docker.io) | Docker container runtime |
| [kubectl](https://kubernetes.io/releases/download/#kubectl) | Kubernetes CLI | | [kubectl](https://kubernetes.io/releases/download/#kubectl) | Kubernetes CLI |
| [helm](https://helm.sh) | Kubernetes package manager | | [helm](https://helm.sh) | Kubernetes package manager |
@@ -20,7 +20,6 @@ All the commands in the document should be run from the `k3d` directory.
| [tilt](https://tilt.dev) | (Optional) Local CI loop for kubernetes deployment | | [tilt](https://tilt.dev) | (Optional) Local CI loop for kubernetes deployment |
| [direnv](https://direnv.net/) | (Optional) Automatically loads `kubeconfig` via `.envrc` | | [direnv](https://direnv.net/) | (Optional) Automatically loads `kubeconfig` via `.envrc` |
## One-off Test Deployments ## One-off Test Deployments
Create a cluster: Create a cluster:
@@ -57,7 +56,7 @@ tilt up
Press space bar to open the tilt web UI, which is quite informative. Press space bar to open the tilt web UI, which is quite informative.
Open the Homepage deployment: Finally, open the Homepage deployment:
```sh ```sh
xdg-open http://homepage.k3d.localhost:8080/ xdg-open http://homepage.k3d.localhost:8080/

View File

@@ -2,9 +2,9 @@
## Requirements ## Requirements
* Kubernetes 1.19+ - Kubernetes 1.19+
* Metrics service - Metrics service
* An Ingress controller - An Ingress controller
## Deployment ## Deployment
@@ -98,7 +98,7 @@ be configured on the service entry.
This works by creating a label selector `app.kubernetes.io/name=home-assistant`, This works by creating a label selector `app.kubernetes.io/name=home-assistant`,
which typically will be the same both for the ingress and the deployment. However, which typically will be the same both for the ingress and the deployment. However,
some deployments can be complex and will not conform to this rule. In such some deployments can be complex and will not conform to this rule. In such
cases the `podSelector` variable can bridge the gap. Any field selector can cases the `pod-selector` variable can bridge the gap. Any field selector can
be used in it which allows for some powerful selection capabilities. be used in it which allows for some powerful selection capabilities.
For instance, it can be utilized to roll multiple underlying deployments under For instance, it can be utilized to roll multiple underlying deployments under
@@ -112,7 +112,7 @@ one application to see a high-level aggregate:
description: Matrix Synapse Powered Chat description: Matrix Synapse Powered Chat
app: matrix-element app: matrix-element
namespace: comms namespace: comms
podSelector: >- pod-selector: >-
app.kubernetes.io/instance in ( app.kubernetes.io/instance in (
matrix-element, matrix-element,
matrix-media-repo, matrix-media-repo,

View File

@@ -4,9 +4,9 @@ site_name: homepage
site_url: https://gethomepage.dev/ site_url: https://gethomepage.dev/
# Repository # Repository
repo_name: benphelps/homepage repo_name: gethomepage/homepage
repo_url: https://github.com/benphelps/homepage repo_url: https://github.com/gethomepage/homepage
edit_uri: https://github.com/benphelps/homepage/tree/main/docs/ edit_uri: https://github.com/gethomepage/homepage/tree/main/docs/
nav: nav:
- "Home": - "Home":
@@ -59,11 +59,11 @@ nav:
- widgets/services/gluetun.md - widgets/services/gluetun.md
- widgets/services/gotify.md - widgets/services/gotify.md
- widgets/services/grafana.md - widgets/services/grafana.md
- widgets/services/hdhomerun.md
- widgets/services/healthchecks.md - widgets/services/healthchecks.md
- widgets/services/homeassistant.md - widgets/services/homeassistant.md
- widgets/services/homebridge.md - widgets/services/homebridge.md
- widgets/services/immich.md - widgets/services/immich.md
- widgets/services/index.md
- widgets/services/jackett.md - widgets/services/jackett.md
- widgets/services/jdownloader.md - widgets/services/jdownloader.md
- widgets/services/jellyfin.md - widgets/services/jellyfin.md
@@ -150,6 +150,7 @@ nav:
- more/index.md - more/index.md
- more/development.md - more/development.md
- more/translations.md - more/translations.md
- more/homepage-move.md
theme: theme:
name: material name: material
@@ -193,6 +194,13 @@ extra_css:
extra: extra:
version: version:
provider: mike provider: mike
social:
- icon: fontawesome/brands/discord
link: https://discord.gg/k4ruYNrudu
- icon: fontawesome/regular/message
link: https://github.com/gethomepage/homepage/discussions
- icon: fontawesome/brands/github
link: https://github.com/gethomepage/homepage
markdown_extensions: markdown_extensions:
- pymdownx.highlight: - pymdownx.highlight:
@@ -216,10 +224,13 @@ markdown_extensions:
- admonition - admonition
plugins: plugins:
- tags - group:
- typeset enabled: !ENV MKINSIDERS
# - social plugins:
- optimize - optimize
- typeset
- social
- tags
- search: - search:
pipeline: pipeline:
- stemmer - stemmer

View File

@@ -69,7 +69,7 @@ function prettyBytes(number, options) {
const exponent = Math.min( const exponent = Math.min(
Math.floor(options.binary ? Math.log(number) / Math.log(1024) : Math.log10(number) / 3), Math.floor(options.binary ? Math.log(number) / Math.log(1024) : Math.log10(number) / 3),
UNITS.length - 1 UNITS.length - 1,
); );
number /= (options.binary ? 1024 : 1000) ** exponent; number /= (options.binary ? 1024 : 1000) ** exponent;
@@ -94,13 +94,18 @@ module.exports = {
{ {
init: (i18next) => { init: (i18next) => {
i18next.services.formatter.add("bytes", (value, lng, options) => i18next.services.formatter.add("bytes", (value, lng, options) =>
prettyBytes(parseFloat(value), { locale: lng, ...options }) prettyBytes(parseFloat(value), { locale: lng, ...options }),
); );
i18next.services.formatter.add("rate", (value, lng, options) => { i18next.services.formatter.add("rate", (value, lng, options) => {
const k = options.binary ? 1024 : 1000; const k = options.binary ? 1024 : 1000;
const sizes = options.bits ? (options.binary ? BIBIT_UNITS : BIT_UNITS) : (options.binary ? BIBYTE_UNITS : BYTE_UNITS); const sizes = options.bits
? options.binary
? BIBIT_UNITS
: BIT_UNITS
: options.binary
? BIBYTE_UNITS
: BYTE_UNITS;
if (value === 0) return `0 ${sizes[0]}/s`; if (value === 0) return `0 ${sizes[0]}/s`;
@@ -109,14 +114,14 @@ module.exports = {
const i = options.binary ? 2 : Math.floor(Math.log(value) / Math.log(k)); const i = options.binary ? 2 : Math.floor(Math.log(value) / Math.log(k));
const formatted = new Intl.NumberFormat(lng, { maximumFractionDigits: dm, minimumFractionDigits: dm }).format( const formatted = new Intl.NumberFormat(lng, { maximumFractionDigits: dm, minimumFractionDigits: dm }).format(
parseFloat(value / k ** i) parseFloat(value / k ** i),
); );
return `${formatted} ${sizes[i]}/s`; return `${formatted} ${sizes[i]}/s`;
}); });
i18next.services.formatter.add("percent", (value, lng, options) => i18next.services.formatter.add("percent", (value, lng, options) =>
new Intl.NumberFormat(lng, { style: "percent", ...options }).format(parseFloat(value) / 100.0) new Intl.NumberFormat(lng, { style: "percent", ...options }).format(parseFloat(value) / 100.0),
); );
}, },
type: "3rdParty", type: "3rdParty",

26
package-lock.json generated
View File

@@ -30,7 +30,6 @@
"react-i18next": "^11.18.6", "react-i18next": "^11.18.6",
"react-icons": "^4.4.0", "react-icons": "^4.4.0",
"recharts": "^2.7.2", "recharts": "^2.7.2",
"shvl": "^3.0.0",
"swr": "^1.3.0", "swr": "^1.3.0",
"systeminformation": "^5.17.12", "systeminformation": "^5.17.12",
"tough-cookie": "^4.1.2", "tough-cookie": "^4.1.2",
@@ -44,14 +43,14 @@
"eslint": "^8.24.0", "eslint": "^8.24.0",
"eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb": "^19.0.4",
"eslint-config-next": "^12.3.1", "eslint-config-next": "^12.3.1",
"eslint-config-prettier": "^8.5.0", "eslint-config-prettier": "^9.0.0",
"eslint-plugin-import": "^2.26.0", "eslint-plugin-import": "^2.26.0",
"eslint-plugin-jsx-a11y": "^6.6.1", "eslint-plugin-jsx-a11y": "^6.6.1",
"eslint-plugin-prettier": "^4.2.1", "eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-react": "^7.31.8", "eslint-plugin-react": "^7.31.8",
"eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-hooks": "^4.6.0",
"postcss": "^8.4.16", "postcss": "^8.4.16",
"prettier": "^2.7.1", "prettier": "^3.0.3",
"tailwind-scrollbar": "^2.0.1", "tailwind-scrollbar": "^2.0.1",
"tailwindcss": "^3.1.8", "tailwindcss": "^3.1.8",
"typescript": "^4.8.3" "typescript": "^4.8.3"
@@ -2264,9 +2263,9 @@
} }
}, },
"node_modules/eslint-config-prettier": { "node_modules/eslint-config-prettier": {
"version": "8.8.0", "version": "9.0.0",
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz", "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.0.0.tgz",
"integrity": "sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==", "integrity": "sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw==",
"dev": true, "dev": true,
"bin": { "bin": {
"eslint-config-prettier": "bin/cli.js" "eslint-config-prettier": "bin/cli.js"
@@ -5008,15 +5007,15 @@
} }
}, },
"node_modules/prettier": { "node_modules/prettier": {
"version": "2.8.7", "version": "3.0.3",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.7.tgz", "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz",
"integrity": "sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==", "integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==",
"dev": true, "dev": true,
"bin": { "bin": {
"prettier": "bin-prettier.js" "prettier": "bin/prettier.cjs"
}, },
"engines": { "engines": {
"node": ">=10.13.0" "node": ">=14"
}, },
"funding": { "funding": {
"url": "https://github.com/prettier/prettier?sponsor=1" "url": "https://github.com/prettier/prettier?sponsor=1"
@@ -5628,11 +5627,6 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/shvl": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/shvl/-/shvl-3.0.0.tgz",
"integrity": "sha512-5IomAM3ykE/g9K9L6lhODc+TpCuN03rrhlboegeKyyfh66DDdpRD5JN37DYhNHH+RaYjiIDx64K/Ms/xQYOR5w=="
},
"node_modules/side-channel": { "node_modules/side-channel": {
"version": "1.0.4", "version": "1.0.4",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",

View File

@@ -32,7 +32,6 @@
"react-i18next": "^11.18.6", "react-i18next": "^11.18.6",
"react-icons": "^4.4.0", "react-icons": "^4.4.0",
"recharts": "^2.7.2", "recharts": "^2.7.2",
"shvl": "^3.0.0",
"swr": "^1.3.0", "swr": "^1.3.0",
"systeminformation": "^5.17.12", "systeminformation": "^5.17.12",
"tough-cookie": "^4.1.2", "tough-cookie": "^4.1.2",
@@ -46,14 +45,14 @@
"eslint": "^8.24.0", "eslint": "^8.24.0",
"eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb": "^19.0.4",
"eslint-config-next": "^12.3.1", "eslint-config-next": "^12.3.1",
"eslint-config-prettier": "^8.5.0", "eslint-config-prettier": "^9.0.0",
"eslint-plugin-import": "^2.26.0", "eslint-plugin-import": "^2.26.0",
"eslint-plugin-jsx-a11y": "^6.6.1", "eslint-plugin-jsx-a11y": "^6.6.1",
"eslint-plugin-prettier": "^4.2.1", "eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-react": "^7.31.8", "eslint-plugin-react": "^7.31.8",
"eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-hooks": "^4.6.0",
"postcss": "^8.4.16", "postcss": "^8.4.16",
"prettier": "^2.7.1", "prettier": "^3.0.3",
"tailwind-scrollbar": "^2.0.1", "tailwind-scrollbar": "^2.0.1",
"tailwindcss": "^3.1.8", "tailwindcss": "^3.1.8",
"typescript": "^4.8.3" "typescript": "^4.8.3"

34
pnpm-lock.yaml generated
View File

@@ -71,9 +71,6 @@ dependencies:
recharts: recharts:
specifier: ^2.7.2 specifier: ^2.7.2
version: 2.7.2(prop-types@15.8.1)(react-dom@18.2.0)(react@18.2.0) version: 2.7.2(prop-types@15.8.1)(react-dom@18.2.0)(react@18.2.0)
shvl:
specifier: ^3.0.0
version: 3.0.0
swr: swr:
specifier: ^1.3.0 specifier: ^1.3.0
version: 1.3.0(react@18.2.0) version: 1.3.0(react@18.2.0)
@@ -115,8 +112,8 @@ devDependencies:
specifier: ^12.3.1 specifier: ^12.3.1
version: 12.3.4(eslint@8.37.0)(typescript@4.9.5) version: 12.3.4(eslint@8.37.0)(typescript@4.9.5)
eslint-config-prettier: eslint-config-prettier:
specifier: ^8.5.0 specifier: ^9.0.0
version: 8.8.0(eslint@8.37.0) version: 9.0.0(eslint@8.37.0)
eslint-plugin-import: eslint-plugin-import:
specifier: ^2.26.0 specifier: ^2.26.0
version: 2.27.5(@typescript-eslint/parser@5.57.0)(eslint-import-resolver-typescript@2.7.1)(eslint@8.37.0) version: 2.27.5(@typescript-eslint/parser@5.57.0)(eslint-import-resolver-typescript@2.7.1)(eslint@8.37.0)
@@ -125,7 +122,7 @@ devDependencies:
version: 6.7.1(eslint@8.37.0) version: 6.7.1(eslint@8.37.0)
eslint-plugin-prettier: eslint-plugin-prettier:
specifier: ^4.2.1 specifier: ^4.2.1
version: 4.2.1(eslint-config-prettier@8.8.0)(eslint@8.37.0)(prettier@2.8.7) version: 4.2.1(eslint-config-prettier@9.0.0)(eslint@8.37.0)(prettier@3.0.3)
eslint-plugin-react: eslint-plugin-react:
specifier: ^7.31.8 specifier: ^7.31.8
version: 7.32.2(eslint@8.37.0) version: 7.32.2(eslint@8.37.0)
@@ -136,8 +133,8 @@ devDependencies:
specifier: ^8.4.16 specifier: ^8.4.16
version: 8.4.21 version: 8.4.21
prettier: prettier:
specifier: ^2.7.1 specifier: ^3.0.3
version: 2.8.7 version: 3.0.3
tailwind-scrollbar: tailwind-scrollbar:
specifier: ^2.0.1 specifier: ^2.0.1
version: 2.1.0(tailwindcss@3.3.0) version: 2.1.0(tailwindcss@3.3.0)
@@ -1503,8 +1500,8 @@ packages:
- supports-color - supports-color
dev: true dev: true
/eslint-config-prettier@8.8.0(eslint@8.37.0): /eslint-config-prettier@9.0.0(eslint@8.37.0):
resolution: {integrity: sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==} resolution: {integrity: sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw==}
hasBin: true hasBin: true
peerDependencies: peerDependencies:
eslint: '>=7.0.0' eslint: '>=7.0.0'
@@ -1628,7 +1625,7 @@ packages:
semver: 6.3.0 semver: 6.3.0
dev: true dev: true
/eslint-plugin-prettier@4.2.1(eslint-config-prettier@8.8.0)(eslint@8.37.0)(prettier@2.8.7): /eslint-plugin-prettier@4.2.1(eslint-config-prettier@9.0.0)(eslint@8.37.0)(prettier@3.0.3):
resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==} resolution: {integrity: sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==}
engines: {node: '>=12.0.0'} engines: {node: '>=12.0.0'}
peerDependencies: peerDependencies:
@@ -1640,8 +1637,8 @@ packages:
optional: true optional: true
dependencies: dependencies:
eslint: 8.37.0 eslint: 8.37.0
eslint-config-prettier: 8.8.0(eslint@8.37.0) eslint-config-prettier: 9.0.0(eslint@8.37.0)
prettier: 2.8.7 prettier: 3.0.3
prettier-linter-helpers: 1.0.0 prettier-linter-helpers: 1.0.0
dev: true dev: true
@@ -3206,9 +3203,10 @@ packages:
fast-diff: 1.2.0 fast-diff: 1.2.0
dev: true dev: true
/prettier@2.8.7: /prettier@3.0.3:
resolution: {integrity: sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==} resolution: {integrity: sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==}
engines: {node: '>=10.13.0'} engines: {node: '>=14'}
hasBin: true
dev: true dev: true
/pretty-bytes@6.1.0: /pretty-bytes@6.1.0:
@@ -3614,10 +3612,6 @@ packages:
rechoir: 0.6.2 rechoir: 0.6.2
dev: false dev: false
/shvl@3.0.0:
resolution: {integrity: sha512-5IomAM3ykE/g9K9L6lhODc+TpCuN03rrhlboegeKyyfh66DDdpRD5JN37DYhNHH+RaYjiIDx64K/Ms/xQYOR5w==}
dev: false
/side-channel@1.0.4: /side-channel@1.0.4:
resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==}
dependencies: dependencies:

View File

@@ -3,4 +3,4 @@ module.exports = {
tailwindcss: {}, tailwindcss: {},
autoprefixer: {}, autoprefixer: {},
}, },
} };

View File

@@ -382,7 +382,9 @@
}, },
"ping": { "ping": {
"error": "خطأ", "error": "خطأ",
"ping": "Ping" "ping": "Ping",
"up": "Up",
"down": "Down"
}, },
"scrutiny": { "scrutiny": {
"passed": "إجتاز", "passed": "إجتاز",

View File

@@ -382,7 +382,9 @@
}, },
"ping": { "ping": {
"ping": "Ping", "ping": "Ping",
"error": "Грешка" "error": "Грешка",
"up": "Up",
"down": "Down"
}, },
"scrutiny": { "scrutiny": {
"passed": "Passed", "passed": "Passed",

View File

@@ -382,7 +382,9 @@
}, },
"ping": { "ping": {
"error": "Error", "error": "Error",
"ping": "Ping" "ping": "Ping",
"up": "Up",
"down": "Down"
}, },
"scrutiny": { "scrutiny": {
"passed": "Aprobat", "passed": "Aprobat",

View File

@@ -382,7 +382,9 @@
}, },
"ping": { "ping": {
"error": "Chyba", "error": "Chyba",
"ping": "Odezva" "ping": "Odezva",
"up": "Up",
"down": "Down"
}, },
"scrutiny": { "scrutiny": {
"passed": "Úspěšné", "passed": "Úspěšné",

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -136,7 +136,9 @@
}, },
"ping": { "ping": {
"error": "Σφάλμα", "error": "Σφάλμα",
"ping": "Ping" "ping": "Ping",
"up": "Up",
"down": "Down"
}, },
"emby": { "emby": {
"playing": "Παίζει", "playing": "Παίζει",

View File

@@ -79,8 +79,12 @@
"partial": "Partial" "partial": "Partial"
}, },
"ping": { "ping": {
"http_status": "HTTP status",
"error": "Error", "error": "Error",
"ping": "Ping" "ping": "Ping",
"down": "Down",
"up": "Up",
"not_available": "Not Available"
}, },
"emby": { "emby": {
"playing": "Playing", "playing": "Playing",

View File

@@ -67,7 +67,9 @@
}, },
"ping": { "ping": {
"error": "Eraro", "error": "Eraro",
"ping": "Sondaĵo" "ping": "Sondaĵo",
"up": "Up",
"down": "Down"
}, },
"emby": { "emby": {
"playing": "Ludante", "playing": "Ludante",

View File

@@ -1,23 +1,42 @@
{ {
"common": {
"bytes": "{{value, bytes}}",
"bits": "{{value, bytes(bits: true)}}",
"bbytes": "{{value, bytes(binary: true)}}",
"bbits": "{{value, bytes(bits: true; binary: true)}}",
"byterate": "{{value, rate(bits: false)}}",
"bibyterate": "{{value, rate(bits: false; binary: true)}}",
"bitrate": "{{value, rate(bits: true)}}",
"bibitrate": "{{value, rate(bits: true; binary: true)}}",
"percent": "{{value, percent}}",
"number": "{{value, number}}",
"ms": "{{value, number}}"
},
"widget": { "widget": {
"missing_type": "Falta el tipo de widget: {{type}}", "missing_type": "Tipo de Widget que falta: {{type}}",
"api_error": "Error de API", "api_error": "Error en API",
"status": "Estado",
"information": "Información", "information": "Información",
"url": "URL", "status": "Estado",
"url": "Enlace",
"raw_error": "Error sin procesar", "raw_error": "Error sin procesar",
"response_data": "Datos de respuesta" "response_data": "Datos de respuesta"
}, },
"weather": {
"current": "Ubicación actual",
"allow": "Clic para permitir",
"updating": "Actualizando",
"wait": "Espera, por favor"
},
"search": { "search": {
"placeholder": "Buscar…" "placeholder": "Buscar…"
}, },
"resources": { "resources": {
"cpu": "CPU",
"mem": "MEM",
"total": "Total", "total": "Total",
"free": "Libre", "free": "Libre",
"used": "Usado", "used": "Usado",
"load": "Carga", "load": "Carga",
"cpu": "CPU",
"mem": "MEM",
"temp": "TEMP", "temp": "TEMP",
"max": "Máx.", "max": "Máx.",
"uptime": "ARRIBA", "uptime": "ARRIBA",
@@ -26,21 +45,46 @@
"hours": "Horas", "hours": "Horas",
"minutes": "Minutos" "minutes": "Minutos"
}, },
"unifi": {
"users": "Usuarios",
"uptime": "Tiempo de actividad",
"days": "Días",
"wan": "WAN",
"lan": "LAN",
"wlan": "WLAN",
"devices": "Dispositivos",
"lan_devices": "Dispositivos LAN",
"wlan_devices": "Dispositivos WLAN",
"lan_users": "Usuarios LAN",
"wlan_users": "Usuarios WLAN",
"up": "ARRIBA",
"down": "CAÍDO",
"wait": "Espera, por favor",
"empty_data": "Se desconoce el estado del subsistema"
},
"docker": { "docker": {
"rx": "Recibido", "rx": "Recibido",
"tx": "Transmitido", "tx": "Transmitido",
"mem": "Memoria", "mem": "MEM",
"cpu": "Procesador", "cpu": "CPU",
"running": "Ejecutando",
"offline": "Desconectado", "offline": "Desconectado",
"error": "Fallo", "error": "Fallo",
"unknown": "Desconocido", "unknown": "Desconocido",
"running": "Ejecutando", "healthy": "Saludable",
"starting": "Comenzando", "starting": "Comenzando",
"unhealthy": "Insalubre", "unhealthy": "Insalubre",
"not_found": "No encontrado", "not_found": "No encontrado",
"exited": "Salida", "exited": "Salida",
"partial": "Parcial", "partial": "Parcial"
"healthy": "Saludable" },
"ping": {
"http_status": "Estado HTTP",
"error": "Fallo",
"ping": "Ping",
"down": "Abajo",
"up": "Arriba",
"not_available": "No Disponible"
}, },
"emby": { "emby": {
"playing": "Reproduciendo", "playing": "Reproduciendo",
@@ -48,10 +92,43 @@
"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": "Series", "series": "Serie",
"episodes": "Episodios", "episodes": "Episodios",
"songs": "Canciones" "songs": "Canciones"
}, },
"evcc": {
"pv_power": "Producción",
"battery_soc": "Batería",
"grid_power": "Red",
"home_power": "Consumo",
"charge_power": "Cargador",
"watt_hour": "vatio-hora (Wh)"
},
"flood": {
"download": "Descarga",
"upload": "Subida",
"leech": "Depender",
"seed": "Semillas"
},
"freshrss": {
"subscriptions": "Suscripciones",
"unread": "Sin leer"
},
"caddy": {
"upstreams": "Upstream (desarrollo de software)",
"requests": "Peticiones actuales",
"requests_failed": "Peticiones fallidas"
},
"changedetectionio": {
"totalObserved": "Total Observados",
"diffsDetected": "Diferencias detectadas"
},
"channelsdvrserver": {
"shows": "Espectáculos",
"recordings": "Grabaciones",
"scheduled": "Programado",
"passes": "Pases"
},
"tautulli": { "tautulli": {
"playing": "Reproduciendo", "playing": "Reproduciendo",
"transcoding": "Transcodificando", "transcoding": "Transcodificando",
@@ -59,31 +136,95 @@
"no_active": "Sin transmisiones activas", "no_active": "Sin transmisiones activas",
"plex_connection_error": "Comprueba la conexión a Plex" "plex_connection_error": "Comprueba la conexión a Plex"
}, },
"omada": {
"connectedAp": "AP conectados",
"activeUser": "Dispositivos activos",
"alerts": "Alertas",
"connectedGateway": "Pasarelas conectadas",
"connectedSwitches": "Interruptores conectados"
},
"nzbget": {
"rate": "Tasa",
"remaining": "Restante",
"downloaded": "Descargado"
},
"plex": {
"streams": "Transmisiones activas",
"albums": "Álbumes",
"movies": "Películas",
"tv": "Series"
},
"sabnzbd": {
"rate": "Tasa",
"queue": "En cola",
"timeleft": "Tiempo restante"
},
"rutorrent": { "rutorrent": {
"active": "Activo", "active": "Activo",
"upload": "Subida", "upload": "Subida",
"download": "Bajada" "download": "Descarga"
},
"transmission": {
"download": "Descarga",
"upload": "Subida",
"leech": "Depender",
"seed": "Semillas"
},
"qbittorrent": {
"download": "Descarga",
"upload": "Subida",
"leech": "Depender",
"seed": "Semillas"
},
"qnap": {
"cpuUsage": "Uso de la Cpu",
"memUsage": "Uso de la memoria",
"systemTempC": "Temperatura del sistema",
"poolUsage": "Comprobación del uso del grupo de memoria",
"volumeUsage": "Volumen utilizado",
"invalid": "No válido"
},
"deluge": {
"download": "Descarga",
"upload": "Subida",
"leech": "Depender",
"seed": "Semillas"
},
"downloadstation": {
"download": "Descarga",
"upload": "Subida",
"leech": "Depender",
"seed": "Semillas"
}, },
"sonarr": { "sonarr": {
"wanted": "Buscando", "wanted": "Buscando",
"queued": "En cola", "queued": "En cola",
"series": "Series", "series": "Serie",
"queue": "Poner a la cola", "queue": "En cola",
"unknown": "Desconocido" "unknown": "Desconocido"
}, },
"radarr": { "radarr": {
"wanted": "Buscando", "wanted": "Buscando",
"missing": "Faltan",
"queued": "En cola", "queued": "En cola",
"movies": "Películas", "movies": "Películas",
"missing": "Faltan", "queue": "En cola",
"queue": "Poner a la cola",
"unknown": "Desconocido" "unknown": "Desconocido"
}, },
"lidarr": {
"wanted": "Buscando",
"queued": "En cola",
"artists": "Artistas"
},
"readarr": { "readarr": {
"wanted": "Buscando", "wanted": "Buscando",
"queued": "En cola", "queued": "En cola",
"books": "Libros" "books": "Libros"
}, },
"bazarr": {
"missingEpisodes": "Episodios perdidos",
"missingMovies": "Películas perdidas"
},
"ombi": { "ombi": {
"pending": "Pendiente", "pending": "Pendiente",
"approved": "Aprobado", "approved": "Aprobado",
@@ -94,54 +235,74 @@
"approved": "Aprobado", "approved": "Aprobado",
"available": "Disponible" "available": "Disponible"
}, },
"overseerr": {
"pending": "Pendiente",
"processing": "Procesando",
"approved": "Aprobado",
"available": "Disponible"
},
"pialert": {
"total": "Total",
"connected": "Conectado",
"new_devices": "Nuevos dispositivos",
"down_alerts": "Alertas"
},
"pihole": { "pihole": {
"queries": "Consultas", "queries": "Consultas",
"blocked": "Bloqueado", "blocked": "Bloqueado",
"gravity": "Gravedad", "blocked_percent": "% bloqueado",
"blocked_percent": "% bloqueado" "gravity": "Gravedad"
},
"adguard": {
"queries": "Consultas",
"blocked": "Bloqueado",
"filtered": "Filtrado",
"latency": "Latencia"
}, },
"speedtest": { "speedtest": {
"upload": "Subida", "upload": "Subida",
"download": "Bajada", "download": "Descarga",
"ping": "Ping" "ping": "Ping"
}, },
"portainer": { "portainer": {
"running": "En ejecución", "running": "Ejecutando",
"stopped": "Detenido", "stopped": "Detenido",
"total": "Total" "total": "Total"
}, },
"tailscale": {
"address": "Dirección",
"expires": "Caduca en",
"never": "Nunca",
"last_seen": "Visto por última vez",
"now": "Ahora",
"years": "{{number}}años",
"weeks": "{{number}}semanas",
"days": "{{number}}días",
"hours": "{{number}}horas",
"minutes": "{{number}}minutos",
"seconds": "{{number}}segundos",
"ago": "Hace {{value}}"
},
"tdarr": {
"queue": "En cola",
"processed": "Procesado",
"errored": "Error",
"saved": "Guardado"
},
"traefik": { "traefik": {
"routers": "Enrutadores", "routers": "Enrutadores",
"services": "Servicios", "services": "Servicios",
"middleware": "Software intermedio" "middleware": "Software intermedio"
}, },
"navidrome": {
"nothing_streaming": "Sin transmisiones activas",
"please_wait": "Espere por favor"
},
"npm": { "npm": {
"enabled": "Activado", "enabled": "Activado",
"disabled": "Desactivado", "disabled": "Desactivado",
"total": "Total" "total": "Total"
}, },
"weather": {
"current": "Ubicación actual",
"allow": "Clic para permitir",
"updating": "Actualizando",
"wait": "Espera, por favor"
},
"overseerr": {
"pending": "Pendiente",
"approved": "Aprobado",
"available": "Disponible",
"processing": "Procesando"
},
"sabnzbd": {
"rate": "Tasa",
"queue": "En cola",
"timeleft": "Tiempo restante"
},
"nzbget": {
"rate": "Tasa",
"remaining": "Restante",
"downloaded": "Descargado"
},
"coinmarketcap": { "coinmarketcap": {
"configure": "Configurar una o más criptomonedas para rastrear", "configure": "Configurar una o más criptomonedas para rastrear",
"1hour": "1 Hora", "1hour": "1 Hora",
@@ -161,47 +322,36 @@
"numberOfFailGrabs": "Capturas fallidas", "numberOfFailGrabs": "Capturas fallidas",
"numberOfFailQueries": "Consultas fallidas" "numberOfFailQueries": "Consultas fallidas"
}, },
"transmission": {
"download": "Bajada",
"upload": "Subida",
"leech": "Compañeros",
"seed": "Semillas"
},
"jackett": { "jackett": {
"configured": "Configurado", "configured": "Configurado",
"errored": "Con errores" "errored": "Error"
}, },
"bazarr": { "strelaysrv": {
"missingEpisodes": "Episodios perdidos", "numActiveSessions": "Sesiones",
"missingMovies": "Películas perdidas" "numConnections": "Conexiones",
}, "dataRelayed": "Retransmitido",
"lidarr": { "transferRate": "Tasa"
"queued": "En cola",
"wanted": "Buscando",
"artists": "Artistas"
},
"adguard": {
"queries": "Consultas",
"blocked": "Bloqueado",
"filtered": "Filtrado",
"latency": "Latencia"
},
"qbittorrent": {
"download": "Bajada",
"upload": "Subida",
"leech": "Pares",
"seed": "Semillas"
}, },
"mastodon": { "mastodon": {
"user_count": "Usuarios", "user_count": "Usuarios",
"status_count": "Publicaciones", "status_count": "Publicaciones",
"domain_count": "Dominios" "domain_count": "Dominios"
}, },
"strelaysrv": { "medusa": {
"numActiveSessions": "Sesiones", "wanted": "Buscando",
"numConnections": "Conexiones", "queued": "En cola",
"dataRelayed": "Retransmitido", "series": "Serie"
"transferRate": "Velocidad" },
"minecraft": {
"players": "Jugadores",
"version": "Versión",
"status": "Estado",
"up": "En línea",
"down": "Desconectado"
},
"miniflux": {
"read": "Leer",
"unread": "Sin leer"
}, },
"authentik": { "authentik": {
"users": "Usuarios", "users": "Usuarios",
@@ -209,73 +359,54 @@
"failedLoginsLast24H": "Inicios de sesión fallidos (24h)" "failedLoginsLast24H": "Inicios de sesión fallidos (24h)"
}, },
"proxmox": { "proxmox": {
"mem": "Memoria", "mem": "MEM",
"cpu": "Procesador", "cpu": "CPU",
"lxc": "Contenedores Linux", "lxc": "Contenedores Linux",
"vms": "Máquinas Virtuales" "vms": "Máquinas Virtuales"
}, },
"unifi": {
"up": "LEVANTADO",
"users": "Usuarios",
"uptime": "Tiempo de actividad",
"days": "Días",
"wan": "WAN",
"lan_users": "Usuarios LAN",
"wlan_users": "Usuarios WLAN",
"down": "CAÍDO",
"wait": "Espera por favor",
"lan": "LAN",
"wlan": "WLAN",
"devices": "Dispositivos",
"lan_devices": "Dispositivos LAN",
"wlan_devices": "Dispositivos WLAN",
"empty_data": "Se desconoce el estado del subsistema"
},
"plex": {
"streams": "Transmisiones activas",
"movies": "Películas",
"tv": "Series",
"albums": "Álbumes"
},
"glances": { "glances": {
"cpu": "Procesador", "cpu": "CPU",
"wait": "Espera por favor", "load": "Carga",
"temp": "TEMPORAL", "wait": "Espera, por favor",
"uptime": "ARRIBA", "temp": "TEMP",
"days": "Días", "_temp": "Temperatura",
"hours": "Horas",
"load": "Cargar",
"warn": "Advertir", "warn": "Advertir",
"uptime": "ARRIBA",
"total": "Total", "total": "Total",
"free": "Libre", "free": "Libre",
"used": "Utilizado", "used": "Usado",
"days": "Días",
"hours": "Horas",
"crit": "Crít.", "crit": "Crít.",
"read": "Leer", "read": "Leer",
"write": "Escribir", "write": "Escribir",
"gpu": "GPU", "gpu": "GPU",
"mem": "Memoria", "mem": "Memoria",
"swap": "Intercambiar", "swap": "Intercambiar"
"_temp": "Temperatura"
}, },
"changedetectionio": { "quicklaunch": {
"totalObserved": "Total Observados", "bookmark": "Marcadores",
"diffsDetected": "Diferencias detectadas" "service": "Servicio",
"search": "Buscar",
"custom": "Personalizado",
"visit": "Visita",
"url": "Enlace"
}, },
"wmo": { "wmo": {
"48-night": "Niebla",
"51-day": "Llovizna ligera",
"51-night": "Llovizna ligera",
"2-day": "Parcialmente nuboso",
"0-day": "Soleado", "0-day": "Soleado",
"0-night": "Despejado", "0-night": "Despejado",
"1-day": "Mayormente soleado", "1-day": "Mayormente soleado",
"1-night": "Mayormente despejado", "1-night": "Mayormente despejado",
"2-day": "Parcialmente nuboso",
"2-night": "Parcialmente nuboso", "2-night": "Parcialmente nuboso",
"3-day": "Nublado", "3-day": "Nublado",
"3-night": "Nublado", "3-night": "Nublado",
"45-day": "Niebla", "45-day": "Niebla",
"45-night": "Niebla", "45-night": "Niebla",
"48-day": "Niebla", "48-day": "Niebla",
"48-night": "Niebla",
"51-day": "Llovizna ligera",
"51-night": "Llovizna ligera",
"53-day": "Llovizna", "53-day": "Llovizna",
"53-night": "Llovizna", "53-night": "Llovizna",
"55-day": "Llovizna pesada", "55-day": "Llovizna pesada",
@@ -286,13 +417,13 @@
"57-night": "Llovizna helada", "57-night": "Llovizna helada",
"61-day": "Lluvia ligera", "61-day": "Lluvia ligera",
"61-night": "Lluvia ligera", "61-night": "Lluvia ligera",
"67-day": "Granizo",
"63-day": "Lluvia", "63-day": "Lluvia",
"63-night": "Lluvia", "63-night": "Lluvia",
"65-day": "Chubascos", "65-day": "Chubascos",
"65-night": "Chubascos", "65-night": "Chubascos",
"66-day": "Granizo", "66-day": "Granizo",
"66-night": "Granizo", "66-night": "Granizo",
"67-day": "Granizo",
"67-night": "Granizo", "67-night": "Granizo",
"71-day": "Nevada Leve", "71-day": "Nevada Leve",
"71-night": "Nevada Leve", "71-night": "Nevada Leve",
@@ -300,8 +431,8 @@
"73-night": "Nevada", "73-night": "Nevada",
"75-day": "Fuertes Nevadas", "75-day": "Fuertes Nevadas",
"75-night": "Fuertes Nevadas", "75-night": "Fuertes Nevadas",
"77-day": "Nevada Leve", "77-day": "Granizada",
"77-night": "Nevada Leve", "77-night": "Granizada",
"80-day": "Llovizna", "80-day": "Llovizna",
"80-night": "Llovizna", "80-night": "Llovizna",
"81-day": "Lluvia", "81-day": "Lluvia",
@@ -319,38 +450,40 @@
"99-day": "Tormenta con granizo", "99-day": "Tormenta con granizo",
"99-night": "Tormenta con granizo" "99-night": "Tormenta con granizo"
}, },
"quicklaunch": {
"bookmark": "Marcadores",
"service": "Servicio",
"search": "Buscar",
"custom": "Personalizado",
"visit": "Visita",
"url": "URL"
},
"homebridge": { "homebridge": {
"available_update": "Sistema", "available_update": "Sistema",
"updates": "Actualizaciones", "updates": "Actualizaciones",
"update_available": "Actualización disponible", "update_available": "Actualización disponible",
"up_to_date": "Actualizado", "up_to_date": "Actualizado",
"child_bridges": "Child Bridges", "child_bridges": "Bridges secundarios",
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Arriba", "up": "Arriba",
"pending": "Pendiente", "pending": "Pendiente",
"down": "Abajo" "down": "Abajo"
}, },
"healthchecks": {
"new": "Nuevo",
"up": "En línea",
"grace": "En Periodo de Gracia",
"down": "Desconectado",
"paused": "Pausado",
"status": "Estado",
"last_ping": "Último ping",
"never": "Aún no hay pings"
},
"watchtower": {
"containers_scanned": "Escaneado",
"containers_updated": "Actualizado",
"containers_failed": "Fallido"
},
"autobrr": { "autobrr": {
"approvedPushes": "Aprobado", "approvedPushes": "Aprobado",
"rejectedPushes": "Rechazado", "rejectedPushes": "Rechazado",
"filters": "Filtros", "filters": "Filtros",
"indexers": "Indexadores" "indexers": "Indexadores"
}, },
"watchtower": {
"containers_scanned": "Escaneado",
"containers_updated": "Actualizado",
"containers_failed": "Fallido"
},
"tubearchivist": { "tubearchivist": {
"downloads": "Cola", "downloads": "En cola",
"videos": "Vídeos", "videos": "Vídeos",
"channels": "Canales", "channels": "Canales",
"playlists": "Listas de reproducción" "playlists": "Listas de reproducción"
@@ -361,14 +494,10 @@
"alerts": "Alertas", "alerts": "Alertas",
"time": "{{value, number(style: unit; unitDisplay: long;)}}" "time": "{{value, number(style: unit; unitDisplay: long;)}}"
}, },
"navidrome": {
"nothing_streaming": "Sin transmisiones activas",
"please_wait": "Espere por favor"
},
"pyload": { "pyload": {
"speed": "Velocidad", "speed": "Velocidad",
"active": "Activo", "active": "Activo",
"queue": "Cola", "queue": "En cola",
"total": "Total" "total": "Total"
}, },
"gluetun": { "gluetun": {
@@ -380,10 +509,6 @@
"channels": "Canales", "channels": "Canales",
"hd": "Alta definición" "hd": "Alta definición"
}, },
"ping": {
"error": "Error",
"ping": "Ping"
},
"scrutiny": { "scrutiny": {
"passed": "Aprobado", "passed": "Aprobado",
"failed": "Fallido", "failed": "Fallido",
@@ -393,53 +518,14 @@
"inbox": "Bandeja de entrada", "inbox": "Bandeja de entrada",
"total": "Total" "total": "Total"
}, },
"deluge": {
"download": "Descarga",
"upload": "Subida",
"leech": "Compañeros",
"seed": "Semillas"
},
"flood": {
"download": "Descarga",
"upload": "Subida",
"leech": "Depender",
"seed": "Semillas"
},
"tdarr": {
"queue": "Cola",
"processed": "Procesado",
"saved": "Guardado",
"errored": "Error"
},
"miniflux": {
"read": "Leer",
"unread": "Sin leer"
},
"nextdns": { "nextdns": {
"wait": "Espera, por favor", "wait": "Espere por favor",
"no_devices": "No se reciben datos del dispositivo" "no_devices": "No se reciben datos del dispositivo"
}, },
"common": {
"bibyterate": "{{value, rate(bits: false; binary: true)}}",
"bibitrate": "{{value, rate(bits: true; binary: true)}}"
},
"omada": {
"connectedAp": "AP conectados",
"activeUser": "Dispositivos activos",
"alerts": "Alertas",
"connectedGateway": "Pasarelas conectadas",
"connectedSwitches": "Interruptores conectados"
},
"downloadstation": {
"download": "Descargar",
"upload": "Subir",
"leech": "Compañeros",
"seed": "Semilla"
},
"mikrotik": { "mikrotik": {
"cpuLoad": "Carga de la CPU", "cpuLoad": "Carga de la CPU",
"memoryUsed": "Memoria utilizada", "memoryUsed": "Memoria utilizada",
"uptime": "Tiempo en funcionamiento", "uptime": "Tiempo de la actividad",
"numberOfLeases": "Alquileres" "numberOfLeases": "Alquileres"
}, },
"xteve": { "xteve": {
@@ -447,6 +533,12 @@
"streams_active": "Transmisiones activas", "streams_active": "Transmisiones activas",
"streams_xepg": "Canales XEPG" "streams_xepg": "Canales XEPG"
}, },
"opendtu": {
"yieldDay": "Hoy",
"absolutePower": "Encender",
"relativePower": "Encender %",
"limit": "Límite"
},
"opnsense": { "opnsense": {
"cpu": "Carga de la CPU", "cpu": "Carga de la CPU",
"memory": "Memoria activa", "memory": "Memoria activa",
@@ -459,25 +551,30 @@
"print_progress": "Progreso", "print_progress": "Progreso",
"layers": "Capas" "layers": "Capas"
}, },
"medusa": {
"wanted": "Querido",
"queued": "A la espera",
"series": "Series"
},
"octoprint": { "octoprint": {
"temp_bed": "Temperatura de la plataforma",
"printer_state": "Estado", "printer_state": "Estado",
"temp_tool": "Temperatura de la herramienta", "temp_tool": "Temperatura de la herramienta",
"temp_bed": "Temperatura de la plataforma",
"job_completion": "Finalización" "job_completion": "Finalización"
}, },
"cloudflared": { "cloudflared": {
"origin_ip": "IP de origen", "origin_ip": "IP de origen",
"status": "Estado" "status": "Estado"
}, },
"pfsense": {
"load": "Promedio de carga",
"memory": "Memoria utilizada",
"wanStatus": "Estado de la WAN",
"up": "Arriba",
"down": "Abajo",
"temp": "Temperatura",
"disk": "Uso del disco",
"wanIP": "IP de la WAN"
},
"proxmoxbackupserver": { "proxmoxbackupserver": {
"cpu_usage": "CPU",
"datastore_usage": "Almacén de datos", "datastore_usage": "Almacén de datos",
"failed_tasks_24h": "Tareas fallidas en 24h", "failed_tasks_24h": "Tareas fallidas en 24h",
"cpu_usage": "CPU",
"memory_usage": "Memoria" "memory_usage": "Memoria"
}, },
"immich": { "immich": {
@@ -489,19 +586,30 @@
"uptimekuma": { "uptimekuma": {
"up": "Páginas web activas", "up": "Páginas web activas",
"down": "Páginas web inactivas", "down": "Páginas web inactivas",
"uptime": "Disponibilidad", "uptime": "Tiempo de la actividad",
"incident": "Incidencia", "incident": "Incidencia",
"m": "m" "m": "Minutos"
},
"atsumeru": {
"series": "Serie",
"archives": "Archivos",
"chapters": "Capítulos",
"categories": "Categorías"
}, },
"komga": { "komga": {
"libraries": "Librerías", "libraries": "Librerías",
"series": "Series", "series": "Serie",
"books": "Libros" "books": "Libros"
}, },
"diskstation": {
"days": "Días",
"uptime": "Tiempo de la actividad",
"volumeAvailable": "Disponible"
},
"mylar": { "mylar": {
"series": "Serie",
"issues": "Cuestiones", "issues": "Cuestiones",
"series": "Series", "wanted": "Buscando"
"wanted": "Buscado"
}, },
"photoprism": { "photoprism": {
"albums": "Álbumes", "albums": "Álbumes",
@@ -509,19 +617,14 @@
"videos": "Vídeos", "videos": "Vídeos",
"people": "Personas" "people": "Personas"
}, },
"diskstation": {
"days": "Días",
"uptime": "Funcionando",
"volumeAvailable": "Disponible"
},
"fileflows": { "fileflows": {
"queue": "Cola", "queue": "En cola",
"processing": "Procesando", "processing": "Procesando",
"processed": "Procesado", "processed": "Procesado",
"time": "Tiempo" "time": "Tiempo"
}, },
"grafana": { "grafana": {
"dashboards": "Dashboards", "dashboards": "Tableros",
"datasources": "Fuentes de datos", "datasources": "Fuentes de datos",
"totalalerts": "Alertas totales", "totalalerts": "Alertas totales",
"alertstriggered": "Alertas activadas" "alertstriggered": "Alertas activadas"
@@ -546,16 +649,6 @@
"total_workers": "Total de trabajadores", "total_workers": "Total de trabajadores",
"records_total": "Duración de la cola" "records_total": "Duración de la cola"
}, },
"healthchecks": {
"new": "Nuevo",
"up": "Conectado",
"down": "Desconectado",
"grace": "En Periodo de Gracia",
"paused": "Pausado",
"status": "Estado",
"last_ping": "Último ping",
"never": "Aún no hay pings"
},
"pterodactyl": { "pterodactyl": {
"servers": "Servidores", "servers": "Servidores",
"nodes": "Nodos" "nodes": "Nodos"
@@ -565,13 +658,6 @@
"targets_down": "Objetivos abajo", "targets_down": "Objetivos abajo",
"targets_total": "Objetivos totales" "targets_total": "Objetivos totales"
}, },
"minecraft": {
"status": "Estado",
"up": "En línea",
"players": "Jugadores",
"version": "Versión",
"down": "Sin conexión"
},
"ghostfolio": { "ghostfolio": {
"gross_percent_today": "Hoy", "gross_percent_today": "Hoy",
"gross_percent_1y": "Un año", "gross_percent_1y": "Un año",
@@ -588,93 +674,26 @@
"lights_on": "Luces encendidas", "lights_on": "Luces encendidas",
"switches_on": "Encendido" "switches_on": "Encendido"
}, },
"freshrss": {
"subscriptions": "Suscripciones",
"unread": "Sin leer"
},
"channelsdvrserver": {
"shows": "Espectáculos",
"recordings": "Grabaciones",
"scheduled": "Programado",
"passes": "Pases"
},
"whatsupdocker": { "whatsupdocker": {
"monitoring": "Supervisión", "monitoring": "Supervisión",
"updates": "Actualizaciones" "updates": "Actualizaciones"
}, },
"tailscale": { "calibreweb": {
"address": "Dirección", "books": "Libros",
"expires": "Caduca en", "authors": "Autores",
"never": "Nunca", "categories": "Categorías",
"last_seen": "Visto por última vez", "series": "Serie"
"now": "Ahora",
"years": "{{number}}años",
"hours": "{{number}}horas",
"minutes": "{{number}}minutos",
"seconds": "{{number}}segundos",
"ago": "Hace {{value}}",
"weeks": "{{number}}semanas",
"days": "{{number}}días"
},
"qnap": {
"cpuUsage": "Uso de la Cpu",
"memUsage": "Uso de la memoria",
"systemTempC": "Temperatura del sistema",
"poolUsage": "Comprobación del uso del grupo de memoria",
"volumeUsage": "Volumen utilizado",
"invalid": "No válido"
},
"pfsense": {
"load": "Promedio de carga",
"memory": "Memoria utilizada",
"wanStatus": "Estado de la WAN",
"up": "Arriba",
"down": "Abajo",
"temp": "Temperatura",
"disk": "Uso del disco",
"wanIP": "IP de la WAN"
},
"caddy": {
"upstreams": "Upstream (desarrollo de software)",
"requests": "Peticiones actuales",
"requests_failed": "Peticiones fallidas"
},
"evcc": {
"pv_power": "Producción",
"battery_soc": "Batería",
"grid_power": "Red",
"home_power": "Consumo",
"charge_power": "Cargador",
"watt_hour": "vatio-hora (Wh)"
},
"pialert": {
"total": "Total",
"connected": "Conectado",
"new_devices": "Nuevos dispositivos",
"down_alerts": "Alertas"
}, },
"jdownloader": { "jdownloader": {
"downloadCount": "Cola", "downloadCount": "En cola",
"downloadSpeed": "Velocidad",
"downloadBytesRemaining": "Restante", "downloadBytesRemaining": "Restante",
"downloadTotalBytes": "Tamaño" "downloadTotalBytes": "Tamaño",
"downloadSpeed": "Velocidad"
}, },
"kavita": { "kavita": {
"seriesCount": "Series", "seriesCount": "Serie",
"totalFiles": "Archivos" "totalFiles": "Archivos"
}, },
"gamedig": {
"name": "Nombre",
"map": "Mapa",
"currentPlayers": "Jugadores actuales",
"players": "Jugadores",
"maxPlayers": "Jugadores máximos",
"bots": "Bots",
"ping": "Ping",
"status": "Estado",
"online": "En línea",
"offline": "Sin conexión"
},
"azuredevops": { "azuredevops": {
"result": "Resultado", "result": "Resultado",
"status": "Estado", "status": "Estado",
@@ -686,7 +705,19 @@
"inProgress": "En curso", "inProgress": "En curso",
"totalPrs": "RP totales", "totalPrs": "RP totales",
"myPrs": "Mis logros", "myPrs": "Mis logros",
"approved": "Aprobados" "approved": "Aprobado"
},
"gamedig": {
"status": "Estado",
"online": "En línea",
"offline": "Desconectado",
"name": "Nombre",
"map": "Mapa",
"currentPlayers": "Jugadores actuales",
"players": "Jugadores",
"maxPlayers": "Jugadores máximos",
"bots": "Bots",
"ping": "Ping"
}, },
"urbackup": { "urbackup": {
"ok": "De acuerdo", "ok": "De acuerdo",
@@ -694,39 +725,27 @@
"noRecent": "Caducado", "noRecent": "Caducado",
"totalUsed": "Almacenamiento usado" "totalUsed": "Almacenamiento usado"
}, },
"openmediavault": {
"running": "Ejecutando",
"downloading": "Descargando",
"total": "Total",
"stopped": "Detenido",
"passed": "Aprobado",
"failed": "Fallido"
},
"mealie": { "mealie": {
"recipes": "Recetas", "recipes": "Recetas",
"users": "Usuarios", "users": "Usuarios",
"categories": "Categorías", "categories": "Categorías",
"tags": "Etiquetas" "tags": "Etiquetas"
}, },
"atsumeru": { "openmediavault": {
"series": "Series", "downloading": "Descargando",
"archives": "Archivos", "total": "Total",
"chapters": "Capítulos", "running": "Ejecutando",
"categories": "Categorías" "stopped": "Detenido",
}, "passed": "Aprobado",
"calibreweb": { "failed": "Fallido"
"books": "Libros",
"authors": "Autores",
"categories": "Categorías",
"series": "Series"
}, },
"uptimerobot": { "uptimerobot": {
"status": "Estado", "status": "Estado",
"uptime": "Tiempo de actividad", "uptime": "Tiempo de la actividad",
"lastDown": "Último periodo de inactividad", "lastDown": "Último periodo de inactividad",
"downDuration": "Tiempo de inactividad", "downDuration": "Tiempo de inactividad",
"sitesUp": "Páginas web con conexión", "sitesUp": "Páginas web activas",
"sitesDown": "Páginas web caídas", "sitesDown": "Páginas web inactivas",
"paused": "Pausado", "paused": "Pausado",
"notyetchecked": "Aún no verificado", "notyetchecked": "Aún no verificado",
"up": "Arriba", "up": "Arriba",
@@ -734,15 +753,9 @@
"down": "Abajo", "down": "Abajo",
"unknown": "Desconocido" "unknown": "Desconocido"
}, },
"opendtu": {
"relativePower": "Encender %",
"yieldDay": "Hoy",
"limit": "Límite",
"absolutePower": "Encender"
},
"calendar": { "calendar": {
"physicalRelease": "Physical release", "inCinemas": "En cine",
"inCinemas": "In cinemas", "physicalRelease": "Lanzamiento en físico",
"digitalRelease": "Digital release" "digitalRelease": "Lanzamiento en digital"
} }
} }

View File

@@ -140,7 +140,9 @@
}, },
"ping": { "ping": {
"error": "Errorea", "error": "Errorea",
"ping": "Ping" "ping": "Ping",
"up": "Up",
"down": "Down"
}, },
"emby": { "emby": {
"playing": "Playing", "playing": "Playing",

View File

@@ -382,7 +382,9 @@
}, },
"ping": { "ping": {
"error": "Error", "error": "Error",
"ping": "Ping" "ping": "Ping",
"up": "Up",
"down": "Down"
}, },
"scrutiny": { "scrutiny": {
"passed": "Passed", "passed": "Passed",

View File

@@ -1,46 +1,90 @@
{ {
"common": {
"bytes": "{{value, bytes}}",
"bits": "{{value, bytes(bits: true)}}",
"bbytes": "{{value, bytes(binary: true)}}",
"bbits": "{{value, bytes(bits: true; binary: true)}}",
"byterate": "{{value, rate(bits: false)}}",
"bibyterate": "{{value, rate(bits: false; binary: true)}}",
"bitrate": "{{value, rate(bits: true)}}",
"bibitrate": "{{value, rate(bits: true; binary: true)}}",
"percent": "{{value, percent}}",
"number": "{{value, number}}",
"ms": "{{value, number}}"
},
"widget": { "widget": {
"missing_type": "Type de widget manquant: {{type}}", "missing_type": "Type de widget manquant: {{type}}",
"api_error": "Erreur de l'API", "api_error": "Erreur de l'API",
"status": "Statut",
"information": "Information", "information": "Information",
"status": "Statut",
"url": "URL", "url": "URL",
"raw_error": "Erreur brute", "raw_error": "Erreur brute",
"response_data": "Données de réponse" "response_data": "Données de réponse"
}, },
"weather": {
"current": "Localisation actuelle",
"allow": "Cliquez pour autoriser",
"updating": "Mise à jour",
"wait": "Veuillez patienter"
},
"search": { "search": {
"placeholder": "Recherche…" "placeholder": "Recherche…"
}, },
"resources": { "resources": {
"cpu": "CPU",
"mem": "MÉM",
"total": "Total", "total": "Total",
"free": "Libre", "free": "Libre",
"used": "Utilisé", "used": "Utilisé",
"load": "Charge", "load": "Charge",
"cpu": "CPU",
"mem": "MÉM",
"max": "Max",
"temp": "TEMP", "temp": "TEMP",
"max": "Max",
"uptime": "UP", "uptime": "UP",
"months": "mo", "months": "mo",
"days": "d", "days": "d",
"hours": "h", "hours": "h",
"minutes": "mn" "minutes": "mn"
}, },
"unifi": {
"users": "Utilisateurs",
"uptime": "Disponibilité du système",
"days": "Jours",
"wan": "WAN",
"lan": "LAN",
"wlan": "WLAN",
"devices": "Équipt.",
"lan_devices": "Équipt. LAN",
"wlan_devices": "Équipt. WLAN",
"lan_users": "Utilisateurs LAN",
"wlan_users": "Utilisateurs WLAN",
"up": "UP",
"down": "DOWN",
"wait": "Veuillez patienter",
"empty_data": "Statut sous-système inconnu"
},
"docker": { "docker": {
"rx": "Rx", "rx": "Rx",
"tx": "Tx", "tx": "Tx",
"mem": "Mém", "mem": "MÉM",
"cpu": "Cpu", "cpu": "CPU",
"running": "Démarré",
"offline": "Hors ligne", "offline": "Hors ligne",
"error": "Erreur", "error": "Erreur",
"unknown": "Inconnu", "unknown": "Inconnu",
"running": "Démarré", "healthy": "Fonctionnel",
"starting": "Démarrage", "starting": "Démarrage",
"unhealthy": "Dysfonctionnement", "unhealthy": "Dysfonctionnement",
"not_found": "Inconnu", "not_found": "Inconnu",
"exited": "Arrêté", "exited": "Arrêté",
"partial": "Partiel", "partial": "Partiel"
"healthy": "Fonctionnel" },
"ping": {
"http_status": "État HTTP",
"error": "Erreur",
"ping": "Ping",
"down": "Down",
"up": "Up",
"not_available": "Non disponible"
}, },
"emby": { "emby": {
"playing": "En lecture", "playing": "En lecture",
@@ -52,6 +96,39 @@
"episodes": "Épisodes", "episodes": "Épisodes",
"songs": "Musique" "songs": "Musique"
}, },
"evcc": {
"pv_power": "Production",
"battery_soc": "Batterie",
"grid_power": "Grille",
"home_power": "Consommation",
"charge_power": "Chargeur",
"watt_hour": "Wh"
},
"flood": {
"download": "Récep.",
"upload": "Envoi",
"leech": "Leech",
"seed": "Seed"
},
"freshrss": {
"subscriptions": "Abonnements",
"unread": "Non lu"
},
"caddy": {
"upstreams": "Upstreams",
"requests": "Demandes en cours",
"requests_failed": "Demandes échouées"
},
"changedetectionio": {
"totalObserved": "Total Observé",
"diffsDetected": "Diffs Detectées"
},
"channelsdvrserver": {
"shows": "Affichages",
"recordings": "Enregistrements",
"scheduled": "Planifié",
"passes": "Passes"
},
"tautulli": { "tautulli": {
"playing": "En lecture", "playing": "En lecture",
"transcoding": "Transcodage", "transcoding": "Transcodage",
@@ -59,31 +136,95 @@
"no_active": "Aucun flux actif", "no_active": "Aucun flux actif",
"plex_connection_error": "Vérifier la connexion à Plex" "plex_connection_error": "Vérifier la connexion à Plex"
}, },
"omada": {
"connectedAp": "APs connectées",
"activeUser": "Équipts actifs",
"alerts": "Alertes",
"connectedGateway": "Passerelles connectées",
"connectedSwitches": "Switches connectés"
},
"nzbget": {
"rate": "Débit",
"remaining": "Restant",
"downloaded": "Téléchargé"
},
"plex": {
"streams": "Flux actif",
"albums": "Albums",
"movies": "Films",
"tv": "Séries TV"
},
"sabnzbd": {
"rate": "Débit",
"queue": "En attente",
"timeleft": "Temps restant"
},
"rutorrent": { "rutorrent": {
"active": "Actif", "active": "Actif",
"upload": "Envoi", "upload": "Envoi",
"download": "Réception" "download": "Récep."
},
"transmission": {
"download": "Récep.",
"upload": "Envoi",
"leech": "Leech",
"seed": "Seed"
},
"qbittorrent": {
"download": "Récep.",
"upload": "Envoi",
"leech": "Leech",
"seed": "Seed"
},
"qnap": {
"cpuUsage": "Cpu",
"memUsage": "Mém",
"systemTempC": "Temp",
"poolUsage": "Pool",
"volumeUsage": "Volume",
"invalid": "Invalide"
},
"deluge": {
"download": "Récep.",
"upload": "Envoi",
"leech": "Leech",
"seed": "Seed"
},
"downloadstation": {
"download": "Récep.",
"upload": "Envoi",
"leech": "Leech",
"seed": "Seed"
}, },
"sonarr": { "sonarr": {
"wanted": "Demande", "wanted": "Demande",
"queued": "Attente", "queued": "Attente",
"series": "Séries", "series": "Séries TV",
"queue": "Attente", "queue": "En attente",
"unknown": "Inconnu" "unknown": "Inconnu"
}, },
"radarr": { "radarr": {
"wanted": "Demande", "wanted": "Demande",
"missing": "Manquant",
"queued": "Attente", "queued": "Attente",
"movies": "Films", "movies": "Films",
"missing": "Manquant", "queue": "En attente",
"queue": "Attente",
"unknown": "Inconnu" "unknown": "Inconnu"
}, },
"lidarr": {
"wanted": "Demande",
"queued": "Attente",
"artists": "Artistes"
},
"readarr": { "readarr": {
"wanted": "Demande", "wanted": "Demande",
"queued": "Attente", "queued": "Attente",
"books": "Livres" "books": "Livres"
}, },
"bazarr": {
"missingEpisodes": "Épisodes manquants",
"missingMovies": "Films manquants"
},
"ombi": { "ombi": {
"pending": "En attente", "pending": "En attente",
"approved": "Validé", "approved": "Validé",
@@ -94,11 +235,29 @@
"approved": "Validé", "approved": "Validé",
"available": "Disponible" "available": "Disponible"
}, },
"overseerr": {
"pending": "En attente",
"processing": "Traitement",
"approved": "Validé",
"available": "Disponible"
},
"pialert": {
"total": "Total",
"connected": "Connecté",
"new_devices": "Nouvel Appareil",
"down_alerts": "Alertes"
},
"pihole": { "pihole": {
"queries": "Requêtes", "queries": "Requêtes",
"blocked": "Bloqué", "blocked": "Bloqué",
"gravity": "Listes dom. bloqués", "blocked_percent": "Bloqué %",
"blocked_percent": "Bloqué %" "gravity": "Listes dom. bloqués"
},
"adguard": {
"queries": "Requêtes",
"blocked": "Bloqué",
"filtered": "Filtrées",
"latency": "Latence"
}, },
"speedtest": { "speedtest": {
"upload": "Envoi", "upload": "Envoi",
@@ -110,38 +269,40 @@
"stopped": "Arrêté", "stopped": "Arrêté",
"total": "Total" "total": "Total"
}, },
"tailscale": {
"address": "Adresse",
"expires": "Expire",
"never": "Jamais",
"last_seen": "Vu pour la dernière fois",
"now": "Maintenant",
"years": "{{number}}y",
"weeks": "{{number}}w",
"days": "{{number}}d",
"hours": "{{number}}h",
"minutes": "{{number}}m",
"seconds": "{{number}}s",
"ago": "Il y a {{value}}"
},
"tdarr": {
"queue": "En attente",
"processed": "Traité",
"errored": "En erreur",
"saved": "Libéré"
},
"traefik": { "traefik": {
"routers": "Routeurs", "routers": "Routeurs",
"services": "Services", "services": "Services",
"middleware": "Middleware" "middleware": "Middleware"
}, },
"navidrome": {
"nothing_streaming": "Aucun flux actif",
"please_wait": "Merci de patienter"
},
"npm": { "npm": {
"enabled": "Activé", "enabled": "Activé",
"disabled": "Désactivé", "disabled": "Désactivé",
"total": "Total" "total": "Total"
}, },
"weather": {
"current": "Localisation actuelle",
"allow": "Cliquez pour autoriser",
"updating": "Mise à jour",
"wait": "Veuillez patienter"
},
"overseerr": {
"pending": "Attente",
"approved": "Demande",
"available": "Disponible",
"processing": "Traitement"
},
"sabnzbd": {
"rate": "Débit",
"queue": "En attente",
"timeleft": "Temps restant"
},
"nzbget": {
"remaining": "Restant",
"downloaded": "Téléchargé",
"rate": "Débit"
},
"coinmarketcap": { "coinmarketcap": {
"configure": "Configurer une ou plusieurs crypto-monnaies à suivre", "configure": "Configurer une ou plusieurs crypto-monnaies à suivre",
"1hour": "1 Heure", "1hour": "1 Heure",
@@ -157,123 +318,89 @@
"prowlarr": { "prowlarr": {
"enableIndexers": "Indexeur", "enableIndexers": "Indexeur",
"numberOfGrabs": "Capture", "numberOfGrabs": "Capture",
"numberOfQueries": "Demande", "numberOfQueries": "Requêtes",
"numberOfFailGrabs": "Capt. échouée", "numberOfFailGrabs": "Capt. échouée",
"numberOfFailQueries": "Dem. échouée" "numberOfFailQueries": "Dem. échouée"
}, },
"transmission": {
"download": "Réception",
"upload": "Envoi",
"leech": "Leech",
"seed": "Seed"
},
"jackett": { "jackett": {
"configured": "Configuré", "configured": "Configuré",
"errored": "En erreur" "errored": "En erreur"
}, },
"bazarr": {
"missingEpisodes": "Épisodes manquants",
"missingMovies": "Films manquants"
},
"lidarr": {
"wanted": "Demandé",
"queued": "En queue",
"artists": "Artistes"
},
"adguard": {
"queries": "Requêtes",
"blocked": "Bloquées",
"filtered": "Filtrées",
"latency": "Latence"
},
"qbittorrent": {
"download": "Récep.",
"upload": "Envoi",
"leech": "Leech",
"seed": "Seed"
},
"mastodon": {
"user_count": "Utilisateurs",
"status_count": "Messages",
"domain_count": "Domaines"
},
"strelaysrv": { "strelaysrv": {
"numActiveSessions": "Sessions", "numActiveSessions": "Sessions",
"numConnections": "Cnx", "numConnections": "Cnx",
"dataRelayed": "Relayé", "dataRelayed": "Relayé",
"transferRate": "Débit" "transferRate": "Débit"
}, },
"mastodon": {
"user_count": "Utilisateurs",
"status_count": "Messages",
"domain_count": "Domaines"
},
"medusa": {
"wanted": "Demande",
"queued": "Attente",
"series": "Séries TV"
},
"minecraft": {
"players": "Joueurs",
"version": "Version",
"status": "Statut",
"up": "En ligne",
"down": "Hors ligne"
},
"miniflux": {
"read": "Lu",
"unread": "Non lu"
},
"authentik": { "authentik": {
"users": "Utilisateurs", "users": "Utilisateurs",
"loginsLast24H": "Cnx. (24h)", "loginsLast24H": "Cnx. (24h)",
"failedLoginsLast24H": "Cnx. échouées (24h)" "failedLoginsLast24H": "Cnx. échouées (24h)"
}, },
"proxmox": { "proxmox": {
"mem": "Mém", "mem": "MÉM",
"cpu": "Cpu", "cpu": "CPU",
"lxc": "LxC", "lxc": "LxC",
"vms": "VMs" "vms": "VMs"
}, },
"unifi": {
"users": "Utilisateurs",
"uptime": "Disponibilité du système",
"days": "Jours",
"wan": "WAN",
"lan_users": "Utilisateurs LAN",
"wlan_users": "Utilisateurs WLAN",
"up": "UP",
"down": "DOWN",
"wait": "Merci de patienter",
"lan": "LAN",
"wlan": "WLAN",
"devices": "Équipt.",
"lan_devices": "Équipt. LAN",
"wlan_devices": "Équipt. WLAN",
"empty_data": "Statut sous-système inconnu"
},
"plex": {
"streams": "Flux actif",
"movies": "Films",
"tv": "Séries TV",
"albums": "Albums"
},
"glances": { "glances": {
"cpu": "Cpu", "cpu": "CPU",
"wait": "Merci de patienter",
"temp": "Temp",
"uptime": "Up",
"days": "j",
"hours": "h",
"load": "Charge", "load": "Charge",
"wait": "Veuillez patienter",
"temp": "TEMP",
"_temp": "Temp",
"warn": "Alerte", "warn": "Alerte",
"uptime": "UP",
"total": "Total", "total": "Total",
"free": "Libre", "free": "Libre",
"used": "Utilisé", "used": "Utilisé",
"days": "d",
"hours": "h",
"crit": "Crit.", "crit": "Crit.",
"read": "Lect.", "read": "Lu",
"write": "Écrit.", "write": "Écrit.",
"gpu": "GPU", "gpu": "GPU",
"mem": "Mém.", "mem": "Mém.",
"swap": "Swap", "swap": "Swap"
"_temp": "Temp"
}, },
"changedetectionio": { "quicklaunch": {
"totalObserved": "Total Observé", "bookmark": "Signet",
"diffsDetected": "Diffs Detectées" "service": "Service",
"search": "Recherche",
"custom": "Personnalisé",
"visit": "Aller vers",
"url": "URL"
}, },
"wmo": { "wmo": {
"0-day": "Ensoleillé",
"0-night": "Ciel clair",
"1-day": "Principalement ensoleillé", "1-day": "Principalement ensoleillé",
"1-night": "Principalement clair", "1-night": "Principalement clair",
"2-day": "Partiellement couvert", "2-day": "Partiellement couvert",
"2-night": "Partiellement couvert", "2-night": "Partiellement couvert",
"3-day": "Couvert", "3-day": "Couvert",
"3-night": "Couvert", "3-night": "Couvert",
"63-night": "Pluie",
"65-day": "Pluie forte",
"85-day": "Averses de neige",
"85-night": "Averses de neige",
"86-day": "Averses de neige",
"0-night": "Ciel clair",
"45-day": "Brumeux", "45-day": "Brumeux",
"45-night": "Brumeux", "45-night": "Brumeux",
"48-day": "Brumeux", "48-day": "Brumeux",
@@ -291,6 +418,8 @@
"61-day": "Pluie légère", "61-day": "Pluie légère",
"61-night": "Pluie légère", "61-night": "Pluie légère",
"63-day": "Pluie", "63-day": "Pluie",
"63-night": "Pluie",
"65-day": "Pluie forte",
"65-night": "Pluie forte", "65-night": "Pluie forte",
"66-day": "Pluie verglaçante", "66-day": "Pluie verglaçante",
"66-night": "Pluie verglaçante", "66-night": "Pluie verglaçante",
@@ -310,22 +439,16 @@
"81-night": "Averses", "81-night": "Averses",
"82-day": "Averses fortes", "82-day": "Averses fortes",
"82-night": "Averses fortes", "82-night": "Averses fortes",
"85-day": "Averses de neige",
"85-night": "Averses de neige",
"86-day": "Averses de neige",
"86-night": "Averses de neige", "86-night": "Averses de neige",
"95-day": "Orage", "95-day": "Orage",
"95-night": "Orage", "95-night": "Orage",
"96-day": "Orage avec grêle", "96-day": "Orage avec grêle",
"96-night": "Orage avec grêle", "96-night": "Orage avec grêle",
"99-day": "Orage avec grêle", "99-day": "Orage avec grêle",
"99-night": "Orage avec grêle", "99-night": "Orage avec grêle"
"0-day": "Ensoleillé"
},
"quicklaunch": {
"bookmark": "Signet",
"service": "Service",
"search": "Recherche",
"custom": "Personnalisé",
"visit": "Aller vers",
"url": "URL"
}, },
"homebridge": { "homebridge": {
"available_update": "Système", "available_update": "Système",
@@ -335,22 +458,32 @@
"child_bridges": "Child Bridges", "child_bridges": "Child Bridges",
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Up",
"pending": "Pending", "pending": "En attente",
"down": "Down" "down": "Down"
}, },
"autobrr": { "healthchecks": {
"approvedPushes": "Approuvé", "new": "Nouveau",
"rejectedPushes": "Rejeté", "up": "En ligne",
"filters": "Filtres", "grace": "En Période de Grâce",
"indexers": "Indexeur" "down": "Hors ligne",
"paused": "En Pause",
"status": "Statut",
"last_ping": "Dernier Ping",
"never": "Pas de Ping"
}, },
"watchtower": { "watchtower": {
"containers_scanned": "Scanné", "containers_scanned": "Scanné",
"containers_updated": "Mis à jour", "containers_updated": "Mis à jour",
"containers_failed": "Échoué" "containers_failed": "Échoué"
}, },
"autobrr": {
"approvedPushes": "Validé",
"rejectedPushes": "Rejeté",
"filters": "Filtres",
"indexers": "Indexeur"
},
"tubearchivist": { "tubearchivist": {
"downloads": "Queue", "downloads": "En attente",
"videos": "Vidéos", "videos": "Vidéos",
"channels": "Chaînes", "channels": "Chaînes",
"playlists": "Playlists" "playlists": "Playlists"
@@ -361,14 +494,10 @@
"alerts": "Alertes", "alerts": "Alertes",
"time": "{{value, number(style: unit; unitDisplay: long;)}}" "time": "{{value, number(style: unit; unitDisplay: long;)}}"
}, },
"navidrome": {
"nothing_streaming": "Aucun flux actif",
"please_wait": "Merci de patienter"
},
"pyload": { "pyload": {
"speed": "Débit", "speed": "Débit",
"active": "Actif", "active": "Actif",
"queue": "Queue", "queue": "En attente",
"total": "Total" "total": "Total"
}, },
"gluetun": { "gluetun": {
@@ -377,13 +506,9 @@
"country": "Pays" "country": "Pays"
}, },
"hdhomerun": { "hdhomerun": {
"channels": "Canaux", "channels": "Chaînes",
"hd": "HD" "hd": "HD"
}, },
"ping": {
"error": "Erreur",
"ping": "Ping"
},
"scrutiny": { "scrutiny": {
"passed": "Réussi", "passed": "Réussi",
"failed": "Échoué", "failed": "Échoué",
@@ -393,53 +518,14 @@
"inbox": "Boîte de réception", "inbox": "Boîte de réception",
"total": "Total" "total": "Total"
}, },
"deluge": {
"download": "Récep.",
"upload": "Envoi",
"leech": "Leech",
"seed": "Seed"
},
"flood": {
"download": "Récep.",
"upload": "Envoi",
"leech": "Leech",
"seed": "Seed"
},
"tdarr": {
"queue": "À traiter",
"processed": "Traité",
"errored": "En erreur",
"saved": "Libéré"
},
"miniflux": {
"read": "Lu",
"unread": "Non lu"
},
"nextdns": { "nextdns": {
"wait": "Patientez...", "wait": "Merci de patienter",
"no_devices": "Aucune donnée d'appareil reçue" "no_devices": "Aucune donnée d'appareil reçue"
}, },
"common": {
"bibitrate": "{{value, rate(bits: true; binary: true)}}",
"bibyterate": "{{value, rate(bits: false; binary: true)}}"
},
"omada": {
"connectedAp": "APs connectées",
"activeUser": "Équipts actifs",
"alerts": "Alertes",
"connectedGateway": "Passerelles connectées",
"connectedSwitches": "Switches connectés"
},
"downloadstation": {
"download": "Récep.",
"upload": "Envoi",
"leech": "Leech",
"seed": "Seed"
},
"mikrotik": { "mikrotik": {
"cpuLoad": "Charge CPU", "cpuLoad": "Charge CPU",
"memoryUsed": "Mém. Utilisée", "memoryUsed": "Mém. Utilisée",
"uptime": "Disponibilité", "uptime": "Démarré depuis",
"numberOfLeases": "Baux" "numberOfLeases": "Baux"
}, },
"xteve": { "xteve": {
@@ -447,6 +533,12 @@
"streams_active": "Flux actif", "streams_active": "Flux actif",
"streams_xepg": "Canal XEPG" "streams_xepg": "Canal XEPG"
}, },
"opendtu": {
"yieldDay": "Aujourd'hui",
"absolutePower": "Puissance",
"relativePower": "Puissance %",
"limit": "Limite"
},
"opnsense": { "opnsense": {
"cpu": "Charge CPU", "cpu": "Charge CPU",
"memory": "Mém. Utilisée", "memory": "Mém. Utilisée",
@@ -459,13 +551,8 @@
"print_progress": "Progression", "print_progress": "Progression",
"layers": "Couches" "layers": "Couches"
}, },
"medusa": {
"wanted": "Demande",
"queued": "En attente",
"series": "Séries"
},
"octoprint": { "octoprint": {
"printer_state": "Status", "printer_state": "Statut",
"temp_tool": "Tool temp", "temp_tool": "Tool temp",
"temp_bed": "Bed temp", "temp_bed": "Bed temp",
"job_completion": "Achèvement" "job_completion": "Achèvement"
@@ -474,6 +561,16 @@
"origin_ip": "IP Publique", "origin_ip": "IP Publique",
"status": "Statut" "status": "Statut"
}, },
"pfsense": {
"load": "Charge moy.",
"memory": "Util. Mém.",
"wanStatus": "Statut WAN",
"up": "Up",
"down": "Down",
"temp": "Temp",
"disk": "Util. Disque",
"wanIP": "IP WAN"
},
"proxmoxbackupserver": { "proxmoxbackupserver": {
"datastore_usage": "Datastore", "datastore_usage": "Datastore",
"failed_tasks_24h": "Tâches échouées 24h", "failed_tasks_24h": "Tâches échouées 24h",
@@ -489,17 +586,28 @@
"uptimekuma": { "uptimekuma": {
"up": "En ligne", "up": "En ligne",
"down": "Hors ligne", "down": "Hors ligne",
"uptime": "Dispo.", "uptime": "Démarré depuis",
"incident": "Incident", "incident": "Incident",
"m": "m" "m": "mn"
},
"atsumeru": {
"series": "Séries TV",
"archives": "Archives",
"chapters": "Chapitres",
"categories": "Catégories"
}, },
"komga": { "komga": {
"libraries": "Librairies", "libraries": "Librairies",
"series": "Séries", "series": "Séries TV",
"books": "Livres" "books": "Livres"
}, },
"diskstation": {
"days": "Jours",
"uptime": "Démarré depuis",
"volumeAvailable": "Disponible"
},
"mylar": { "mylar": {
"series": "Séries", "series": "Séries TV",
"issues": "Issues", "issues": "Issues",
"wanted": "Demande" "wanted": "Demande"
}, },
@@ -509,13 +617,8 @@
"videos": "Vidéos", "videos": "Vidéos",
"people": "Personnes" "people": "Personnes"
}, },
"diskstation": {
"days": "Jours",
"uptime": "Fonctionnement",
"volumeAvailable": "Disponible"
},
"fileflows": { "fileflows": {
"queue": "À traiter", "queue": "En attente",
"processing": "Traitement", "processing": "Traitement",
"processed": "Traité", "processed": "Traité",
"time": "Temps" "time": "Temps"
@@ -527,10 +630,10 @@
"alertstriggered": "Alertes déclenchées" "alertstriggered": "Alertes déclenchées"
}, },
"nextcloud": { "nextcloud": {
"freespace": "Espace Libre",
"activeusers": "Utilisateurs Actifs",
"cpuload": "Charge Cpu", "cpuload": "Charge Cpu",
"memoryusage": "Utilisation Mémoire", "memoryusage": "Utilisation Mémoire",
"freespace": "Libre",
"activeusers": "Utilisateurs Actifs",
"numfiles": "Fichiers", "numfiles": "Fichiers",
"numshares": "Partages" "numshares": "Partages"
}, },
@@ -539,23 +642,13 @@
"size": "Taille", "size": "Taille",
"lastrun": "Dernière exécution", "lastrun": "Dernière exécution",
"nextrun": "Prochaine exécution", "nextrun": "Prochaine exécution",
"failed": "En erreur" "failed": "Échoué"
}, },
"unmanic": { "unmanic": {
"active_workers": "En cours", "active_workers": "En cours",
"total_workers": "Total", "total_workers": "Total",
"records_total": "En attente" "records_total": "En attente"
}, },
"healthchecks": {
"new": "Nouveau",
"up": "En ligne",
"grace": "En Période de Grâce",
"down": "Hors ligne",
"paused": "En Pause",
"status": "Statut",
"last_ping": "Dernier Ping",
"never": "Pas de Ping"
},
"pterodactyl": { "pterodactyl": {
"servers": "Serveurs", "servers": "Serveurs",
"nodes": "Nœuds" "nodes": "Nœuds"
@@ -565,13 +658,6 @@
"targets_down": "Targets Down", "targets_down": "Targets Down",
"targets_total": "Total Targets" "targets_total": "Total Targets"
}, },
"minecraft": {
"players": "Joueurs",
"version": "Version",
"status": "Statut",
"up": "En ligne",
"down": "Hors ligne"
},
"ghostfolio": { "ghostfolio": {
"gross_percent_today": "Aujourd'hui", "gross_percent_today": "Aujourd'hui",
"gross_percent_1y": "Un an", "gross_percent_1y": "Un an",
@@ -588,93 +674,26 @@
"lights_on": "Lumières allumées", "lights_on": "Lumières allumées",
"switches_on": "Commutateur On" "switches_on": "Commutateur On"
}, },
"freshrss": {
"unread": "Non lu",
"subscriptions": "Abonnements"
},
"channelsdvrserver": {
"shows": "Affichages",
"recordings": "Enregistrements",
"scheduled": "Planifié",
"passes": "Passes"
},
"whatsupdocker": { "whatsupdocker": {
"monitoring": "Conteneurs", "monitoring": "Conteneurs",
"updates": "Mises à jour" "updates": "Mises à jour"
}, },
"tailscale": { "calibreweb": {
"address": "Adresse", "books": "Livres",
"expires": "Expire", "authors": "Auteurs",
"never": "Jamais", "categories": "Catégories",
"last_seen": "Vu pour la dernière fois", "series": "Séries TV"
"now": "Maintenant",
"years": "{{number}}y",
"weeks": "{{number}}w",
"days": "{{number}}d",
"hours": "{{number}}h",
"minutes": "{{number}}m",
"seconds": "{{number}}s",
"ago": "Il y a {{value}}"
},
"qnap": {
"cpuUsage": "Cpu",
"memUsage": "Mém",
"systemTempC": "Temp",
"poolUsage": "Pool",
"volumeUsage": "Volume",
"invalid": "Invalide"
},
"pfsense": {
"load": "Charge moy.",
"memory": "Util. Mém.",
"wanStatus": "Statut WAN",
"up": "Up",
"down": "Down",
"temp": "Temp",
"disk": "Util. Disque",
"wanIP": "IP WAN"
},
"caddy": {
"upstreams": "Upstreams",
"requests": "Demandes en cours",
"requests_failed": "Demandes échouées"
},
"evcc": {
"pv_power": "Production",
"battery_soc": "Batterie",
"grid_power": "Grille",
"home_power": "Consommation",
"charge_power": "Chargeur",
"watt_hour": "Wh"
},
"pialert": {
"total": "Total",
"connected": "Connecté",
"new_devices": "Nouvel Appareil",
"down_alerts": "Alertes"
}, },
"jdownloader": { "jdownloader": {
"downloadCount": "Total en attente", "downloadCount": "En attente",
"downloadSpeed": "Vitesse de téléchargement",
"downloadBytesRemaining": "Restant", "downloadBytesRemaining": "Restant",
"downloadTotalBytes": "Taille" "downloadTotalBytes": "Taille",
"downloadSpeed": "Débit"
}, },
"kavita": { "kavita": {
"seriesCount": "Séries", "seriesCount": "Séries TV",
"totalFiles": "Fichiers" "totalFiles": "Fichiers"
}, },
"gamedig": {
"name": "Nom",
"map": "Carte",
"currentPlayers": "Joueurs actuels",
"players": "Joueurs",
"maxPlayers": "Joueurs max",
"bots": "Bots",
"ping": "Ping",
"status": "Statut",
"online": "En ligne",
"offline": "Hors ligne"
},
"azuredevops": { "azuredevops": {
"result": "Résultat", "result": "Résultat",
"status": "Statut", "status": "Statut",
@@ -686,7 +705,19 @@
"inProgress": "En cours", "inProgress": "En cours",
"totalPrs": "PRs Total", "totalPrs": "PRs Total",
"myPrs": "Mes PRs", "myPrs": "Mes PRs",
"approved": "Approuvé" "approved": "Validé"
},
"gamedig": {
"status": "Statut",
"online": "En ligne",
"offline": "Hors ligne",
"name": "Nom",
"map": "Carte",
"currentPlayers": "Joueurs actuels",
"players": "Joueurs",
"maxPlayers": "Joueurs max",
"bots": "Bots",
"ping": "Ping"
}, },
"urbackup": { "urbackup": {
"ok": "Ok", "ok": "Ok",
@@ -694,6 +725,12 @@
"noRecent": "Obsolète", "noRecent": "Obsolète",
"totalUsed": "Esp. Utilisé" "totalUsed": "Esp. Utilisé"
}, },
"mealie": {
"recipes": "Recettes",
"users": "Utilisateurs",
"categories": "Catégories",
"tags": "Étiquettes"
},
"openmediavault": { "openmediavault": {
"downloading": "Téléchargement", "downloading": "Téléchargement",
"total": "Total", "total": "Total",
@@ -702,47 +739,23 @@
"passed": "Réussi", "passed": "Réussi",
"failed": "Échoué" "failed": "Échoué"
}, },
"mealie": {
"recipes": "Recettes",
"users": "Utilisateurs",
"categories": "Catégories",
"tags": "Étiquettes"
},
"atsumeru": {
"series": "Séries",
"archives": "Archives",
"chapters": "Chapitres",
"categories": "Catégories"
},
"calibreweb": {
"series": "Séries",
"books": "Ebooks",
"authors": "Auteurs",
"categories": "Catégories"
},
"uptimerobot": { "uptimerobot": {
"status": "Statut", "status": "Statut",
"uptime": "Disponibilité", "uptime": "Démarré depuis",
"lastDown": "Dernière interruption", "lastDown": "Dernière interruption",
"downDuration": "Durée d'interruption", "downDuration": "Durée d'interruption",
"sitesUp": "Sites en ligne", "sitesUp": "En ligne",
"sitesDown": "Sites hors ligne", "sitesDown": "Hors ligne",
"paused": "En pause", "paused": "En Pause",
"notyetchecked": "Non vérifié", "notyetchecked": "Non vérifié",
"up": "En ligne", "up": "Up",
"seemsdown": "Semble hors ligne", "seemsdown": "Semble hors ligne",
"down": "Hors ligne", "down": "Down",
"unknown": "Inconnu" "unknown": "Inconnu"
}, },
"opendtu": {
"relativePower": "Puissance %",
"yieldDay": "Aujourd'hui",
"limit": "Limite",
"absolutePower": "Puissance"
},
"calendar": { "calendar": {
"physicalRelease": "Physical release", "inCinemas": "En salle",
"inCinemas": "In cinemas", "physicalRelease": "Sortie physique",
"digitalRelease": "Digital release" "digitalRelease": "Sortie numérique"
} }
} }

View File

@@ -382,7 +382,9 @@
}, },
"ping": { "ping": {
"error": "Error", "error": "Error",
"ping": "Ping" "ping": "Ping",
"up": "Up",
"down": "Down"
}, },
"scrutiny": { "scrutiny": {
"passed": "Passed", "passed": "Passed",

View File

@@ -382,7 +382,9 @@
}, },
"ping": { "ping": {
"error": "Error", "error": "Error",
"ping": "Ping" "ping": "Ping",
"up": "Up",
"down": "Down"
}, },
"scrutiny": { "scrutiny": {
"passed": "Passed", "passed": "Passed",

View File

@@ -382,7 +382,9 @@
}, },
"ping": { "ping": {
"error": "Greška", "error": "Greška",
"ping": "Ping" "ping": "Ping",
"up": "Up",
"down": "Down"
}, },
"scrutiny": { "scrutiny": {
"passed": "Uspjelo", "passed": "Uspjelo",

View File

@@ -382,7 +382,9 @@
}, },
"ping": { "ping": {
"error": "Hiba", "error": "Hiba",
"ping": "Ping" "ping": "Ping",
"up": "Up",
"down": "Down"
}, },
"scrutiny": { "scrutiny": {
"passed": "Megfelelt", "passed": "Megfelelt",

View File

@@ -610,7 +610,9 @@
}, },
"ping": { "ping": {
"error": "Error", "error": "Error",
"ping": "Ping" "ping": "Ping",
"up": "Up",
"down": "Down"
}, },
"emby": { "emby": {
"playing": "Playing", "playing": "Playing",

File diff suppressed because it is too large Load Diff

View File

@@ -1,58 +1,21 @@
{ {
"navidrome": {
"nothing_streaming": "アクティブストリームなし",
"please_wait": "お待ちください"
},
"npm": {
"total": "合計",
"enabled": "有効",
"disabled": "無効"
},
"strelaysrv": {
"numActiveSessions": "セッション",
"numConnections": "コネクション",
"dataRelayed": "中継",
"transferRate": "レート"
},
"glances": {
"cpu": "CPU",
"wait": "お待ちください",
"temp": "温度",
"uptime": "UP",
"days": "日",
"hours": "時間",
"load": "ロード",
"warn": "警告",
"total": "トータル",
"free": "空き",
"used": "使用中",
"crit": "Crit",
"read": "読み込み",
"write": "書き込み",
"gpu": "GPU",
"mem": "メモリ",
"swap": "スワップ",
"_temp": "Temp"
},
"autobrr": {
"filters": "フィルター",
"indexers": "Indexers",
"approvedPushes": "承認済",
"rejectedPushes": "却下"
},
"gluetun": {
"region": "地域",
"country": "国",
"public_ip": "パブリックIP"
},
"common": { "common": {
"bytes": "{{value, bytes}}",
"bits": "{{value, bytes(bits: true)}}",
"bbytes": "{{value, bytes(binary: true)}}",
"bbits": "{{value, bytes(bits: true; binary: true)}}",
"byterate": "{{value, rate(bits: false)}}",
"bibyterate": "{{value, rate(bits: false; binary: true)}}", "bibyterate": "{{value, rate(bits: false; binary: true)}}",
"bibitrate": "{{value, rate(bits: true; binary: true)}}" "bitrate": "{{value, rate(bits: true)}}",
"bibitrate": "{{value, rate(bits: true; binary: true)}}",
"percent": "{{value, percent}}",
"number": "{{value, number}}",
"ms": "{{value, number}}"
}, },
"widget": { "widget": {
"missing_type": "見つからないウィジェットタイプ: {{type}}",
"api_error": "APIエラー", "api_error": "APIエラー",
"information": "情報", "information": "情報",
"missing_type": "見つからないウィジェットタイプ: {{type}}",
"status": "状態", "status": "状態",
"url": "URL", "url": "URL",
"raw_error": "生のエラー", "raw_error": "生のエラー",
@@ -69,14 +32,14 @@
}, },
"resources": { "resources": {
"cpu": "CPU", "cpu": "CPU",
"mem": "MEM",
"total": "合計", "total": "合計",
"free": "Free", "free": "空き",
"used": "使用", "used": "使用",
"load": "ロード", "load": "ロード",
"mem": "MEM",
"temp": "温度", "temp": "温度",
"max": "Max", "max": "最大",
"uptime": "UP", "uptime": "上へ",
"months": "月", "months": "月",
"days": "日", "days": "日",
"hours": "時間", "hours": "時間",
@@ -88,14 +51,14 @@
"days": "日", "days": "日",
"wan": "WAN", "wan": "WAN",
"lan": "LAN", "lan": "LAN",
"wlan": "WLAN", "wlan": "Wi-Fi",
"devices": "デバイス", "devices": "デバイス",
"lan_devices": "LAN デバイス", "lan_devices": "LAN デバイス",
"wlan_devices": "WLAN デバイス", "wlan_devices": "WLAN デバイス",
"lan_users": "LAN ユーザ", "lan_users": "LAN ユーザ",
"wlan_users": "WLAN ユーザ", "wlan_users": "WLAN ユーザ",
"up": "UP", "up": "上へ",
"down": "DOWN", "down": "下へ",
"wait": "お待ちください", "wait": "お待ちください",
"empty_data": "サブシステム状態・不明" "empty_data": "サブシステム状態・不明"
}, },
@@ -104,20 +67,24 @@
"tx": "TX", "tx": "TX",
"mem": "MEM", "mem": "MEM",
"cpu": "CPU", "cpu": "CPU",
"running": "起動中",
"offline": "オフライン", "offline": "オフライン",
"error": "エラー", "error": "エラー",
"unknown": "不明", "unknown": "不明",
"running": "起動中", "healthy": "健全",
"starting": "起動中", "starting": "起動中",
"unhealthy": "非健全", "unhealthy": "非健全",
"not_found": "不明", "not_found": "不明",
"exited": "終了", "exited": "終了",
"partial": "部分的", "partial": "部分的"
"healthy": "健全"
}, },
"ping": { "ping": {
"http_status": "HTTP ステータス",
"error": "エラー", "error": "エラー",
"ping": "Ping" "ping": "Ping",
"down": "下へ",
"up": "上へ",
"not_available": "利用できません。"
}, },
"emby": { "emby": {
"playing": "再生中", "playing": "再生中",
@@ -129,21 +96,44 @@
"episodes": "エピソード", "episodes": "エピソード",
"songs": "曲" "songs": "曲"
}, },
"evcc": {
"pv_power": "発電量",
"battery_soc": "バッテリー",
"grid_power": "グリッド",
"home_power": "消費",
"charge_power": "チャージャー",
"watt_hour": "Wh"
},
"flood": { "flood": {
"download": "ダウンロード", "download": "ダウンロード",
"upload": "アップロード", "upload": "アップロード",
"leech": "リーチ", "leech": "リーチ",
"seed": "Seed" "seed": "シード"
},
"freshrss": {
"subscriptions": "購読",
"unread": "未読"
},
"caddy": {
"upstreams": "アップストリーム",
"requests": "現在のリクエスト",
"requests_failed": "失敗したリクエスト"
}, },
"changedetectionio": { "changedetectionio": {
"totalObserved": "全観測数", "totalObserved": "全観測数",
"diffsDetected": "変更数" "diffsDetected": "変更数"
}, },
"channelsdvrserver": {
"shows": "表示",
"recordings": "レコーディング",
"scheduled": "予定済",
"passes": "パス"
},
"tautulli": { "tautulli": {
"playing": "再生中", "playing": "再生中",
"transcoding": "変換中", "transcoding": "変換中",
"bitrate": "ビットレート", "bitrate": "ビットレート",
"no_active": "アクティブストリームし", "no_active": "アクティブストリームし",
"plex_connection_error": "Plex接続の確認" "plex_connection_error": "Plex接続の確認"
}, },
"omada": { "omada": {
@@ -160,9 +150,9 @@
}, },
"plex": { "plex": {
"streams": "アクティブストリーム", "streams": "アクティブストリーム",
"albums": "アルバム",
"movies": "映画", "movies": "映画",
"tv": "テレビ番組", "tv": "テレビ番組"
"albums": "アルバム"
}, },
"sabnzbd": { "sabnzbd": {
"rate": "速度", "rate": "速度",
@@ -178,25 +168,33 @@
"download": "ダウンロード", "download": "ダウンロード",
"upload": "アップロード", "upload": "アップロード",
"leech": "リーチ", "leech": "リーチ",
"seed": "Seed" "seed": "シード"
}, },
"qbittorrent": { "qbittorrent": {
"download": "ダウンロード", "download": "ダウンロード",
"upload": "アップロード", "upload": "アップロード",
"leech": "Leech", "leech": "リーチ",
"seed": "Seed" "seed": "シード"
},
"qnap": {
"cpuUsage": "CPU使用量",
"memUsage": "MEM使用量",
"systemTempC": "システム温度",
"poolUsage": "プール使用量",
"volumeUsage": "ボリューム使用量",
"invalid": "無効"
}, },
"deluge": { "deluge": {
"download": "ダウンロード", "download": "ダウンロード",
"upload": "アップロード", "upload": "アップロード",
"leech": "Leech", "leech": "リーチ",
"seed": "Seed" "seed": "シード"
}, },
"downloadstation": { "downloadstation": {
"download": "ダウンロード", "download": "ダウンロード",
"upload": "アップロード", "upload": "アップロード",
"leech": "Leech", "leech": "リーチ",
"seed": "Seed" "seed": "シード"
}, },
"sonarr": { "sonarr": {
"wanted": "募集中", "wanted": "募集中",
@@ -208,14 +206,14 @@
"radarr": { "radarr": {
"wanted": "募集中", "wanted": "募集中",
"missing": "不明", "missing": "不明",
"queued": "キュー", "queued": "待機中",
"movies": "映画", "movies": "映画",
"queue": "キュー", "queue": "キュー",
"unknown": "Unknown" "unknown": "不明"
}, },
"lidarr": { "lidarr": {
"wanted": "募集中", "wanted": "募集中",
"queued": "キュー", "queued": "待機中",
"artists": "アーティスト" "artists": "アーティスト"
}, },
"readarr": { "readarr": {
@@ -225,7 +223,7 @@
}, },
"bazarr": { "bazarr": {
"missingEpisodes": "欠番エピソード", "missingEpisodes": "欠番エピソード",
"missingMovies": "行方不明の映画" "missingMovies": "動画が見つかりません"
}, },
"ombi": { "ombi": {
"pending": "保留中", "pending": "保留中",
@@ -243,11 +241,17 @@
"approved": "承認済", "approved": "承認済",
"available": "利用可" "available": "利用可"
}, },
"pialert": {
"total": "合計",
"connected": "接続済み",
"new_devices": "新しいデバイス",
"down_alerts": "ダウンアラート"
},
"pihole": { "pihole": {
"queries": "クエリ", "queries": "クエリ",
"blocked": "ブロック中", "blocked": "ブロック中",
"gravity": "グラビティ", "blocked_percent": "ブロック %",
"blocked_percent": "ブロック %" "gravity": "グラビティ"
}, },
"adguard": { "adguard": {
"queries": "クエリ", "queries": "クエリ",
@@ -265,6 +269,20 @@
"stopped": "停止中", "stopped": "停止中",
"total": "合計" "total": "合計"
}, },
"tailscale": {
"address": "アドレス",
"expires": "失効",
"never": "なし",
"last_seen": "最終日時",
"now": "現在",
"years": "{{number}}年",
"weeks": "{{number}}月",
"days": "{{number}}日",
"hours": "{{number}}時間",
"minutes": "{{number}}分",
"seconds": "{{number}}秒",
"ago": "{{value}} 前"
},
"tdarr": { "tdarr": {
"queue": "キュー", "queue": "キュー",
"processed": "処理済み", "processed": "処理済み",
@@ -276,6 +294,15 @@
"services": "サービス", "services": "サービス",
"middleware": "ミドルウェア" "middleware": "ミドルウェア"
}, },
"navidrome": {
"nothing_streaming": "アクティブ・ストリーム無し",
"please_wait": "お待ちください"
},
"npm": {
"enabled": "有効",
"disabled": "無効",
"total": "合計"
},
"coinmarketcap": { "coinmarketcap": {
"configure": "1つ以上の暗号通貨を設定して追跡", "configure": "1つ以上の暗号通貨を設定して追跡",
"1hour": "1時間", "1hour": "1時間",
@@ -289,27 +316,45 @@
"messages": "メッセージ" "messages": "メッセージ"
}, },
"prowlarr": { "prowlarr": {
"enableIndexers": "Indexers", "enableIndexers": "インデックス",
"numberOfGrabs": "Grabs", "numberOfGrabs": "Grab",
"numberOfQueries": "クエリ", "numberOfQueries": "クエリ",
"numberOfFailGrabs": "Fail Grabs", "numberOfFailGrabs": "失敗したグラブ",
"numberOfFailQueries": "失敗クエリー" "numberOfFailQueries": "失敗クエリー"
}, },
"jackett": { "jackett": {
"configured": "設定済", "configured": "設定済",
"errored": "エラー" "errored": "エラー"
}, },
"strelaysrv": {
"numActiveSessions": "セッション",
"numConnections": "コネクション",
"dataRelayed": "中継",
"transferRate": "速度"
},
"mastodon": { "mastodon": {
"user_count": "ユーザ", "user_count": "ユーザ",
"status_count": "ポスト", "status_count": "ポスト",
"domain_count": "ドメイン" "domain_count": "ドメイン"
}, },
"medusa": {
"wanted": "募集中",
"queued": "待機中",
"series": "シリーズ"
},
"minecraft": {
"players": "プレイヤー",
"version": "バージョン",
"status": "状態",
"up": "オンライン",
"down": "オフライン"
},
"miniflux": { "miniflux": {
"read": "既読", "read": "既読",
"unread": "未読" "unread": "未読"
}, },
"authentik": { "authentik": {
"users": "ユーザ", "users": "ユーザ",
"loginsLast24H": "ログイン (24時間)", "loginsLast24H": "ログイン (24時間)",
"failedLoginsLast24H": "ログイン失敗(24時間)" "failedLoginsLast24H": "ログイン失敗(24時間)"
}, },
@@ -319,6 +364,26 @@
"lxc": "LXC", "lxc": "LXC",
"vms": "VM" "vms": "VM"
}, },
"glances": {
"cpu": "CPU",
"load": "ロード",
"wait": "お待ちください",
"temp": "温度",
"_temp": "温度",
"warn": "警告",
"uptime": "上へ",
"total": "合計",
"free": "空き",
"used": "使用",
"days": "日",
"hours": "時間",
"crit": "クリティカル",
"read": "既読",
"write": "書き込み",
"gpu": "GPU",
"mem": "メモリ",
"swap": "スワップ"
},
"quicklaunch": { "quicklaunch": {
"bookmark": "ブックマーク", "bookmark": "ブックマーク",
"service": "サービス", "service": "サービス",
@@ -329,47 +394,47 @@
}, },
"wmo": { "wmo": {
"0-day": "晴れ", "0-day": "晴れ",
"1-day": "ほぼ晴れ",
"0-night": "晴れ", "0-night": "晴れ",
"1-night": "ほぼ晴れ", "1-day": "晴れ時々曇り",
"2-day": "一時くもり", "1-night": "晴れ時々曇り",
"2-night": "一部くもり", "2-day": "曇り時々晴れ",
"3-day": "くもり", "2-night": "曇り時々晴れ",
"3-night": "くもり", "3-day": "り",
"3-night": "曇り",
"45-day": "霧", "45-day": "霧",
"45-night": "霧", "45-night": "霧",
"48-day": "霧", "48-day": "霧",
"48-night": "霧", "48-night": "霧",
"51-day": "霧雨", "51-day": "霧雨",
"51-night": "霧雨", "51-night": "霧雨",
"53-day": "雨", "53-day": "雨",
"53-night": "雨", "53-night": "雨",
"55-day": "霧雨", "55-day": "霧雨",
"55-night": "霧雨", "55-night": "霧雨",
"56-day": "霧雨", "56-day": "着氷性の霧雨",
"56-night": "霧雨", "56-night": "着氷性の霧雨",
"57-day": "雨", "57-day": "着氷性の小雨",
"57-night": "雨", "57-night": "着氷性の小雨",
"61-day": "小雨", "61-day": "小雨",
"61-night": "小雨", "61-night": "小雨",
"63-day": "雨", "63-day": "雨",
"63-night": "雨", "63-night": "雨",
"67-night": "雨",
"71-day": "雪",
"65-day": "大雨", "65-day": "大雨",
"65-night": "大雨", "65-night": "大雨",
"66-day": "雨", "66-day": "着氷性の雨",
"66-night": "雨", "66-night": "着氷性の雨",
"67-day": "雨", "67-day": "着氷性の雨",
"71-night": "", "67-night": "着氷性の雨",
"71-day": "小雪",
"71-night": "小雪",
"73-day": "雪", "73-day": "雪",
"73-night": "雪", "73-night": "雪",
"75-day": "大雪", "75-day": "大雪",
"75-night": "大雪", "75-night": "大雪",
"77-day": "雪", "77-day": "雪",
"77-night": "雪", "77-night": "雪",
"80-day": "にわか雨", "80-day": "弱いにわか雨",
"80-night": "にわか雨", "80-night": "弱いにわか雨",
"81-day": "にわか雨", "81-day": "にわか雨",
"81-night": "にわか雨", "81-night": "にわか雨",
"82-day": "強いにわか雨", "82-day": "強いにわか雨",
@@ -390,17 +455,33 @@
"updates": "アップデート", "updates": "アップデート",
"update_available": "更新あり", "update_available": "更新あり",
"up_to_date": "最新", "up_to_date": "最新",
"child_bridges": "Child Bridges", "child_bridges": "子ブリッジ",
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "上へ",
"pending": "Pending", "pending": "保留中",
"down": "Down" "down": "下へ"
},
"healthchecks": {
"new": "新着",
"up": "オンライン",
"grace": "猶予期間中",
"down": "オフライン",
"paused": "一時停止中",
"status": "状態",
"last_ping": "最後のPing",
"never": "Pingしていません"
}, },
"watchtower": { "watchtower": {
"containers_scanned": "スキャン済", "containers_scanned": "スキャン済",
"containers_updated": "更新済", "containers_updated": "更新済",
"containers_failed": "失敗" "containers_failed": "失敗"
}, },
"autobrr": {
"approvedPushes": "承認済",
"rejectedPushes": "却下",
"filters": "フィルター",
"indexers": "インデックス"
},
"tubearchivist": { "tubearchivist": {
"downloads": "キュー", "downloads": "キュー",
"videos": "ビデオ", "videos": "ビデオ",
@@ -419,6 +500,11 @@
"queue": "キュー", "queue": "キュー",
"total": "合計" "total": "合計"
}, },
"gluetun": {
"public_ip": "パブリックIP",
"region": "地域",
"country": "国"
},
"hdhomerun": { "hdhomerun": {
"channels": "チャンネル", "channels": "チャンネル",
"hd": "HD" "hd": "HD"
@@ -429,7 +515,7 @@
"unknown": "不明" "unknown": "不明"
}, },
"paperlessngx": { "paperlessngx": {
"inbox": "受信", "inbox": "受信トレイ",
"total": "合計" "total": "合計"
}, },
"nextdns": { "nextdns": {
@@ -438,15 +524,21 @@
}, },
"mikrotik": { "mikrotik": {
"cpuLoad": "CPU負荷", "cpuLoad": "CPU負荷",
"memoryUsed": "使用メモリ", "memoryUsed": "使用済みメモリ",
"uptime": "稼働時間", "uptime": "稼働時間",
"numberOfLeases": "リース" "numberOfLeases": "リース"
}, },
"xteve": { "xteve": {
"streams_all": "ストリーム", "streams_all": "すべてのストリーム",
"streams_active": "アクティブストリーム", "streams_active": "アクティブストリーム",
"streams_xepg": "XEPGチャンネル" "streams_xepg": "XEPGチャンネル"
}, },
"opendtu": {
"yieldDay": "今日",
"absolutePower": "電源",
"relativePower": "電源 %",
"limit": "リミット"
},
"opnsense": { "opnsense": {
"cpu": "CPU負荷", "cpu": "CPU負荷",
"memory": "アクティブ・メモリ", "memory": "アクティブ・メモリ",
@@ -459,21 +551,26 @@
"print_progress": "進捗状況", "print_progress": "進捗状況",
"layers": "レイヤー" "layers": "レイヤー"
}, },
"medusa": {
"wanted": "Wanted",
"queued": "Queued",
"series": "シリーズ"
},
"octoprint": { "octoprint": {
"temp_bed": "ベッド温度",
"printer_state": "状態", "printer_state": "状態",
"temp_tool": "ツール温度", "temp_tool": "ツール温度",
"temp_bed": "ベッド温度",
"job_completion": "完了" "job_completion": "完了"
}, },
"cloudflared": { "cloudflared": {
"origin_ip": "オリジンIP", "origin_ip": "オリジンIP",
"status": "状態" "status": "状態"
}, },
"pfsense": {
"load": "読み込み平均",
"memory": "メモリ使用量",
"wanStatus": "WANステータス",
"up": "上へ",
"down": "下へ",
"temp": "温度",
"disk": "ディスク使用量",
"wanIP": "WAN IP"
},
"proxmoxbackupserver": { "proxmoxbackupserver": {
"datastore_usage": "データストア", "datastore_usage": "データストア",
"failed_tasks_24h": "失敗タスク(24h)", "failed_tasks_24h": "失敗タスク(24h)",
@@ -490,18 +587,29 @@
"up": "サイトUp", "up": "サイトUp",
"down": "サイトDown", "down": "サイトDown",
"uptime": "稼働時間", "uptime": "稼働時間",
"incident": "Incident", "incident": "インシデント",
"m": "m" "m": ""
},
"atsumeru": {
"series": "シリーズ",
"archives": "アーカイブ",
"chapters": "チャプター",
"categories": "カテゴリー"
}, },
"komga": { "komga": {
"libraries": "ライブラリ", "libraries": "ライブラリ",
"series": "シリーズ", "series": "シリーズ",
"books": "書籍" "books": "書籍"
}, },
"diskstation": {
"days": "日",
"uptime": "稼働時間",
"volumeAvailable": "利用可"
},
"mylar": { "mylar": {
"series": "シリーズ", "series": "シリーズ",
"issues": "課題", "issues": "課題",
"wanted": "Wanted" "wanted": "募集中"
}, },
"photoprism": { "photoprism": {
"albums": "アルバム", "albums": "アルバム",
@@ -509,11 +617,6 @@
"videos": "ビデオ", "videos": "ビデオ",
"people": "人" "people": "人"
}, },
"diskstation": {
"days": "日",
"uptime": "稼働時間",
"volumeAvailable": "利用可能"
},
"fileflows": { "fileflows": {
"queue": "キュー", "queue": "キュー",
"processing": "処理中", "processing": "処理中",
@@ -537,8 +640,8 @@
"kopia": { "kopia": {
"status": "状態", "status": "状態",
"size": "サイズ", "size": "サイズ",
"lastrun": "最終実行", "lastrun": "前回の実行",
"nextrun": "次の実行", "nextrun": "次の実行",
"failed": "失敗" "failed": "失敗"
}, },
"unmanic": { "unmanic": {
@@ -546,16 +649,6 @@
"total_workers": "トータル・ワーカー", "total_workers": "トータル・ワーカー",
"records_total": "キューの長さ" "records_total": "キューの長さ"
}, },
"healthchecks": {
"never": "Pingしていません",
"new": "New",
"up": "オンライン",
"grace": "猶予期間中",
"down": "オフライン",
"paused": "一時停止中",
"status": "状態",
"last_ping": "最後のPing"
},
"pterodactyl": { "pterodactyl": {
"servers": "サーバ", "servers": "サーバ",
"nodes": "ノード" "nodes": "ノード"
@@ -565,17 +658,10 @@
"targets_down": "ターゲット Down", "targets_down": "ターゲット Down",
"targets_total": "ターゲット合計" "targets_total": "ターゲット合計"
}, },
"minecraft": {
"players": "プレイヤー",
"version": "バージョン",
"status": "状態",
"up": "オンライン",
"down": "オフライン"
},
"ghostfolio": { "ghostfolio": {
"gross_percent_max": "全期間",
"gross_percent_today": "今日", "gross_percent_today": "今日",
"gross_percent_1y": "1年" "gross_percent_1y": "1年",
"gross_percent_max": "全期間"
}, },
"audiobookshelf": { "audiobookshelf": {
"podcasts": "ポッドキャスト", "podcasts": "ポッドキャスト",
@@ -588,161 +674,88 @@
"lights_on": "点灯", "lights_on": "点灯",
"switches_on": "スイッチオン" "switches_on": "スイッチオン"
}, },
"freshrss": {
"subscriptions": "購読",
"unread": "未読"
},
"channelsdvrserver": {
"shows": "ショー",
"recordings": "レコーディング",
"scheduled": "予定済",
"passes": "パス"
},
"whatsupdocker": { "whatsupdocker": {
"monitoring": "モニタリング", "monitoring": "モニタリング",
"updates": "アップデート" "updates": "アップデート"
}, },
"tailscale": {
"address": "アドレス",
"expires": "失効",
"never": "なし",
"last_seen": "最終日時",
"now": "現在",
"years": "{{number}}年",
"weeks": "{{number}}月",
"days": "{{number}}日",
"hours": "{{number}}時間",
"minutes": "{{number}}分",
"seconds": "{{number}}秒",
"ago": "{{value}} 前"
},
"qnap": {
"cpuUsage": "CPU使用量",
"memUsage": "MEM使用量",
"systemTempC": "システム温度",
"poolUsage": "プール使用量",
"volumeUsage": "ボリューム使用量",
"invalid": "無効"
},
"pfsense": {
"up": "アップ",
"load": "読み込み平均",
"memory": "メモリ使用量",
"wanStatus": "WANステータス",
"down": "ダウン",
"temp": "温度",
"disk": "ディスク使用量",
"wanIP": "WAN IP"
},
"caddy": {
"upstreams": "アップストリーム",
"requests": "現在のリクエスト",
"requests_failed": "失敗したリクエスト"
},
"evcc": {
"watt_hour": "Wh",
"pv_power": "発電量",
"battery_soc": "バッテリー",
"grid_power": "グリッド",
"home_power": "消費",
"charge_power": "チャージャー"
},
"pialert": {
"total": "トータル",
"connected": "接続済み",
"new_devices": "新しいデバイス",
"down_alerts": "ダウンアラート"
},
"jdownloader": {
"downloadCount": "キュー",
"downloadSpeed": "スピード",
"downloadBytesRemaining": "残り",
"downloadTotalBytes": "サイズ"
},
"kavita": {
"seriesCount": "シリーズ",
"totalFiles": "ファイル"
},
"gamedig": {
"name": "名前",
"map": "マップ",
"currentPlayers": "現在のプレーヤー",
"players": "プレーヤー",
"maxPlayers": "最大プレーヤー",
"bots": "ボット",
"ping": "Ping",
"status": "ステータス",
"online": "オンライン",
"offline": "オフライン"
},
"azuredevops": {
"result": "結果",
"status": "ステータス",
"buildId": "ビルドID",
"succeeded": "成功",
"notStarted": "Not Started",
"failed": "失敗",
"canceled": "キャンセル",
"inProgress": "進行中",
"totalPrs": "合計PR数",
"myPrs": "私のPR",
"approved": "承認"
},
"urbackup": {
"ok": "Ok",
"errored": "エラー",
"noRecent": "期限切れ",
"totalUsed": "使用済みストレージ"
},
"openmediavault": {
"downloading": "ダウンロード中",
"total": "トータル",
"running": "実行中",
"stopped": "停止中",
"passed": "合格",
"failed": "不合格"
},
"mealie": {
"recipes": "レシピ",
"users": "ユーザー",
"categories": "カテゴリー",
"tags": "タグ"
},
"atsumeru": {
"series": "シリーズ",
"archives": "アーカイブ",
"chapters": "チャプター",
"categories": "カテゴリー"
},
"calibreweb": { "calibreweb": {
"books": "書籍", "books": "書籍",
"authors": "著者", "authors": "著者",
"categories": "カテゴリー", "categories": "カテゴリー",
"series": "シリーズ" "series": "シリーズ"
}, },
"uptimerobot": { "jdownloader": {
"status": "Status", "downloadCount": "キュー",
"uptime": "Uptime", "downloadBytesRemaining": "残り",
"lastDown": "Last Downtime", "downloadTotalBytes": "サイズ",
"downDuration": "Downtime Duration", "downloadSpeed": "スピード"
"sitesUp": "Sites Up",
"sitesDown": "Sites Down",
"paused": "Paused",
"notyetchecked": "Not Yet Checked",
"up": "Up",
"seemsdown": "Seems Down",
"down": "Down",
"unknown": "Unknown"
}, },
"opendtu": { "kavita": {
"relativePower": "Power %", "seriesCount": "シリーズ",
"yieldDay": "Today", "totalFiles": "ファイル"
"limit": "Limit", },
"absolutePower": "Power" "azuredevops": {
"result": "結果",
"status": "状態",
"buildId": "ビルドID",
"succeeded": "成功",
"notStarted": "開始していません",
"failed": "失敗",
"canceled": "キャンセル",
"inProgress": "進行中",
"totalPrs": "合計PR数",
"myPrs": "私のPR",
"approved": "承認済"
},
"gamedig": {
"status": "状態",
"online": "オンライン",
"offline": "オフライン",
"name": "名前",
"map": "マップ",
"currentPlayers": "現在のプレーヤー",
"players": "プレイヤー",
"maxPlayers": "最大プレイヤー数",
"bots": "ボット",
"ping": "Ping"
},
"urbackup": {
"ok": "はい",
"errored": "エラー",
"noRecent": "期限切れ",
"totalUsed": "使用済みストレージ"
},
"mealie": {
"recipes": "レシピ",
"users": "ユーザ",
"categories": "カテゴリー",
"tags": "タグ"
},
"openmediavault": {
"downloading": "ダウンロード中",
"total": "合計",
"running": "起動中",
"stopped": "停止中",
"passed": "合格",
"failed": "失敗"
},
"uptimerobot": {
"status": "状態",
"uptime": "稼働時間",
"lastDown": "最後のダウンタイム",
"downDuration": "ダウンタイム感覚",
"sitesUp": "サイトUp",
"sitesDown": "サイトDown",
"paused": "一時停止中",
"notyetchecked": "チェックされていません",
"up": "上へ",
"seemsdown": "ダウンしているようです",
"down": "下へ",
"unknown": "不明"
}, },
"calendar": { "calendar": {
"physicalRelease": "Physical release", "inCinemas": "映画館内",
"inCinemas": "In cinemas", "physicalRelease": "物理的なリリース",
"digitalRelease": "Digital release" "digitalRelease": "デジタル・リリース"
} }
} }

View File

@@ -85,7 +85,9 @@
}, },
"ping": { "ping": {
"error": "오류", "error": "오류",
"ping": "Ping" "ping": "Ping",
"up": "Up",
"down": "Down"
}, },
"emby": { "emby": {
"playing": "재생 중", "playing": "재생 중",

View File

@@ -71,7 +71,9 @@
}, },
"ping": { "ping": {
"error": "Kļūda", "error": "Kļūda",
"ping": "Ping" "ping": "Ping",
"up": "Up",
"down": "Down"
}, },
"emby": { "emby": {
"playing": "Atskaņo", "playing": "Atskaņo",

View File

@@ -382,7 +382,9 @@
}, },
"ping": { "ping": {
"error": "Ralat", "error": "Ralat",
"ping": "Ping" "ping": "Ping",
"up": "Up",
"down": "Down"
}, },
"scrutiny": { "scrutiny": {
"passed": "Lulus", "passed": "Lulus",

View File

@@ -382,7 +382,9 @@
}, },
"ping": { "ping": {
"error": "Error", "error": "Error",
"ping": "Ping" "ping": "Ping",
"up": "Up",
"down": "Down"
}, },
"scrutiny": { "scrutiny": {
"passed": "Passed", "passed": "Passed",

File diff suppressed because it is too large Load Diff

View File

@@ -1,20 +1,42 @@
{ {
"common": {
"bytes": "{{value, bytes}}",
"bits": "{{value, bytes(bits: true)}}",
"bbytes": "{{value, bytes(binary: true)}}",
"bbits": "{{value, bytes(bits: true; binary: true)}}",
"byterate": "{{value, rate(bits: false)}}",
"bibyterate": "{{value, rate(bits: false; binary: true)}}",
"bitrate": "{{value, rate(bits: true)}}",
"bibitrate": "{{value, rate(bits: true; binary: true)}}",
"percent": "{{value, percent}}",
"number": "{{value, number}}",
"ms": "{{value, number}}"
},
"widget": {
"missing_type": "Brakujący typ widżetu: {{type}}",
"api_error": "Błąd API",
"information": "Informacje",
"status": "Stan",
"url": "Adres URL",
"raw_error": "Niesformatowany błąd",
"response_data": "Dane odpowiedzi"
},
"weather": { "weather": {
"current": "Aktualna lokalizacja",
"allow": "Kliknij, aby zezwolić", "allow": "Kliknij, aby zezwolić",
"updating": "Aktualizacja", "updating": "Aktualizacja",
"wait": "Proszę czekać", "wait": "Proszę czekać"
"current": "Aktualna lokalizacja"
}, },
"search": { "search": {
"placeholder": "Szukaj…" "placeholder": "Szukaj…"
}, },
"resources": { "resources": {
"used": "Użyte", "cpu": "Procesor",
"load": "Obciążenie", "mem": "PAM",
"total": "Całkowite", "total": "Całkowite",
"free": "Wolne", "free": "Wolne",
"cpu": "CPU", "used": "Użyte",
"mem": "PAM", "load": "Obciążenie",
"temp": "TEMP.", "temp": "TEMP.",
"max": "Maks", "max": "Maks",
"uptime": "CZAS", "uptime": "CZAS",
@@ -23,16 +45,90 @@
"hours": "godz", "hours": "godz",
"minutes": "min" "minutes": "min"
}, },
"unifi": {
"users": "Użytkownicy",
"uptime": "Czas pracy systemu",
"days": "Dni",
"wan": "Sieć WAN",
"lan": "Sieć LAN",
"wlan": "Sieć WLAN",
"devices": "Urządzenia",
"lan_devices": "Urządzenia LAN",
"wlan_devices": "Urządzenia WLAN",
"lan_users": "Użytkownicy LAN",
"wlan_users": "Użytkownicy WLAN",
"up": "CZAS",
"down": "Pobieranie",
"wait": "Proszę czekać",
"empty_data": "Nieznany stan"
},
"docker": {
"rx": "Rx",
"tx": "Tx",
"mem": "PAM",
"cpu": "Procesor",
"running": "Działa",
"offline": "Offline",
"error": "Błąd",
"unknown": "Nieznany",
"healthy": "Zdrowy",
"starting": "Rozpoczynanie",
"unhealthy": "Niezdrowe",
"not_found": "Nie znaleziono",
"exited": "Zakończone",
"partial": "Częściowe"
},
"ping": {
"http_status": "HTTP status",
"error": "Błąd",
"ping": "Ping",
"down": "Down",
"up": "Up",
"not_available": "Not Available"
},
"emby": { "emby": {
"no_active": "Brak aktywnych strumieni",
"playing": "Odtwarzanie", "playing": "Odtwarzanie",
"transcoding": "Transkodowanie", "transcoding": "Transkodowanie",
"bitrate": "Bitrate", "bitrate": "Bitrate",
"no_active": "Brak aktywnych strumieni",
"movies": "Filmy", "movies": "Filmy",
"series": "Seriale", "series": "Seriale",
"episodes": "Odcinki", "episodes": "Odcinki",
"songs": "Piosenki" "songs": "Piosenki"
}, },
"evcc": {
"pv_power": "Production",
"battery_soc": "Battery",
"grid_power": "Siatka",
"home_power": "Consumption",
"charge_power": "Charger",
"watt_hour": "Wh"
},
"flood": {
"download": "Pobieranie",
"upload": "Wysyłanie",
"leech": "Leech",
"seed": "Seed"
},
"freshrss": {
"subscriptions": "Subskrypcje",
"unread": "Nieprzeczytane"
},
"caddy": {
"upstreams": "Upstreams",
"requests": "Current requests",
"requests_failed": "Failed requests"
},
"changedetectionio": {
"totalObserved": "Obserwowanych ogółem",
"diffsDetected": "Wykryto różnic"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Nagrywanie",
"scheduled": "W kolejce",
"passes": "Passes"
},
"tautulli": { "tautulli": {
"playing": "Odtwarzanie", "playing": "Odtwarzanie",
"transcoding": "Transkodowanie", "transcoding": "Transkodowanie",
@@ -40,58 +136,24 @@
"no_active": "Brak aktywnych strumieni", "no_active": "Brak aktywnych strumieni",
"plex_connection_error": "Check Plex Connection" "plex_connection_error": "Check Plex Connection"
}, },
"speedtest": { "omada": {
"download": "Pobieranie", "connectedAp": "Połączone punkty dostępowe",
"ping": "Ping", "activeUser": "Aktywne urządzenia",
"upload": "Wysyłanie" "alerts": "Alarmy",
}, "connectedGateway": "Połączone bramy",
"portainer": { "connectedSwitches": "Połączone przełączniki"
"running": "Działające",
"stopped": "Zatrzymane",
"total": "Ogólnie"
},
"coinmarketcap": {
"1day": "1 dzień",
"7days": "7 dni",
"30days": "30 dni",
"1hour": "1 godzina",
"configure": "Wybierz jedną lub więcej kryptowalut do śledzenia"
},
"gotify": {
"apps": "Aplikacje",
"clients": "Klienci",
"messages": "Wiadomości"
},
"widget": {
"missing_type": "Brakujący typ widżetu: {{type}}",
"api_error": "Błąd API",
"status": "Stan",
"url": "Adres URL",
"information": "Informacje",
"raw_error": "Niesformatowany błąd",
"response_data": "Dane odpowiedzi"
},
"docker": {
"rx": "Rx",
"tx": "Tx",
"mem": "Pamięć",
"cpu": "Procesor",
"offline": "Offline",
"error": "Błąd",
"unknown": "Nieznany",
"running": "Działa",
"starting": "Rozpoczynanie",
"unhealthy": "Niezdrowe",
"not_found": "Nie znaleziono",
"exited": "Exited",
"partial": "Częściowe",
"healthy": "Zdrowy"
}, },
"nzbget": { "nzbget": {
"rate": "Szybkość", "rate": "Szybkość",
"remaining": "Pozostało", "remaining": "Pozostało",
"downloaded": "Pobrano" "downloaded": "Pobrano"
}, },
"plex": {
"streams": "Aktywne strumienie",
"albums": "Albumy",
"movies": "Filmy",
"tv": "Seriale"
},
"sabnzbd": { "sabnzbd": {
"rate": "Szybkość", "rate": "Szybkość",
"queue": "Kolejka", "queue": "Kolejka",
@@ -108,20 +170,46 @@
"leech": "Leech", "leech": "Leech",
"seed": "Seed" "seed": "Seed"
}, },
"qbittorrent": {
"download": "Pobieranie",
"upload": "Wysyłanie",
"leech": "Leech",
"seed": "Seed"
},
"qnap": {
"cpuUsage": "CPU Usage",
"memUsage": "MEM Usage",
"systemTempC": "System Temp",
"poolUsage": "Pool Usage",
"volumeUsage": "Volume Usage",
"invalid": "Invalid"
},
"deluge": {
"download": "Pobieranie",
"upload": "Wysyłanie",
"leech": "Leech",
"seed": "Seed"
},
"downloadstation": {
"download": "Pobieranie",
"upload": "Wysyłanie",
"leech": "Leech",
"seed": "Seed"
},
"sonarr": { "sonarr": {
"wanted": "Poszukiwane", "wanted": "Poszukiwane",
"queued": "W kolejce", "queued": "W kolejce",
"series": "Seriale", "series": "Seriale",
"queue": "Queue", "queue": "Kolejka",
"unknown": "Unknown" "unknown": "Nieznany"
}, },
"radarr": { "radarr": {
"wanted": "Poszukiwane", "wanted": "Poszukiwane",
"missing": "Brakujące",
"queued": "W kolejce", "queued": "W kolejce",
"movies": "Filmy", "movies": "Filmy",
"missing": "Brakujące", "queue": "Kolejka",
"queue": "Queue", "unknown": "Nieznany"
"unknown": "Unknown"
}, },
"lidarr": { "lidarr": {
"wanted": "Poszukiwane", "wanted": "Poszukiwane",
@@ -149,25 +237,83 @@
}, },
"overseerr": { "overseerr": {
"pending": "Oczekiwane", "pending": "Oczekiwane",
"processing": "Przetwarzane",
"approved": "Zaakceptowane", "approved": "Zaakceptowane",
"available": "Dostępne", "available": "Dostępne"
"processing": "Przetwarzane" },
"pialert": {
"total": "Całkowite",
"connected": "Connected",
"new_devices": "New Devices",
"down_alerts": "Down Alerts"
}, },
"pihole": { "pihole": {
"queries": "Zapytania", "queries": "Zapytania",
"blocked": "Zablokowane", "blocked": "Zablokowane",
"gravity": "Grawitacja", "blocked_percent": "Blocked %",
"blocked_percent": "Blocked %" "gravity": "Grawitacja"
},
"adguard": {
"queries": "Zapytania",
"blocked": "Zablokowane",
"filtered": "Przefiltrowane",
"latency": "Opóźnienia"
},
"speedtest": {
"upload": "Wysyłanie",
"download": "Pobieranie",
"ping": "Ping"
},
"portainer": {
"running": "Działa",
"stopped": "Zatrzymane",
"total": "Całkowite"
},
"tailscale": {
"address": "Address",
"expires": "Expires",
"never": "Nigdy",
"last_seen": "Last Seen",
"now": "Teraz",
"years": "{{number}}y",
"weeks": "{{number}}w",
"days": "{{number}}d",
"hours": "{{number}}h",
"minutes": "{{number}}m",
"seconds": "{{number}}s",
"ago": "{{value}} Ago"
},
"tdarr": {
"queue": "Kolejka",
"processed": "Przetworzone",
"errored": "Błędne",
"saved": "Zapisane"
}, },
"traefik": { "traefik": {
"routers": "Routery", "routers": "Routery",
"services": "Serwisy", "services": "Serwisy",
"middleware": "Pośrednicy" "middleware": "Pośrednicy"
}, },
"navidrome": {
"nothing_streaming": "Brak aktywnych strumieni",
"please_wait": "Proszę czekać"
},
"npm": { "npm": {
"enabled": "Włączone", "enabled": "Włączone",
"disabled": "Wyłączone", "disabled": "Wyłączone",
"total": "Ogólnie" "total": "Całkowite"
},
"coinmarketcap": {
"configure": "Wybierz jedną lub więcej kryptowalut do śledzenia",
"1hour": "1 godzina",
"1day": "1 dzień",
"7days": "7 dni",
"30days": "30 dni"
},
"gotify": {
"apps": "Aplikacje",
"clients": "Klienci",
"messages": "Wiadomości"
}, },
"prowlarr": { "prowlarr": {
"enableIndexers": "Indeksery", "enableIndexers": "Indeksery",
@@ -180,28 +326,32 @@
"configured": "Skonfigurowane", "configured": "Skonfigurowane",
"errored": "Błędne" "errored": "Błędne"
}, },
"adguard": { "strelaysrv": {
"queries": "Zapytania", "numActiveSessions": "Sesje",
"blocked": "Zablokowane", "numConnections": "Połączenia",
"filtered": "Przefiltrowane", "dataRelayed": "Przekazane",
"latency": "Opóźnienia" "transferRate": "Szybkość"
},
"qbittorrent": {
"download": "Pobieranie",
"upload": "Wysyłanie",
"leech": "Leech",
"seed": "Seed"
}, },
"mastodon": { "mastodon": {
"user_count": "Użytkownicy", "user_count": "Użytkownicy",
"status_count": "Posty", "status_count": "Posty",
"domain_count": "Domeny" "domain_count": "Domeny"
}, },
"strelaysrv": { "medusa": {
"numActiveSessions": "Sesje", "wanted": "Poszukiwane",
"numConnections": "Połączenia", "queued": "W kolejce",
"dataRelayed": "Przekazane", "series": "Seriale"
"transferRate": "Przesył" },
"minecraft": {
"players": "Gracze",
"version": "Wersja",
"status": "Stan",
"up": "Online",
"down": "Offline"
},
"miniflux": {
"read": "Przeczytane",
"unread": "Nieprzeczytane"
}, },
"authentik": { "authentik": {
"users": "Użytkownicy", "users": "Użytkownicy",
@@ -209,60 +359,40 @@
"failedLoginsLast24H": "Nieudane logowania (24h)" "failedLoginsLast24H": "Nieudane logowania (24h)"
}, },
"proxmox": { "proxmox": {
"mem": "Pamięć", "mem": "PAM",
"cpu": "Procesor", "cpu": "Procesor",
"lxc": "Kontenery LXC", "lxc": "Kontenery LXC",
"vms": "Maszyn wirtualnych" "vms": "Maszyn wirtualnych"
}, },
"unifi": {
"users": "Użytkownicy",
"uptime": "Czas pracy systemu",
"days": "Dni",
"wan": "WAN",
"lan_users": "Użytkownicy LAN",
"wlan_users": "Użytkownicy WLAN",
"up": "Wysyłanie",
"down": "Pobieranie",
"wait": "Proszę czekać",
"lan": "LAN",
"wlan": "WLAN",
"devices": "Urządzenia",
"lan_devices": "Urządzenia LAN",
"wlan_devices": "Urządzenia WLAN",
"empty_data": "Nieznany stan"
},
"plex": {
"streams": "Aktywne strumienie",
"movies": "Filmy",
"tv": "Seriale",
"albums": "Albumy"
},
"glances": { "glances": {
"cpu": "Procesor", "cpu": "Procesor",
"load": "Obciążenie",
"wait": "Proszę czekać", "wait": "Proszę czekać",
"temp": "TEMP", "temp": "TEMP.",
"_temp": "Temperatura",
"warn": "Ostrzeżenie",
"uptime": "CZAS", "uptime": "CZAS",
"total": "Całkowite",
"free": "Wolne",
"used": "Użyte",
"days": "dni", "days": "dni",
"hours": "godz", "hours": "godz",
"load": "Load",
"warn": "Warn",
"total": "Total",
"free": "Free",
"used": "Used",
"crit": "Crit", "crit": "Crit",
"read": "Read", "read": "Przeczytane",
"write": "Write", "write": "Zapis",
"gpu": "GPU", "gpu": "Karta graficzna",
"mem": "Mem", "mem": "Pamięć",
"swap": "Swap", "swap": "Swap"
"_temp": "Temp"
}, },
"changedetectionio": { "quicklaunch": {
"diffsDetected": "Wykryto różnic", "bookmark": "Zakładka",
"totalObserved": "Obserwowanych ogółem" "service": "Usługi",
"search": "Wyszukaj",
"custom": "Niestandardowe",
"visit": "Odwiedź",
"url": "Adres URL"
}, },
"wmo": { "wmo": {
"77-day": "Ziarnisty śnieg",
"0-day": "Słoneczny", "0-day": "Słoneczny",
"0-night": "Bezchmurny", "0-night": "Bezchmurny",
"1-day": "Głównie słoneczny", "1-day": "Głównie słoneczny",
@@ -301,6 +431,7 @@
"73-night": "Śnieg", "73-night": "Śnieg",
"75-day": "Ciężki śnieg", "75-day": "Ciężki śnieg",
"75-night": "Ciężki śnieg", "75-night": "Ciężki śnieg",
"77-day": "Ziarnisty śnieg",
"77-night": "Ziarnisty śnieg", "77-night": "Ziarnisty śnieg",
"80-day": "Lekkie opady", "80-day": "Lekkie opady",
"80-night": "Lekkie opady", "80-night": "Lekkie opady",
@@ -319,14 +450,6 @@
"99-day": "Burza z gradobiciem", "99-day": "Burza z gradobiciem",
"99-night": "Burza z gradobiciem" "99-night": "Burza z gradobiciem"
}, },
"quicklaunch": {
"bookmark": "Zakładka",
"service": "Usługi",
"search": "Wyszukaj",
"custom": "Niestandardowe",
"visit": "Odwiedź",
"url": "Adres URL"
},
"homebridge": { "homebridge": {
"available_update": "System", "available_update": "System",
"updates": "Aktualizacje", "updates": "Aktualizacje",
@@ -335,20 +458,30 @@
"child_bridges": "Child Bridges", "child_bridges": "Child Bridges",
"child_bridges_status": "{{ok}}/{{total}}", "child_bridges_status": "{{ok}}/{{total}}",
"up": "Up", "up": "Up",
"pending": "Oczekujące", "pending": "Oczekiwane",
"down": "Down" "down": "Down"
}, },
"healthchecks": {
"new": "Nowy",
"up": "Online",
"grace": "In Grace Period",
"down": "Offline",
"paused": "Zatrzymane",
"status": "Stan",
"last_ping": "Last Ping",
"never": "No pings yet"
},
"watchtower": {
"containers_scanned": "Zeskanowane",
"containers_updated": "Zaktualizowane",
"containers_failed": "Niepowodzenie"
},
"autobrr": { "autobrr": {
"approvedPushes": "Zaakceptowane", "approvedPushes": "Zaakceptowane",
"rejectedPushes": "Odrzucone", "rejectedPushes": "Odrzucone",
"filters": "Filtry", "filters": "Filtry",
"indexers": "Indeksery" "indexers": "Indeksery"
}, },
"watchtower": {
"containers_scanned": "Zeskanowane",
"containers_updated": "Zaktualizowane",
"containers_failed": "Niepowodzenie"
},
"tubearchivist": { "tubearchivist": {
"downloads": "Kolejka", "downloads": "Kolejka",
"videos": "Pliki wideo", "videos": "Pliki wideo",
@@ -358,18 +491,14 @@
"truenas": { "truenas": {
"load": "Obciążenie systemu", "load": "Obciążenie systemu",
"uptime": "Czas działania", "uptime": "Czas działania",
"alerts": "Ostrzeżenia", "alerts": "Alarmy",
"time": "{{value, number(style: unit; unitDisplay: long;)}}" "time": "{{value, number(style: unit; unitDisplay: long;)}}"
}, },
"navidrome": {
"please_wait": "Proszę czekać",
"nothing_streaming": "Brak aktywnych strumieni"
},
"pyload": { "pyload": {
"speed": "Prędkość", "speed": "Prędkość",
"active": "Aktywne", "active": "Aktywny",
"queue": "Kolejka", "queue": "Kolejka",
"total": "Razem" "total": "Całkowite"
}, },
"gluetun": { "gluetun": {
"public_ip": "Adres publiczny", "public_ip": "Adres publiczny",
@@ -380,62 +509,19 @@
"channels": "Kanały", "channels": "Kanały",
"hd": "HD" "hd": "HD"
}, },
"ping": {
"error": "Błąd",
"ping": "Ping"
},
"scrutiny": { "scrutiny": {
"passed": "Powodzenie", "passed": "Powodzenie",
"failed": "Nieudane", "failed": "Niepowodzenie",
"unknown": "Nieznane" "unknown": "Nieznany"
}, },
"paperlessngx": { "paperlessngx": {
"inbox": "Skrzynka odbiorcza", "inbox": "Skrzynka odbiorcza",
"total": "W sumie" "total": "Całkowite"
},
"deluge": {
"download": "Pobieranie",
"upload": "Wysyłanie",
"leech": "Leech",
"seed": "Seed"
},
"flood": {
"download": "Pobieranie",
"upload": "Wysyłanie",
"leech": "Leech",
"seed": "Seed"
},
"tdarr": {
"queue": "Kolejka",
"processed": "Przetworzone",
"errored": "Błędne",
"saved": "Zapisane"
},
"miniflux": {
"read": "Przeczytane",
"unread": "Nieprzeczytane"
}, },
"nextdns": { "nextdns": {
"wait": "Proszę czekać", "wait": "Proszę czekać",
"no_devices": "Nie otrzymano danych urządzenia" "no_devices": "Nie otrzymano danych urządzenia"
}, },
"common": {
"bibyterate": "{{value, rate(bits: false; binary: true)}}",
"bibitrate": "{{value, rate(bits: true; binary: true)}}"
},
"omada": {
"connectedSwitches": "Połączone przełączniki",
"connectedAp": "Połączone punkty dostępowe",
"activeUser": "Aktywne urządzenia",
"alerts": "Alarmy",
"connectedGateway": "Połączone bramy"
},
"downloadstation": {
"download": "Pobieranie",
"upload": "Wysyłanie",
"leech": "Leech",
"seed": "Seed"
},
"mikrotik": { "mikrotik": {
"cpuLoad": "Obciążenie procesora", "cpuLoad": "Obciążenie procesora",
"memoryUsed": "Zuyżyta pamięć", "memoryUsed": "Zuyżyta pamięć",
@@ -447,6 +533,12 @@
"streams_active": "Aktywne strumienie", "streams_active": "Aktywne strumienie",
"streams_xepg": "Kanały XEPG" "streams_xepg": "Kanały XEPG"
}, },
"opendtu": {
"yieldDay": "Dzisiaj",
"absolutePower": "Power",
"relativePower": "Power %",
"limit": "Limit"
},
"opnsense": { "opnsense": {
"cpu": "Obciążenie procesora", "cpu": "Obciążenie procesora",
"memory": "Pamięć rzeczywista", "memory": "Pamięć rzeczywista",
@@ -459,31 +551,36 @@
"print_progress": "Postęp", "print_progress": "Postęp",
"layers": "Warstwy" "layers": "Warstwy"
}, },
"medusa": {
"wanted": "Poszukiwane",
"queued": "Zakolejkowane",
"series": "Seriale"
},
"octoprint": { "octoprint": {
"printer_state": "Status", "printer_state": "Stan",
"temp_tool": "Tool temp", "temp_tool": "Tool temp",
"temp_bed": "Bed temp", "temp_bed": "Bed temp",
"job_completion": "Ukończono" "job_completion": "Ukończono"
}, },
"cloudflared": { "cloudflared": {
"origin_ip": "Origin IP", "origin_ip": "Origin IP",
"status": "Status" "status": "Stan"
},
"pfsense": {
"load": "Load Avg",
"memory": "Mem Usage",
"wanStatus": "WAN Status",
"up": "Up",
"down": "Down",
"temp": "Temperatura",
"disk": "Disk Usage",
"wanIP": "WAN IP"
}, },
"proxmoxbackupserver": { "proxmoxbackupserver": {
"datastore_usage": "Datastore", "datastore_usage": "Datastore",
"failed_tasks_24h": "Failed Tasks 24h", "failed_tasks_24h": "Failed Tasks 24h",
"cpu_usage": "CPU", "cpu_usage": "Procesor",
"memory_usage": "Pamięć" "memory_usage": "Pamięć"
}, },
"immich": { "immich": {
"users": "Użytkownicy", "users": "Użytkownicy",
"photos": "Zdjęcia", "photos": "Zdjęcia",
"videos": "Filmy", "videos": "Pliki wideo",
"storage": "Pamięć" "storage": "Pamięć"
}, },
"uptimekuma": { "uptimekuma": {
@@ -493,31 +590,37 @@
"incident": "Incydent", "incident": "Incydent",
"m": "min" "m": "min"
}, },
"atsumeru": {
"series": "Seriale",
"archives": "Archives",
"chapters": "Chapters",
"categories": "Categories"
},
"komga": { "komga": {
"libraries": "Biblioteki", "libraries": "Biblioteki",
"series": "Seriale", "series": "Seriale",
"books": "Książki" "books": "Książki"
}, },
"diskstation": {
"days": "Dni",
"uptime": "Czas działania",
"volumeAvailable": "Dostępne"
},
"mylar": { "mylar": {
"series": "Seriale", "series": "Seriale",
"issues": "Zgłoszenia", "issues": "Zgłoszenia",
"wanted": "Wanted" "wanted": "Poszukiwane"
}, },
"photoprism": { "photoprism": {
"albums": "Albumy", "albums": "Albumy",
"photos": "Zdjęcia", "photos": "Zdjęcia",
"videos": "Filmy", "videos": "Pliki wideo",
"people": "Ludzie" "people": "Ludzie"
}, },
"diskstation": {
"uptime": "Czas działania",
"volumeAvailable": "Dostępne",
"days": "Dni"
},
"fileflows": { "fileflows": {
"queue": "Kolejka", "queue": "Kolejka",
"processing": "Przetwarzanie", "processing": "Przetwarzane",
"processed": "Processed", "processed": "Przetworzone",
"time": "Czas" "time": "Czas"
}, },
"grafana": { "grafana": {
@@ -535,27 +638,17 @@
"numshares": "Shared Items" "numshares": "Shared Items"
}, },
"kopia": { "kopia": {
"status": "Status", "status": "Stan",
"size": "Rozmiar", "size": "Rozmiar",
"lastrun": "Ostatnie uruchomienie", "lastrun": "Ostatnie uruchomienie",
"nextrun": "Next Run", "nextrun": "Next Run",
"failed": "Nieudane" "failed": "Niepowodzenie"
}, },
"unmanic": { "unmanic": {
"active_workers": "Aktywni pracownicy", "active_workers": "Aktywni pracownicy",
"total_workers": "Total Workers", "total_workers": "Total Workers",
"records_total": "Długość kolejki" "records_total": "Długość kolejki"
}, },
"healthchecks": {
"new": "Nowy",
"up": "Online",
"grace": "In Grace Period",
"down": "Offline",
"paused": "Zatrzymane",
"status": "Status",
"last_ping": "Last Ping",
"never": "No pings yet"
},
"pterodactyl": { "pterodactyl": {
"servers": "Serwery", "servers": "Serwery",
"nodes": "Nodes" "nodes": "Nodes"
@@ -565,13 +658,6 @@
"targets_down": "Targets Down", "targets_down": "Targets Down",
"targets_total": "Total Targets" "targets_total": "Total Targets"
}, },
"minecraft": {
"players": "Gracze",
"version": "Wersja",
"status": "Status",
"up": "Online",
"down": "Offline"
},
"ghostfolio": { "ghostfolio": {
"gross_percent_today": "Dzisiaj", "gross_percent_today": "Dzisiaj",
"gross_percent_1y": "Rok", "gross_percent_1y": "Rok",
@@ -588,105 +674,50 @@
"lights_on": "Lights On", "lights_on": "Lights On",
"switches_on": "Switches On" "switches_on": "Switches On"
}, },
"freshrss": {
"subscriptions": "Subskrypcje",
"unread": "Nieprzeczytane"
},
"channelsdvrserver": {
"shows": "Shows",
"recordings": "Nagrywanie",
"scheduled": "W kolejce",
"passes": "Passes"
},
"whatsupdocker": { "whatsupdocker": {
"monitoring": "Monitoring", "monitoring": "Monitoring",
"updates": "Aktualizacje" "updates": "Aktualizacje"
}, },
"tailscale": { "calibreweb": {
"address": "Address", "books": "Książki",
"expires": "Expires", "authors": "Authors",
"never": "Never", "categories": "Categories",
"last_seen": "Last Seen", "series": "Seriale"
"now": "Now",
"years": "{{number}}y",
"weeks": "{{number}}w",
"days": "{{number}}d",
"hours": "{{number}}h",
"minutes": "{{number}}m",
"seconds": "{{number}}s",
"ago": "{{value}} Ago"
},
"qnap": {
"cpuUsage": "CPU Usage",
"memUsage": "MEM Usage",
"systemTempC": "System Temp",
"poolUsage": "Pool Usage",
"volumeUsage": "Volume Usage",
"invalid": "Invalid"
},
"pfsense": {
"load": "Load Avg",
"memory": "Mem Usage",
"wanStatus": "WAN Status",
"up": "Up",
"down": "Down",
"temp": "Temp",
"disk": "Disk Usage",
"wanIP": "WAN IP"
},
"caddy": {
"upstreams": "Upstreams",
"requests": "Current requests",
"requests_failed": "Failed requests"
},
"evcc": {
"pv_power": "Production",
"battery_soc": "Battery",
"grid_power": "Grid",
"home_power": "Consumption",
"charge_power": "Charger",
"watt_hour": "Wh"
},
"pialert": {
"total": "Total",
"connected": "Connected",
"new_devices": "New Devices",
"down_alerts": "Down Alerts"
}, },
"jdownloader": { "jdownloader": {
"downloadCount": "Queue Count", "downloadCount": "Kolejka",
"downloadSpeed": "Download Speed", "downloadBytesRemaining": "Pozostało",
"downloadBytesRemaining": "Remaining", "downloadTotalBytes": "Rozmiar",
"downloadTotalBytes": "Size" "downloadSpeed": "Prędkość"
}, },
"kavita": { "kavita": {
"seriesCount": "Series", "seriesCount": "Seriale",
"totalFiles": "Files" "totalFiles": "Pliki"
},
"gamedig": {
"name": "Name",
"map": "Map",
"currentPlayers": "Current players",
"players": "Players",
"maxPlayers": "Max players",
"bots": "Bots",
"ping": "Ping",
"status": "Status",
"online": "Online",
"offline": "Offline"
}, },
"azuredevops": { "azuredevops": {
"status": "Status", "result": "Result",
"status": "Stan",
"buildId": "Build ID", "buildId": "Build ID",
"succeeded": "Succeeded", "succeeded": "Succeeded",
"notStarted": "Not Started", "notStarted": "Not Started",
"failed": "Failed", "failed": "Niepowodzenie",
"myPrs": "My PRs",
"approved": "Approved",
"result": "Result",
"canceled": "Canceled", "canceled": "Canceled",
"inProgress": "In Progress", "inProgress": "In Progress",
"totalPrs": "Total PRs" "totalPrs": "Total PRs",
"myPrs": "My PRs",
"approved": "Zaakceptowane"
},
"gamedig": {
"status": "Stan",
"online": "Online",
"offline": "Offline",
"name": "Nazwa",
"map": "Mapa",
"currentPlayers": "Current players",
"players": "Gracze",
"maxPlayers": "Max players",
"bots": "Boty",
"ping": "Ping"
}, },
"urbackup": { "urbackup": {
"ok": "Ok", "ok": "Ok",
@@ -694,55 +725,37 @@
"noRecent": "Out of Date", "noRecent": "Out of Date",
"totalUsed": "Used Storage" "totalUsed": "Used Storage"
}, },
"openmediavault": {
"downloading": "Downloading",
"total": "Total",
"running": "Running",
"stopped": "Stopped",
"passed": "Passed",
"failed": "Failed"
},
"mealie": { "mealie": {
"recipes": "Recipes", "recipes": "Recipes",
"users": "Users", "users": "Użytkownicy",
"categories": "Categories", "categories": "Categories",
"tags": "Tags" "tags": "Tagi"
}, },
"atsumeru": { "openmediavault": {
"series": "Series", "downloading": "Downloading",
"archives": "Archives", "total": "Całkowite",
"chapters": "Chapters", "running": "Działa",
"categories": "Categories" "stopped": "Zatrzymane",
}, "passed": "Powodzenie",
"calibreweb": { "failed": "Niepowodzenie"
"books": "Books",
"authors": "Authors",
"categories": "Categories",
"series": "Series"
}, },
"uptimerobot": { "uptimerobot": {
"status": "Status", "status": "Stan",
"uptime": "Uptime", "uptime": "Czas działania",
"lastDown": "Last Downtime", "lastDown": "Last Downtime",
"downDuration": "Downtime Duration", "downDuration": "Downtime Duration",
"sitesUp": "Sites Up", "sitesUp": "Sites Up",
"sitesDown": "Sites Down", "sitesDown": "Niedziałające strony",
"paused": "Paused", "paused": "Zatrzymane",
"notyetchecked": "Not Yet Checked", "notyetchecked": "Not Yet Checked",
"up": "Up", "up": "Up",
"seemsdown": "Seems Down", "seemsdown": "Seems Down",
"down": "Down", "down": "Down",
"unknown": "Unknown" "unknown": "Nieznany"
},
"opendtu": {
"relativePower": "Power %",
"yieldDay": "Today",
"limit": "Limit",
"absolutePower": "Power"
}, },
"calendar": { "calendar": {
"physicalRelease": "Physical release",
"inCinemas": "In cinemas", "inCinemas": "In cinemas",
"physicalRelease": "Physical release",
"digitalRelease": "Digital release" "digitalRelease": "Digital release"
} }
} }

View File

@@ -382,7 +382,9 @@
}, },
"ping": { "ping": {
"error": "Erro", "error": "Erro",
"ping": "Ping" "ping": "Ping",
"up": "Up",
"down": "Down"
}, },
"scrutiny": { "scrutiny": {
"passed": "Passou", "passed": "Passou",

View File

@@ -395,7 +395,9 @@
}, },
"ping": { "ping": {
"error": "Erro", "error": "Erro",
"ping": "Tempo de resposta" "ping": "Tempo de resposta",
"up": "Up",
"down": "Down"
}, },
"scrutiny": { "scrutiny": {
"passed": "Aprovado", "passed": "Aprovado",

View File

@@ -382,7 +382,9 @@
}, },
"ping": { "ping": {
"error": "Error", "error": "Error",
"ping": "Ping" "ping": "Ping",
"up": "Up",
"down": "Down"
}, },
"scrutiny": { "scrutiny": {
"passed": "Passed", "passed": "Passed",

View File

@@ -382,7 +382,9 @@
}, },
"ping": { "ping": {
"error": "Ошибка", "error": "Ошибка",
"ping": "Пинг" "ping": "Пинг",
"up": "Up",
"down": "Down"
}, },
"scrutiny": { "scrutiny": {
"failed": "Неудачно", "failed": "Неудачно",

View File

@@ -195,7 +195,9 @@
}, },
"ping": { "ping": {
"error": "Chyba", "error": "Chyba",
"ping": "Odozva" "ping": "Odozva",
"up": "Up",
"down": "Down"
}, },
"emby": { "emby": {
"playing": "Prehrávané", "playing": "Prehrávané",

View File

@@ -152,7 +152,9 @@
}, },
"ping": { "ping": {
"error": "Napaka", "error": "Napaka",
"ping": "Ping" "ping": "Ping",
"up": "Up",
"down": "Down"
}, },
"emby": { "emby": {
"playing": "Predvaja", "playing": "Predvaja",

View File

@@ -382,7 +382,9 @@
}, },
"ping": { "ping": {
"error": "Error", "error": "Error",
"ping": "Ping" "ping": "Ping",
"up": "Up",
"down": "Down"
}, },
"scrutiny": { "scrutiny": {
"passed": "Passed", "passed": "Passed",

View File

@@ -382,7 +382,9 @@
}, },
"ping": { "ping": {
"error": "Error", "error": "Error",
"ping": "Ping" "ping": "Ping",
"up": "Up",
"down": "Down"
}, },
"scrutiny": { "scrutiny": {
"passed": "Passed", "passed": "Passed",

View File

@@ -382,7 +382,9 @@
}, },
"ping": { "ping": {
"error": "Error", "error": "Error",
"ping": "Ping" "ping": "Ping",
"up": "Up",
"down": "Down"
}, },
"scrutiny": { "scrutiny": {
"passed": "Passed", "passed": "Passed",

View File

@@ -107,7 +107,9 @@
}, },
"ping": { "ping": {
"error": "ข้อผิดพลาด", "error": "ข้อผิดพลาด",
"ping": "ปิง" "ping": "ปิง",
"up": "Up",
"down": "Down"
}, },
"emby": { "emby": {
"playing": "กำลังเล่น", "playing": "กำลังเล่น",

View File

@@ -382,7 +382,9 @@
}, },
"ping": { "ping": {
"error": "Hata", "error": "Hata",
"ping": "Ping" "ping": "Ping",
"up": "Up",
"down": "Down"
}, },
"scrutiny": { "scrutiny": {
"passed": "Geçti", "passed": "Geçti",

View File

@@ -172,7 +172,9 @@
}, },
"ping": { "ping": {
"error": "Помилка", "error": "Помилка",
"ping": "Пінг" "ping": "Пінг",
"up": "Up",
"down": "Down"
}, },
"emby": { "emby": {
"playing": "Відтворення", "playing": "Відтворення",

View File

@@ -382,7 +382,9 @@
}, },
"ping": { "ping": {
"error": "Error", "error": "Error",
"ping": "Ping" "ping": "Ping",
"up": "Up",
"down": "Down"
}, },
"scrutiny": { "scrutiny": {
"passed": "Passed", "passed": "Passed",

File diff suppressed because it is too large Load Diff

View File

@@ -382,7 +382,9 @@
}, },
"ping": { "ping": {
"error": "错误", "error": "错误",
"ping": "Ping" "ping": "Ping",
"up": "Up",
"down": "Down"
}, },
"scrutiny": { "scrutiny": {
"passed": "通过", "passed": "通过",

View File

@@ -0,0 +1,761 @@
{
"common": {
"bytes": "{{value, bytes}}",
"bits": "{{value, bytes(bits: true)}}",
"bbytes": "{{value, bytes(binary: true)}}",
"bbits": "{{value, bytes(bits: true; binary: true)}}",
"byterate": "{{value, rate(bits: false)}}",
"bibyterate": "{{value, rate(bits: false; binary: true)}}",
"bitrate": "{{value, rate(bits: true)}}",
"bibitrate": "{{value, rate(bits: true; binary: true)}}",
"percent": "{{value, percent}}",
"number": "{{value, number}}",
"ms": "{{value, number}}"
},
"widget": {
"missing_type": "缺失的组件类型: {{type}}",
"api_error": "API 错误",
"information": "信息",
"status": "状态",
"url": "URL",
"raw_error": "原始信息错误",
"response_data": "响应数据"
},
"weather": {
"current": "当前位置",
"allow": "点击以允许",
"updating": "更新中",
"wait": "请稍候"
},
"search": {
"placeholder": "搜索…"
},
"resources": {
"cpu": "CPU",
"mem": "内存",
"total": "总计",
"free": "空闲",
"used": "已使用",
"load": "负载",
"temp": "温度",
"max": "最大",
"uptime": "运行时间",
"months": "月",
"days": "日",
"hours": "时",
"minutes": "分"
},
"unifi": {
"users": "用户数",
"uptime": "系统运行时间",
"days": "天",
"wan": "WAN",
"lan": "LAN",
"wlan": "WLAN",
"devices": "设备",
"lan_devices": "LAN设备",
"wlan_devices": "WLAN 设备",
"lan_users": "LAN 用户",
"wlan_users": "WLAN 用户",
"up": "运行时间",
"down": "离线",
"wait": "请稍候",
"empty_data": "子系统状态未知"
},
"docker": {
"rx": "接收",
"tx": "发送",
"mem": "内存",
"cpu": "CPU",
"running": "运行中",
"offline": "离线",
"error": "错误",
"unknown": "未知",
"healthy": "健康",
"starting": "启动中",
"unhealthy": "不健康",
"not_found": "未找到",
"exited": "已退出",
"partial": "部分"
},
"ping": {
"http_status": "HTTP 状态",
"error": "错误",
"ping": "Ping",
"down": "离线",
"up": "在线",
"not_available": "不可用"
},
"emby": {
"playing": "正在播放",
"transcoding": "转码中",
"bitrate": "码率",
"no_active": "无活动流",
"movies": "电影",
"series": "剧集",
"episodes": "集",
"songs": "曲目"
},
"evcc": {
"pv_power": "发电量",
"battery_soc": "电量",
"grid_power": "电网功率",
"home_power": "全屋功率",
"charge_power": "充电功率",
"watt_hour": "Wh"
},
"flood": {
"download": "下载速率",
"upload": "上传速率",
"leech": "下载中",
"seed": "做种中"
},
"freshrss": {
"subscriptions": "订阅",
"unread": "未读"
},
"caddy": {
"upstreams": "上行",
"requests": "当前请求",
"requests_failed": "失败请求"
},
"changedetectionio": {
"totalObserved": "总监测数",
"diffsDetected": "监测到的变更"
},
"channelsdvrserver": {
"shows": "剧集",
"recordings": "录制中",
"scheduled": "已预约",
"passes": "通行证"
},
"tautulli": {
"playing": "正在播放",
"transcoding": "转码中",
"bitrate": "码率",
"no_active": "无活动流",
"plex_connection_error": "检查Plex连接"
},
"omada": {
"connectedAp": "已连接的 AP",
"activeUser": "活跃的设备",
"alerts": "警告",
"connectedGateway": "已连接的网关",
"connectedSwitches": "已连接的开关"
},
"nzbget": {
"rate": "速率",
"remaining": "剩余时间",
"downloaded": "已下载"
},
"plex": {
"streams": "活动流",
"albums": "专辑",
"movies": "电影",
"tv": "剧集"
},
"sabnzbd": {
"rate": "速率",
"queue": "队列",
"timeleft": "剩余时间"
},
"rutorrent": {
"active": "活动中",
"upload": "上传速率",
"download": "下载速率"
},
"transmission": {
"download": "下载速率",
"upload": "上传速率",
"leech": "下载中",
"seed": "做种中"
},
"qbittorrent": {
"download": "下载速率",
"upload": "上传速率",
"leech": "下载中",
"seed": "做种中"
},
"qnap": {
"cpuUsage": "CPU 使用率",
"memUsage": "内存使用率",
"systemTempC": "系统温度",
"poolUsage": "存储池使用情况",
"volumeUsage": "分卷使用率",
"invalid": "无效的"
},
"deluge": {
"download": "下载速率",
"upload": "上传速率",
"leech": "下载中",
"seed": "做种中"
},
"downloadstation": {
"download": "下载速率",
"upload": "上传速率",
"leech": "下载中",
"seed": "做种中"
},
"sonarr": {
"wanted": "关注中",
"queued": "已加入队列",
"series": "剧集",
"queue": "队列",
"unknown": "未知"
},
"radarr": {
"wanted": "关注中",
"missing": "缺失",
"queued": "已加入队列",
"movies": "电影",
"queue": "队列",
"unknown": "未知"
},
"lidarr": {
"wanted": "关注中",
"queued": "已加入队列",
"artists": "艺术家"
},
"readarr": {
"wanted": "关注中",
"queued": "已加入队列",
"books": "书籍"
},
"bazarr": {
"missingEpisodes": "缺少剧集",
"missingMovies": "缺少电影"
},
"ombi": {
"pending": "等待中",
"approved": "已批准",
"available": "可用"
},
"jellyseerr": {
"pending": "等待中",
"approved": "已批准",
"available": "可用"
},
"overseerr": {
"pending": "等待中",
"processing": "处理中",
"approved": "已批准",
"available": "可用"
},
"pialert": {
"total": "总计",
"connected": "已连接",
"new_devices": "新设备",
"down_alerts": "离线警报"
},
"pihole": {
"queries": "查询",
"blocked": "已屏蔽",
"blocked_percent": "已屏蔽 %",
"gravity": "屏蔽列表"
},
"adguard": {
"queries": "查询",
"blocked": "已屏蔽",
"filtered": "已过滤",
"latency": "延迟"
},
"speedtest": {
"upload": "上传速率",
"download": "下载速率",
"ping": "Ping"
},
"portainer": {
"running": "运行中",
"stopped": "已停止",
"total": "总计"
},
"tailscale": {
"address": "地址",
"expires": "失效",
"never": "从未",
"last_seen": "最后上线",
"now": "当前",
"years": "{{number}}年",
"weeks": "{{number}}周",
"days": "{{number}}天",
"hours": "{{number}}时",
"minutes": "{{number}}分",
"seconds": "{{number}}秒",
"ago": "{{value}} 之前"
},
"tdarr": {
"queue": "队列",
"processed": "已处理",
"errored": "错误",
"saved": "已保存"
},
"traefik": {
"routers": "路由",
"services": "服务",
"middleware": "中间件"
},
"navidrome": {
"nothing_streaming": "无活动流",
"please_wait": "请稍候"
},
"npm": {
"enabled": "启用",
"disabled": "禁用",
"total": "总计"
},
"coinmarketcap": {
"configure": "配置一个或多个加密货币进行跟踪",
"1hour": "1 小时",
"1day": "1 天",
"7days": "7 天",
"30days": "30 天"
},
"gotify": {
"apps": "应用",
"clients": "客户端",
"messages": "消息"
},
"prowlarr": {
"enableIndexers": "索引器",
"numberOfGrabs": "抓取",
"numberOfQueries": "查询",
"numberOfFailGrabs": "抓取失败",
"numberOfFailQueries": "查询失败"
},
"jackett": {
"configured": "已配置",
"errored": "错误"
},
"strelaysrv": {
"numActiveSessions": "会话",
"numConnections": "连接数",
"dataRelayed": "中继",
"transferRate": "速率"
},
"mastodon": {
"user_count": "用户数",
"status_count": "文章",
"domain_count": "域名"
},
"medusa": {
"wanted": "关注中",
"queued": "已加入队列",
"series": "剧集"
},
"minecraft": {
"players": "玩家",
"version": "版本",
"status": "状态",
"up": "在线",
"down": "离线"
},
"miniflux": {
"read": "已读",
"unread": "未读"
},
"authentik": {
"users": "用户数",
"loginsLast24H": "登录 (24小时)",
"failedLoginsLast24H": "登录失败 (24小时)"
},
"proxmox": {
"mem": "内存",
"cpu": "CPU",
"lxc": "LXC",
"vms": "VMs"
},
"glances": {
"cpu": "CPU",
"load": "负载",
"wait": "请稍候",
"temp": "温度",
"_temp": "温度",
"warn": "警告",
"uptime": "运行时间",
"total": "总计",
"free": "空闲",
"used": "已使用",
"days": "日",
"hours": "时",
"crit": "严重",
"read": "已读",
"write": "写入",
"gpu": "GPU",
"mem": "内存",
"swap": "Swap"
},
"quicklaunch": {
"bookmark": "书签",
"service": "服务",
"search": "搜索",
"custom": "自定义",
"visit": "访问",
"url": "URL"
},
"wmo": {
"0-day": "晴天",
"0-night": "晴朗",
"1-day": "晴天为主",
"1-night": "晴朗为主",
"2-day": "局部多云",
"2-night": "局部多云",
"3-day": "多云",
"3-night": "多云",
"45-day": "雾",
"45-night": "雾",
"48-day": "雾",
"48-night": "雾",
"51-day": "小细雨",
"51-night": "小细雨",
"53-day": "细雨",
"53-night": "细雨",
"55-day": "大细雨",
"55-night": "大细雨",
"56-day": "小冻细雨",
"56-night": "小冻细雨",
"57-day": "冻细雨",
"57-night": "冻细雨",
"61-day": "小雨",
"61-night": "小雨",
"63-day": "雨",
"63-night": "雨",
"65-day": "大雨",
"65-night": "大雨",
"66-day": "冻雨",
"66-night": "冻雨",
"67-day": "冻雨",
"67-night": "冻雨",
"71-day": "小雪",
"71-night": "小雪",
"73-day": "雪",
"73-night": "雪",
"75-day": "大雪",
"75-night": "大雪",
"77-day": "雪粒",
"77-night": "雪粒",
"80-day": "小阵雨",
"80-night": "小阵雨",
"81-day": "阵雨",
"81-night": "阵雨",
"82-day": "强阵雨",
"82-night": "强阵雨",
"85-day": "阵雪",
"85-night": "阵雪",
"86-day": "阵雪",
"86-night": "阵雪",
"95-day": "雷雨",
"95-night": "雷雨",
"96-day": "雷暴夹冰雹",
"96-night": "雷暴夹冰雹",
"99-day": "雷暴夹冰雹",
"99-night": "雷暴夹冰雹"
},
"homebridge": {
"available_update": "系统",
"updates": "更新",
"update_available": "有可用更新",
"up_to_date": "已是最新版本",
"child_bridges": "子网桥",
"child_bridges_status": "{{ok}}/{{total}}",
"up": "在线",
"pending": "等待中",
"down": "离线"
},
"healthchecks": {
"new": "新增",
"up": "在线",
"grace": "处于宽限期",
"down": "离线",
"paused": "已暂停",
"status": "状态",
"last_ping": "上次 Ping",
"never": "尚未 Ping"
},
"watchtower": {
"containers_scanned": "已扫描",
"containers_updated": "已更新",
"containers_failed": "失败"
},
"autobrr": {
"approvedPushes": "已批准",
"rejectedPushes": "拒绝",
"filters": "过滤器",
"indexers": "索引器"
},
"tubearchivist": {
"downloads": "队列",
"videos": "视频",
"channels": "频道",
"playlists": "播放列表"
},
"truenas": {
"load": "系统负载",
"uptime": "运行时间",
"alerts": "警告",
"time": "{{value, number(style: unit; unitDisplay: long;)}}"
},
"pyload": {
"speed": "速度",
"active": "活动中",
"queue": "队列",
"total": "总计"
},
"gluetun": {
"public_ip": "公网 IP",
"region": "地区",
"country": "国家"
},
"hdhomerun": {
"channels": "频道",
"hd": "HD"
},
"scrutiny": {
"passed": "通过",
"failed": "失败",
"unknown": "未知"
},
"paperlessngx": {
"inbox": "收件箱",
"total": "总计"
},
"nextdns": {
"wait": "请稍候",
"no_devices": "未收到设备数据"
},
"mikrotik": {
"cpuLoad": "CPU 负载",
"memoryUsed": "内存占用",
"uptime": "运行时间",
"numberOfLeases": "租约"
},
"xteve": {
"streams_all": "所有流",
"streams_active": "活动流",
"streams_xepg": "XEPG 频道"
},
"opendtu": {
"yieldDay": "今日",
"absolutePower": "功率",
"relativePower": "功率 %",
"limit": "限制"
},
"opnsense": {
"cpu": "CPU 负载",
"memory": "活动内存",
"wanUpload": "WAN 上传",
"wanDownload": "WAN 下载"
},
"moonraker": {
"printer_state": "打印机状态",
"print_status": "打印状态",
"print_progress": "进度",
"layers": "层"
},
"octoprint": {
"printer_state": "状态",
"temp_tool": "喷头温度",
"temp_bed": "热床温度",
"job_completion": "完成"
},
"cloudflared": {
"origin_ip": "来源 IP",
"status": "状态"
},
"pfsense": {
"load": "平均负载",
"memory": "内存使用率",
"wanStatus": "WAN 状态",
"up": "在线",
"down": "离线",
"temp": "温度",
"disk": "磁盘使用量",
"wanIP": "WAN IP"
},
"proxmoxbackupserver": {
"datastore_usage": "数据存储",
"failed_tasks_24h": "24小时内失败任务",
"cpu_usage": "CPU",
"memory_usage": "内存"
},
"immich": {
"users": "用户数",
"photos": "照片",
"videos": "视频",
"storage": "存储空间"
},
"uptimekuma": {
"up": "在线网站",
"down": "离线网站",
"uptime": "运行时间",
"incident": "事件",
"m": "分"
},
"atsumeru": {
"series": "剧集",
"archives": "存档",
"chapters": "章节",
"categories": "类别"
},
"komga": {
"libraries": "库",
"series": "剧集",
"books": "书籍"
},
"diskstation": {
"days": "天",
"uptime": "运行时间",
"volumeAvailable": "可用"
},
"mylar": {
"series": "剧集",
"issues": "出版",
"wanted": "关注中"
},
"photoprism": {
"albums": "专辑",
"photos": "照片",
"videos": "视频",
"people": "人物"
},
"fileflows": {
"queue": "队列",
"processing": "处理中",
"processed": "已处理",
"time": "时间"
},
"grafana": {
"dashboards": "仪表板",
"datasources": "数据源",
"totalalerts": "警告总数",
"alertstriggered": "触发警告"
},
"nextcloud": {
"cpuload": "CPU 负载",
"memoryusage": "内存使用量",
"freespace": "剩余空间",
"activeusers": "活动用户",
"numfiles": "文件",
"numshares": "已共享项目"
},
"kopia": {
"status": "状态",
"size": "大小",
"lastrun": "上一次运行",
"nextrun": "下一次运行",
"failed": "失败"
},
"unmanic": {
"active_workers": "活动工作程序",
"total_workers": "总工作程序",
"records_total": "队列长度"
},
"pterodactyl": {
"servers": "服务器",
"nodes": "节点"
},
"prometheus": {
"targets_up": "上线目标",
"targets_down": "离线目标",
"targets_total": "目标总数"
},
"ghostfolio": {
"gross_percent_today": "今日",
"gross_percent_1y": "1年",
"gross_percent_max": "所有时间"
},
"audiobookshelf": {
"podcasts": "播客",
"books": "书籍",
"podcastsDuration": "时长",
"booksDuration": "时长"
},
"homeassistant": {
"people_home": "在家人数",
"lights_on": "灯光开启",
"switches_on": "开关开启"
},
"whatsupdocker": {
"monitoring": "监测中",
"updates": "更新"
},
"calibreweb": {
"books": "书籍",
"authors": "作者",
"categories": "类别",
"series": "剧集"
},
"jdownloader": {
"downloadCount": "队列",
"downloadBytesRemaining": "剩余时间",
"downloadTotalBytes": "大小",
"downloadSpeed": "速度"
},
"kavita": {
"seriesCount": "剧集",
"totalFiles": "文件"
},
"azuredevops": {
"result": "结果",
"status": "状态",
"buildId": "构建 ID",
"succeeded": "成功",
"notStarted": "尚未开始",
"failed": "失败",
"canceled": "已取消",
"inProgress": "处理中",
"totalPrs": "总 PR",
"myPrs": "我的 PR",
"approved": "已批准"
},
"gamedig": {
"status": "状态",
"online": "在线",
"offline": "离线",
"name": "名称",
"map": "地图",
"currentPlayers": "当前玩家",
"players": "玩家",
"maxPlayers": "玩家上限",
"bots": "机器人",
"ping": "Ping"
},
"urbackup": {
"ok": "成功",
"errored": "错误",
"noRecent": "已过期",
"totalUsed": "使用的存储"
},
"mealie": {
"recipes": "食谱",
"users": "用户数",
"categories": "类别",
"tags": "标签"
},
"openmediavault": {
"downloading": "下载中",
"total": "总计",
"running": "运行中",
"stopped": "已停止",
"passed": "通过",
"failed": "失败"
},
"uptimerobot": {
"status": "状态",
"uptime": "运行时间",
"lastDown": "上次下线时间",
"downDuration": "下线时长",
"sitesUp": "在线网站",
"sitesDown": "离线网站",
"paused": "已暂停",
"notyetchecked": "尚未检查",
"up": "在线",
"seemsdown": "貌似离线",
"down": "离线",
"unknown": "未知"
},
"calendar": {
"inCinemas": "上映中",
"physicalRelease": "实体发行",
"digitalRelease": "数字发行"
}
}

View File

@@ -382,7 +382,9 @@
}, },
"ping": { "ping": {
"error": "錯誤", "error": "錯誤",
"ping": "Ping" "ping": "Ping",
"up": "Up",
"down": "Down"
}, },
"scrutiny": { "scrutiny": {
"passed": "通過", "passed": "通過",

View File

@@ -26,3 +26,4 @@ requests==2.31.0
six==1.16.0 six==1.16.0
urllib3==2.0.5 urllib3==2.0.5
watchdog==3.0.0 watchdog==3.0.0
pre-commit==3.5.0

View File

@@ -1,6 +1,6 @@
import { useRef } from "react"; import { useRef } from "react";
import classNames from "classnames"; import classNames from "classnames";
import { Disclosure, Transition } from '@headlessui/react'; import { Disclosure, Transition } from "@headlessui/react";
import { MdKeyboardArrowDown } from "react-icons/md"; import { MdKeyboardArrowDown } from "react-icons/md";
import ErrorBoundary from "components/errorboundry"; import ErrorBoundary from "components/errorboundry";
@@ -15,7 +15,7 @@ export default function BookmarksGroup({ bookmarks, layout, disableCollapse }) {
className={classNames( className={classNames(
"bookmark-group", "bookmark-group",
layout?.style === "row" ? "basis-full" : "basis-full md:basis-1/4 lg:basis-1/5 xl:basis-1/6", layout?.style === "row" ? "basis-full" : "basis-full md:basis-1/4 lg:basis-1/5 xl:basis-1/6",
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",
)} )}
> >
<Disclosure defaultOpen> <Disclosure defaultOpen>
@@ -28,12 +28,14 @@ export default function BookmarksGroup({ bookmarks, layout, disableCollapse }) {
<ResolvedIcon icon={layout.icon} /> <ResolvedIcon icon={layout.icon} />
</div> </div>
)} )}
<h2 className="text-theme-800 dark:text-theme-300 text-xl font-medium bookmark-group-name">{bookmarks.name}</h2> <h2 className="text-theme-800 dark:text-theme-300 text-xl font-medium bookmark-group-name">
{bookmarks.name}
</h2>
<MdKeyboardArrowDown <MdKeyboardArrowDown
className={classNames( 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-180" open ? "" : "rotate-180",
)} )}
/> />
</Disclosure.Button> </Disclosure.Button>

View File

@@ -15,22 +15,24 @@ export default function Item({ bookmark }) {
title={bookmark.name} title={bookmark.name}
target={bookmark.target ?? settings.target ?? "_blank"} target={bookmark.target ?? settings.target ?? "_blank"}
className={classNames( className={classNames(
settings.cardBlur !== undefined && `backdrop-blur${settings.cardBlur.length ? '-' : ""}${settings.cardBlur}`, 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" "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="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"> <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">
{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} />
</div> </div>
} )}
{!bookmark.icon && bookmark.abbr} {!bookmark.icon && bookmark.abbr}
</div> </div>
<div className="flex-1 flex items-center justify-between rounded-r-md bookmark-text"> <div className="flex-1 flex items-center justify-between rounded-r-md bookmark-text">
<div className="flex-1 grow pl-3 py-2 text-xs bookmark-name">{bookmark.name}</div> <div className="flex-1 grow pl-3 py-2 text-xs bookmark-name">{bookmark.name}</div>
<div className="px-2 py-2 truncate text-theme-500 dark:text-theme-300 text-xs bookmark-description">{description}</div> <div className="px-2 py-2 truncate text-theme-500 dark:text-theme-300 text-xs bookmark-description">
{description}
</div>
</div> </div>
</div> </div>
</a> </a>

View File

@@ -9,7 +9,7 @@ export default function List({ bookmarks, layout }) {
<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 bookmark-list" "mt-3 bookmark-list",
)} )}
> >
{bookmarks.map((bookmark) => ( {bookmarks.map((bookmark) => (

View File

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

View File

@@ -6,10 +6,19 @@ import ResolvedIcon from "./resolvedicon";
import { SettingsContext } from "utils/contexts/settings"; import { SettingsContext } from "utils/contexts/settings";
export default function QuickLaunch({servicesAndBookmarks, searchString, setSearchString, isOpen, close, searchProvider}) { export default function QuickLaunch({
servicesAndBookmarks,
searchString,
setSearchString,
isOpen,
close,
searchProvider,
}) {
const { t } = useTranslation(); const { t } = useTranslation();
const { settings } = useContext(SettingsContext); const { settings } = useContext(SettingsContext);
const { searchDescriptions, hideVisitURL } = settings?.quicklaunch ? settings.quicklaunch : { searchDescriptions: false, hideVisitURL: false }; const { searchDescriptions, hideVisitURL } = settings?.quicklaunch
? settings.quicklaunch
: { searchDescriptions: false, hideVisitURL: false };
const searchField = useRef(); const searchField = useRef();
@@ -19,7 +28,7 @@ export default function QuickLaunch({servicesAndBookmarks, searchString, setSear
function openCurrentItem(newWindow) { function openCurrentItem(newWindow) {
const result = results[currentItemIndex]; const result = results[currentItemIndex];
window.open(result.href, newWindow ? "_blank" : result.target ?? settings.target ?? "_blank", 'noreferrer'); window.open(result.href, newWindow ? "_blank" : result.target ?? settings.target ?? "_blank", "noreferrer");
} }
const closeAndReset = useCallback(() => { const closeAndReset = useCallback(() => {
@@ -35,7 +44,7 @@ export default function QuickLaunch({servicesAndBookmarks, searchString, setSear
try { try {
if (!/.+[.:].+/g.test(rawSearchString)) throw new Error(); // basic test for probably a url if (!/.+[.:].+/g.test(rawSearchString)) throw new Error(); // basic test for probably a url
let urlString = rawSearchString; let urlString = rawSearchString;
if (urlString.indexOf('http') !== 0) urlString = `https://${rawSearchString}`; if (urlString.indexOf("http") !== 0) urlString = `https://${rawSearchString}`;
setUrl(new URL(urlString)); // basic validation setUrl(new URL(urlString)); // basic validation
} catch (e) { } catch (e) {
setUrl(null); setUrl(null);
@@ -83,12 +92,12 @@ export default function QuickLaunch({servicesAndBookmarks, searchString, setSear
useEffect(() => { useEffect(() => {
if (searchString.length === 0) setResults([]); if (searchString.length === 0) setResults([]);
else { else {
let newResults = servicesAndBookmarks.filter(r => { let newResults = servicesAndBookmarks.filter((r) => {
const nameMatch = r.name.toLowerCase().includes(searchString); const nameMatch = r.name.toLowerCase().includes(searchString);
let descriptionMatch; let descriptionMatch;
if (searchDescriptions) { if (searchDescriptions) {
descriptionMatch = r.description?.toLowerCase().includes(searchString) descriptionMatch = r.description?.toLowerCase().includes(searchString);
r.priority = nameMatch ? 2 * (+nameMatch) : +descriptionMatch; // eslint-disable-line no-param-reassign r.priority = nameMatch ? 2 * +nameMatch : +descriptionMatch; // eslint-disable-line no-param-reassign
} }
return nameMatch || descriptionMatch; return nameMatch || descriptionMatch;
}); });
@@ -98,23 +107,19 @@ export default function QuickLaunch({servicesAndBookmarks, searchString, setSear
} }
if (searchProvider) { if (searchProvider) {
newResults.push( newResults.push({
{
href: searchProvider.url + encodeURIComponent(searchString), href: searchProvider.url + encodeURIComponent(searchString),
name: `${searchProvider.name ?? t("quicklaunch.custom")} ${t("quicklaunch.search")} `, name: `${searchProvider.name ?? t("quicklaunch.custom")} ${t("quicklaunch.search")} `,
type: 'search', type: "search",
} });
)
} }
if (!hideVisitURL && url) { if (!hideVisitURL && url) {
newResults.unshift( newResults.unshift({
{
href: url.toString(), href: url.toString(),
name: `${t("quicklaunch.visit")} URL`, name: `${t("quicklaunch.visit")} URL`,
type: 'url', type: "url",
} });
)
} }
setResults(newResults); setResults(newResults);
@@ -125,7 +130,6 @@ export default function QuickLaunch({servicesAndBookmarks, searchString, setSear
} }
}, [searchString, servicesAndBookmarks, searchDescriptions, hideVisitURL, searchProvider, url, t]); }, [searchString, servicesAndBookmarks, searchDescriptions, hideVisitURL, searchProvider, url, t]);
const [hidden, setHidden] = useState(true); const [hidden, setHidden] = useState(true);
useEffect(() => { useEffect(() => {
function handleBackdropClick(event) { function handleBackdropClick(event) {
@@ -134,66 +138,103 @@ export default function QuickLaunch({servicesAndBookmarks, searchString, setSear
if (isOpen) { if (isOpen) {
searchField.current.focus(); searchField.current.focus();
document.body.addEventListener('click', handleBackdropClick); document.body.addEventListener("click", handleBackdropClick);
setHidden(false); setHidden(false);
} else { } else {
document.body.removeEventListener('click', handleBackdropClick); document.body.removeEventListener("click", handleBackdropClick);
searchField.current.blur(); searchField.current.blur();
setTimeout(() => { setTimeout(() => {
setHidden(true); setHidden(true);
}, 300); // disable on close }, 300); // disable on close
} }
}, [isOpen, closeAndReset]); }, [isOpen, closeAndReset]);
function highlightText(text) { function highlightText(text) {
const parts = text.split(new RegExp(`(${searchString})`, 'gi')); const parts = text.split(new RegExp(`(${searchString})`, "gi"));
return (
<span>
{parts.map((part, i) =>
part.toLowerCase() === searchString.toLowerCase() ? (
// eslint-disable-next-line react/no-array-index-key // eslint-disable-next-line react/no-array-index-key
return <span>{parts.map((part, i) => part.toLowerCase() === searchString.toLowerCase() ? <span key={`${searchString}_${i}`} className="bg-theme-300/10">{part}</span> : part)}</span>; <span key={`${searchString}_${i}`} className="bg-theme-300/10">
{part}
</span>
) : (
part
),
)}
</span>
);
} }
return ( return (
<div className={classNames( <div
className={classNames(
"relative z-40 ease-in-out duration-300 transition-opacity", "relative z-40 ease-in-out duration-300 transition-opacity",
hidden && !isOpen && "hidden", hidden && !isOpen && "hidden",
!hidden && isOpen && "opacity-100", !hidden && isOpen && "opacity-100",
!isOpen && "opacity-0", !isOpen && "opacity-0",
)} role="dialog" aria-modal="true"> )}
role="dialog"
aria-modal="true"
>
<div className="fixed inset-0 bg-gray-500 bg-opacity-50" /> <div className="fixed inset-0 bg-gray-500 bg-opacity-50" />
<div className="fixed inset-0 z-20 overflow-y-auto"> <div className="fixed inset-0 z-20 overflow-y-auto">
<div className="flex min-h-full min-w-full items-start justify-center text-center"> <div className="flex min-h-full min-w-full items-start justify-center text-center">
<dialog className="mt-[10%] min-w-[80%] max-w-[90%] md:min-w-[40%] rounded-md p-0 block 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-50 dark:bg-theme-800"> <dialog className="mt-[10%] min-w-[80%] max-w-[90%] md:min-w-[40%] rounded-md p-0 block 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-50 dark:bg-theme-800">
<input placeholder="Search" className={classNames( <input
placeholder="Search"
className={classNames(
results.length > 0 && "rounded-t-md", results.length > 0 && "rounded-t-md",
results.length === 0 && "rounded-md", results.length === 0 && "rounded-md",
"w-full p-4 m-0 border-0 border-b border-slate-700 focus:border-slate-700 focus:outline-0 focus:ring-0 text-sm md:text-xl text-theme-700 dark:text-theme-200 bg-theme-60 dark:bg-theme-800" "w-full p-4 m-0 border-0 border-b border-slate-700 focus:border-slate-700 focus:outline-0 focus:ring-0 text-sm md:text-xl text-theme-700 dark:text-theme-200 bg-theme-60 dark:bg-theme-800",
)} type="text" autoCorrect="false" ref={searchField} value={searchString} onChange={handleSearchChange} onKeyDown={handleSearchKeyDown} /> )}
{results.length > 0 && <ul className="max-h-[60vh] overflow-y-auto m-2"> type="text"
autoCorrect="false"
ref={searchField}
value={searchString}
onChange={handleSearchChange}
onKeyDown={handleSearchKeyDown}
/>
{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} onClick={handleItemClick} onKeyDown={handleItemKeyDown} 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",
)}> )}
>
<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} />}
{r.abbr && r.abbr} {r.abbr && r.abbr}
</div>} </div>
)}
<div className="flex flex-col md:flex-row text-left items-baseline mr-4 pointer-events-none"> <div className="flex flex-col md:flex-row text-left items-baseline mr-4 pointer-events-none">
<span className="mr-4">{r.name}</span> <span className="mr-4">{r.name}</span>
{r.description && {r.description && (
<span className="text-xs text-theme-600 text-light"> <span className="text-xs text-theme-600 text-light">
{searchDescriptions && r.priority < 2 ? highlightText(r.description) : r.description} {searchDescriptions && r.priority < 2 ? highlightText(r.description) : r.description}
</span> </span>
} )}
</div> </div>
</div> </div>
<div className="text-xs text-theme-600 font-bold pointer-events-none">{t(`quicklaunch.${r.type ? r.type.toLowerCase() : 'bookmark'}`)}</div> <div className="text-xs text-theme-600 font-bold pointer-events-none">
{t(`quicklaunch.${r.type ? r.type.toLowerCase() : "bookmark"}`)}
</div>
</button> </button>
</li> </li>
))} ))}
</ul>} </ul>
)}
</dialog> </dialog>
</div> </div>
</div> </div>

View File

@@ -5,8 +5,8 @@ import { SettingsContext } from "utils/contexts/settings";
import { ThemeContext } from "utils/contexts/theme"; import { ThemeContext } from "utils/contexts/theme";
const iconSetURLs = { const iconSetURLs = {
'mdi': "https://cdn.jsdelivr.net/npm/@mdi/svg@latest/svg/", mdi: "https://cdn.jsdelivr.net/npm/@mdi/svg@latest/svg/",
'si' : "https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/", si: "https://cdn.jsdelivr.net/npm/simple-icons@latest/icons/",
}; };
export default function ResolvedIcon({ icon, width = 32, height = 32, alt = "logo" }) { export default function ResolvedIcon({ icon, width = 32, height = 32, alt = "logo" }) {
@@ -38,12 +38,13 @@ export default function ResolvedIcon({ icon, width = 32, height = 32, alt = "log
if (prefix in iconSetURLs) { if (prefix in iconSetURLs) {
// default to theme setting // default to theme setting
let iconName = icon.replace(`${prefix}-`, "").replace(".svg", ""); let iconName = icon.replace(`${prefix}-`, "").replace(".svg", "");
let iconColor = settings.iconStyle === "theme" ? let iconColor =
`rgb(var(--color-${ theme === "dark" ? 300 : 900 }) / var(--tw-text-opacity, 1))` : settings.iconStyle === "theme"
"linear-gradient(180deg, rgb(var(--color-logo-start)), rgb(var(--color-logo-stop)))"; ? `rgb(var(--color-${theme === "dark" ? 300 : 900}) / var(--tw-text-opacity, 1))`
: "linear-gradient(180deg, rgb(var(--color-logo-start)), rgb(var(--color-logo-stop)))";
// use custom hex color if provided // use custom hex color if provided
const colorMatches = icon.match(/[#][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]$/i) const colorMatches = icon.match(/[#][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]$/i);
if (colorMatches?.length) { if (colorMatches?.length) {
iconName = icon.replace(`${prefix}-`, "").replace(".svg", "").replace(`-${colorMatches[0]}`, ""); iconName = icon.replace(`${prefix}-`, "").replace(".svg", "").replace(`-${colorMatches[0]}`, "");
iconColor = `${colorMatches[0]}`; iconColor = `${colorMatches[0]}`;
@@ -56,8 +57,8 @@ export default function ResolvedIcon({ icon, width = 32, height = 32, alt = "log
style={{ style={{
width, width,
height, height,
maxWidth: '100%', maxWidth: "100%",
maxHeight: '100%', maxHeight: "100%",
background: `${iconColor}`, background: `${iconColor}`,
mask: `url(${iconSource}) no-repeat center / contain`, mask: `url(${iconSource}) no-repeat center / contain`,
WebkitMask: `url(${iconSource}) no-repeat center / contain`, WebkitMask: `url(${iconSource}) no-repeat center / contain`,
@@ -79,7 +80,7 @@ export default function ResolvedIcon({ icon, width = 32, height = 32, alt = "log
height, height,
objectFit: "contain", objectFit: "contain",
maxHeight: "100%", maxHeight: "100%",
maxWidth: "100%" maxWidth: "100%",
}} }}
alt={alt} alt={alt}
/> />
@@ -97,7 +98,7 @@ export default function ResolvedIcon({ icon, width = 32, height = 32, alt = "log
height, height,
objectFit: "contain", objectFit: "contain",
maxHeight: "100%", maxHeight: "100%",
maxWidth: "100%" maxWidth: "100%",
}} }}
alt={alt} alt={alt}
/> />

View File

@@ -33,7 +33,7 @@ export default function Dropdown({ options, value, setValue }) {
type="button" type="button"
className={classNames( className={classNames(
value === option.value ? "bg-theme-300/40 dark:bg-theme-900/40" : "", value === option.value ? "bg-theme-300/40 dark:bg-theme-900/40" : "",
"w-full block px-3 py-1.5 text-sm hover:bg-theme-300/70 hover:dark:bg-theme-900/70 text-left" "w-full block px-3 py-1.5 text-sm hover:bg-theme-300/70 hover:dark:bg-theme-900/70 text-left",
)} )}
> >
{option.label} {option.label}

View File

@@ -1,13 +1,12 @@
import { useRef } from "react"; import { useRef } from "react";
import classNames from "classnames"; import classNames from "classnames";
import { Disclosure, Transition } from '@headlessui/react'; import { Disclosure, Transition } from "@headlessui/react";
import { MdKeyboardArrowDown } from "react-icons/md"; import { MdKeyboardArrowDown } from "react-icons/md";
import List from "components/services/list"; import List from "components/services/list";
import ResolvedIcon from "components/resolvedicon"; import ResolvedIcon from "components/resolvedicon";
export default function ServicesGroup({ group, services, layout, fiveColumns, disableCollapse }) { export default function ServicesGroup({ group, services, layout, fiveColumns, disableCollapse }) {
const panel = useRef(); const panel = useRef();
return ( return (
@@ -23,33 +22,43 @@ export default function ServicesGroup({ group, services, layout, fiveColumns, di
<Disclosure defaultOpen> <Disclosure defaultOpen>
{({ open }) => ( {({ open }) => (
<> <>
{ 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 service-group-icon"> <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 service-group-name">{services.name}</h2> <h2 className="flex text-theme-800 dark:text-theme-300 text-xl font-medium service-group-name">
<MdKeyboardArrowDown className={classNames( {services.name}
disableCollapse ? 'hidden' : '', </h2>
'transition-all opacity-0 group-hover:opacity-100 ml-auto text-theme-800 dark:text-theme-300 text-xl', <MdKeyboardArrowDown
open ? '' : 'rotate-180' className={classNames(
)} /> disableCollapse ? "hidden" : "",
"transition-all opacity-0 group-hover:opacity-100 ml-auto text-theme-800 dark:text-theme-300 text-xl",
open ? "" : "rotate-180",
)}
/>
</Disclosure.Button> </Disclosure.Button>
} )}
<Transition <Transition
// Otherwise the transition group does display: none and cancels animation // Otherwise the transition group does display: none and cancels animation
className="!block" className="!block"
unmount={false} unmount={false}
beforeLeave={() => { beforeLeave={() => {
panel.current.style.height = `${panel.current.scrollHeight}px`; panel.current.style.height = `${panel.current.scrollHeight}px`;
setTimeout(() => {panel.current.style.height = `0`}, 1); setTimeout(() => {
panel.current.style.height = `0`;
}, 1);
}} }}
beforeEnter={() => { beforeEnter={() => {
panel.current.style.height = `0px`; panel.current.style.height = `0px`;
setTimeout(() => {panel.current.style.height = `${panel.current.scrollHeight}px`}, 1); setTimeout(() => {
setTimeout(() => {panel.current.style.height = 'auto'}, 150); // animation is 150ms panel.current.style.height = `${panel.current.scrollHeight}px`;
}, 1);
setTimeout(() => {
panel.current.style.height = "auto";
}, 150); // animation is 150ms
}} }}
> >
<Disclosure.Panel className="transition-all overflow-hidden duration-300 ease-out" ref={panel} static> <Disclosure.Panel className="transition-all overflow-hidden duration-300 ease-out" ref={panel} static>

View File

@@ -14,7 +14,8 @@ import ResolvedIcon from "components/resolvedicon";
export default function Item({ service, group }) { export default function Item({ service, group }) {
const hasLink = service.href && service.href !== "#"; const hasLink = service.href && service.href !== "#";
const { settings } = useContext(SettingsContext); const { settings } = useContext(SettingsContext);
const showStats = (service.showStats === false) ? false : settings.showStats; const showStats = service.showStats === false ? false : settings.showStats;
const statusStyle = service.statusStyle !== undefined ? service.statusStyle : settings.statusStyle;
const [statsOpen, setStatsOpen] = useState(service.showStats); const [statsOpen, setStatsOpen] = useState(service.showStats);
const [statsClosing, setStatsClosing] = useState(false); const [statsClosing, setStatsClosing] = useState(false);
@@ -33,9 +34,9 @@ export default function Item({ service, group }) {
<li key={service.name} id={service.id} className="service" data-name={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 service-card" "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 service-title"> <div className="flex select-none z-0 service-title">
@@ -64,22 +65,30 @@ export default function Item({ service, group }) {
> >
<div className="flex-1 px-2 py-2 text-sm text-left z-10 service-name"> <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">{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 service-title-text"> <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 service-name"> <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">{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 flex flex-row justify-end gap-2 mr-2 z-30 service-tags"> <div
className={`absolute top-0 right-0 flex flex-row justify-end ${
statusStyle === "dot" ? "gap-0" : "gap-2 mr-2"
} z-30 service-tags`}
>
{service.ping && ( {service.ping && (
<div className="flex-shrink-0 flex items-center justify-center service-tag service-ping"> <div className="flex-shrink-0 flex items-center justify-center service-tag service-ping">
<Ping group={group} service={service.name} style={service.statusStyle} /> <Ping group={group} service={service.name} style={statusStyle} />
<span className="sr-only">Ping status</span> <span className="sr-only">Ping status</span>
</div> </div>
)} )}
@@ -90,17 +99,17 @@ export default function Item({ service, group }) {
onClick={() => (statsOpen ? closeStats() : setStatsOpen(true))} onClick={() => (statsOpen ? closeStats() : setStatsOpen(true))}
className="flex-shrink-0 flex items-center justify-center cursor-pointer service-tag service-container-stats" className="flex-shrink-0 flex items-center justify-center cursor-pointer service-tag service-container-stats"
> >
<Status service={service} /> <Status service={service} style={statusStyle} />
<span className="sr-only">View container stats</span> <span className="sr-only">View container stats</span>
</button> </button>
)} )}
{(service.app && !service.external) && ( {service.app && !service.external && (
<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 service-tag service-app" className="flex-shrink-0 flex items-center justify-center cursor-pointer service-tag service-app"
> >
<KubernetesStatus service={service} /> <KubernetesStatus service={service} style={statusStyle} />
<span className="sr-only">View container stats</span> <span className="sr-only">View container stats</span>
</button> </button>
)} )}
@@ -111,20 +120,28 @@ 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 service-stats" "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 } }} />
)}
</div> </div>
)} )}
{service.app && ( {service.app && (
<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 service-stats" "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 },
}}
/>
)}
</div> </div>
)} )}

View File

@@ -1,35 +1,48 @@
import useSWR from "swr"; import useSWR from "swr";
import { t } from "i18next"; import { t } from "i18next";
export default function KubernetesStatus({ service }) { export default function KubernetesStatus({ service, style }) {
const podSelectorString = service.podSelector !== undefined ? `podSelector=${service.podSelector}` : ""; const podSelectorString = service.podSelector !== undefined ? `podSelector=${service.podSelector}` : "";
const { data, error } = useSWR(`/api/kubernetes/status/${service.namespace}/${service.app}?${podSelectorString}`); const { data, error } = useSWR(`/api/kubernetes/status/${service.namespace}/${service.app}?${podSelectorString}`);
let statusLabel = t("docker.unknown");
let statusTitle = "";
let backgroundClass = "px-1.5 py-0.5 bg-theme-500/10 dark:bg-theme-900/50";
let colorClass = "text-black/20 dark:text-white/40 opacity-20";
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 k8s-status-error" title={t("docker.error")}> statusTitle = t("docker.error");
<div className="text-[8px] font-bold text-rose-500/80 uppercase">{t("docker.error")}</div> statusLabel = statusTitle;
</div> colorClass = "text-rose-500/80";
} else if (data) {
if (data.status === "running") {
statusTitle = data.health ?? data.status;
statusLabel = statusTitle;
colorClass = "text-emerald-500/80";
} }
if (data && data.status === "running") { if (data.status === "not found" || data.status === "down" || data.status === "partial") {
return ( statusTitle = 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}> statusLabel = statusTitle;
<div className="text-[8px] font-bold text-emerald-500/80 uppercase">{data.health ?? data.status}</div> colorClass = "text-orange-400/50 dark:text-orange-400/80";
</div> }
);
} }
if (data && (data.status === "not found" || data.status === "down" || data.status === "partial")) { if (style === "dot") {
return ( colorClass = colorClass.replace(/text-/g, "bg-").replace(/\/\d\d/g, "");
<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}> backgroundClass = "p-4 hover:bg-theme-500/10 dark:hover:bg-theme-900/20";
<div className="text-[8px] font-bold text-orange-400/50 dark:text-orange-400/80 uppercase">{data.status}</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 k8s-status-unknown"> <div
<div className="text-[8px] font-bold text-black/20 dark:text-white/40 uppercase">{t("docker.unknown")}</div> className={`w-auto text-center overflow-hidden ${backgroundClass} rounded-b-[3px] k8s-status`}
title={statusTitle}
>
{style !== "dot" ? (
<div className={`text-[8px] font-bold ${colorClass} uppercase`}>{statusLabel}</div>
) : (
<div className={`rounded-full h-3 w-3 ${colorClass}`} />
)}
</div> </div>
); );
} }

View File

@@ -9,7 +9,7 @@ export default function List({ group, services, layout }) {
<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 services-list" "mt-3 services-list",
)} )}
> >
{services.map((service) => ( {services.map((service) => (

View File

@@ -4,55 +4,55 @@ import useSWR from "swr";
export default function Ping({ group, service, style }) { export default function Ping({ group, service, style }) {
const { t } = useTranslation(); const { t } = useTranslation();
const { data, error } = useSWR(`/api/ping?${new URLSearchParams({ group, service }).toString()}`, { const { data, error } = useSWR(`/api/ping?${new URLSearchParams({ group, service }).toString()}`, {
refreshInterval: 30000 refreshInterval: 30000,
}); });
let textSize = "text-[8px]"; let colorClass = "text-black/20 dark:text-white/40 opacity-20";
let colorClass = "" let backgroundClass = "bg-theme-500/10 dark:bg-theme-900/50 px-1.5 py-0.5";
let backgroundClass = "bg-theme-500/10 dark:bg-theme-900/50"; let statusTitle = t("ping.http_status");
let statusTitle = "HTTP status"; let statusText = "";
let statusText;
if (error) { if (error) {
colorClass = "text-rose-500" colorClass = "text-rose-500";
statusText = t("ping.error") statusText = t("ping.error");
statusTitle += " error" statusTitle += ` ${t("ping.error")}`;
} else if (!data) { } else if (!data) {
colorClass = "text-black/20 dark:text-white/40" statusText = t("ping.ping");
statusText = t("ping.ping") statusTitle += ` ${t("ping.not_available")}`;
statusTitle += " not available"
} else if (data.status > 403) { } else if (data.status > 403) {
colorClass = "text-rose-500/80" colorClass = "text-rose-500/80";
statusTitle += ` ${data.status}` statusTitle += ` ${data.status}`;
if (style === "basic") { if (style === "basic") {
statusText = t("docker.offline") statusText = t("ping.down");
} else if (style === "dot") {
statusText = "◉"
textSize = "text-[14px]"
backgroundClass = ""
} else { } else {
statusText = data.status statusText = data.status;
} }
} else { } else if (data) {
const ping = t("common.ms", { value: data.latency, style: "unit", unit: "millisecond", maximumFractionDigits: 0 }) const ping = t("common.ms", { value: data.latency, style: "unit", unit: "millisecond", maximumFractionDigits: 0 });
statusTitle += ` ${data.status} (${ping})`; statusTitle += ` ${data.status} (${ping})`;
colorClass = "text-emerald-500/80" colorClass = "text-emerald-500/80";
if (style === "basic") { if (style === "basic") {
statusText = t("docker.running") statusText = t("ping.up");
} else if (style === "dot") {
statusText = "◉"
textSize = "text-[14px]"
backgroundClass = ""
} else { } else {
statusText = ping statusText = ping;
colorClass += " lowercase";
} }
} }
if (style === "dot") {
backgroundClass = "p-4";
colorClass = colorClass.replace(/text-/g, "bg-").replace(/\/\d\d/g, "");
}
return ( return (
<div className={`w-auto px-1.5 py-0.5 text-center rounded-b-[3px] overflow-hidden ping-status-invalid ${backgroundClass}`} title={statusTitle}> <div
<div className={`font-bold uppercase ${textSize} ${colorClass}`}>{statusText}</div> className={`w-auto text-center rounded-b-[3px] overflow-hidden ping-status ${backgroundClass}`}
title={statusTitle}
>
{style !== "dot" && <div className={`font-bold uppercase text-[8px] ${colorClass}`}>{statusText}</div>}
{style === "dot" && <div className={`rounded-full h-3 w-3 ${colorClass}`} />}
</div> </div>
); );
} }

View File

@@ -1,65 +1,65 @@
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import useSWR from "swr"; import useSWR from "swr";
export default function Status({ service }) { export default function Status({ service, style }) {
const { t } = useTranslation(); const { t } = useTranslation();
const { data, error } = useSWR(`/api/docker/status/${service.container}/${service.server || ""}`); const { data, error } = useSWR(`/api/docker/status/${service.container}/${service.server || ""}`);
let statusLabel = t("docker.unknown");
let statusTitle = "";
let backgroundClass = "px-1.5 py-0.5 bg-theme-500/10 dark:bg-theme-900/50";
let colorClass = "text-black/20 dark:text-white/40 ";
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 docker-error" title={t("docker.error")}> statusTitle = t("docker.error");
<div className="text-[8px] font-bold text-rose-500/80 uppercase">{t("docker.error")}</div> colorClass = "text-rose-500/80";
</div> } else if (data) {
}
if (data) {
let statusLabel = "";
if (data.status?.includes("running")) { if (data.status?.includes("running")) {
if (data.health === "starting") { if (data.health === "starting") {
return ( statusTitle = 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")}> colorClass = "text-blue-500/80";
<div className="text-[8px] font-bold text-blue-500/80 uppercase">{t("docker.starting")}</div>
</div>
);
} }
if (data.health === "unhealthy") { if (data.health === "unhealthy") {
return ( statusTitle = 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")}> colorClass = "text-orange-400/50 dark:text-orange-400/80";
<div className="text-[8px] font-bold text-orange-400/50 dark:text-orange-400/80 uppercase">{t("docker.unhealthy")}</div>
</div>
);
} }
if (!data.health) { if (!data.health) {
statusLabel = data.status.replace("running", t("docker.running")) statusLabel = data.status.replace("running", t("docker.running"));
} else { } else {
statusLabel = data.health === "healthy" ? t("docker.healthy") : data.health statusLabel = data.health === "healthy" ? t("docker.healthy") : data.health;
} }
return ( statusTitle = 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}> colorClass = "text-emerald-500/80";
<div className="text-[8px] font-bold text-emerald-500/80 uppercase">{statusLabel}</div>
</div>
);
} }
if (data.status === "not found" || data.status === "exited" || data.status?.startsWith("partial")) { if (data.status === "not found" || data.status === "exited" || data.status?.startsWith("partial")) {
if (data.status === "not found") statusLabel = t("docker.not_found") if (data.status === "not found") statusLabel = t("docker.not_found");
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 ( colorClass = "text-orange-400/50 dark:text-orange-400/80";
<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>
);
} }
} }
if (style === "dot") {
colorClass = colorClass.replace(/text-/g, "bg-").replace(/\/\d\d/g, "");
backgroundClass = "p-4 hover:bg-theme-500/10 dark:hover:bg-theme-900/20";
statusTitle = statusLabel;
}
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 docker-status-unknown"> <div
<div className="text-[8px] font-bold text-black/20 dark:text-white/40 uppercase">{t("docker.unknown")}</div> className={`w-auto text-center overflow-hidden ${backgroundClass} rounded-b-[3px] docker-status`}
title={statusTitle}
>
{style !== "dot" ? (
<div className={`text-[8px] font-bold ${colorClass} uppercase`}>{statusLabel}</div>
) : (
<div className={`rounded-full h-3 w-3 ${colorClass}`} />
)}
</div> </div>
); );
} }

View File

@@ -9,7 +9,7 @@ export default function Block({ value, label }) {
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" "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

@@ -12,14 +12,14 @@ export default function Container({ error = false, children, service }) {
return null; return null;
} }
return <Error service={service} error={error} /> return <Error service={service} error={error} />;
} }
const childrenArray = Array.isArray(children) ? children : [children]; const childrenArray = Array.isArray(children) ? children : [children];
let visibleChildren = childrenArray; let visibleChildren = childrenArray;
let fields = service?.widget?.fields; let fields = service?.widget?.fields;
if (typeof fields === 'string') fields = JSON.parse(service.widget.fields); if (typeof fields === "string") fields = JSON.parse(service.widget.fields);
const type = service?.widget?.type; const type = service?.widget?.type;
if (fields && type) { if (fields && type) {
// if the field contains a "." then it most likely contains a common loc value // if the field contains a "." then it most likely contains a common loc value
@@ -27,13 +27,15 @@ export default function Container({ error = false, children, service }) {
// fields: [ "resources.cpu", "resources.mem", "field"] // fields: [ "resources.cpu", "resources.mem", "field"]
// or even // or even
// fields: [ "resources.cpu", "widget_type.field" ] // fields: [ "resources.cpu", "widget_type.field" ]
visibleChildren = childrenArray?.filter(child => fields.some(field => { visibleChildren = childrenArray?.filter((child) =>
fields.some((field) => {
let fullField = field; let fullField = field;
if (!field.includes(".")) { if (!field.includes(".")) {
fullField = `${type}.${field}`; fullField = `${type}.${field}`;
} }
return fullField === child?.props?.label; return fullField === child?.props?.label;
})); }),
);
} }
return <div className="relative flex flex-row w-full service-container">{visibleChildren}</div>; return <div className="relative flex flex-row w-full service-container">{visibleChildren}</div>;

View File

@@ -6,7 +6,7 @@ function displayError(error) {
} }
function displayData(data) { function displayData(data) {
return (data.type === 'Buffer') ? Buffer.from(data).toString() : JSON.stringify(data, 4); return data.type === "Buffer" ? Buffer.from(data).toString() : JSON.stringify(data, 4);
} }
export default function Error({ error }) { export default function Error({ error }) {
@@ -20,29 +20,34 @@ export default function Error({ error }) {
<details className="px-1 pb-1"> <details className="px-1 pb-1">
<summary className="block text-center mt-1 mb-0 mx-auto p-3 rounded bg-rose-900/80 hover:bg-rose-900/95 text-theme-900 cursor-pointer"> <summary className="block text-center mt-1 mb-0 mx-auto p-3 rounded bg-rose-900/80 hover:bg-rose-900/95 text-theme-900 cursor-pointer">
<div className="flex items-center justify-center text-xs font-bold"> <div className="flex items-center justify-center text-xs font-bold">
<IoAlertCircle className="mr-1 w-5 h-5"/>{t("widget.api_error")} {error.message && t("widget.information")} <IoAlertCircle className="mr-1 w-5 h-5" />
{t("widget.api_error")} {error.message && t("widget.information")}
</div> </div>
</summary> </summary>
<div className="bg-white dark:bg-theme-200/50 mt-2 rounded text-rose-900 text-xs font-mono whitespace-pre-wrap break-all"> <div className="bg-white dark:bg-theme-200/50 mt-2 rounded text-rose-900 text-xs font-mono whitespace-pre-wrap break-all">
<ul className="p-4"> <ul className="p-4">
{error.message && <li> {error.message && (
<li>
<span className="text-black">{t("widget.api_error")}:</span> {error.message} <span className="text-black">{t("widget.api_error")}:</span> {error.message}
</li>} </li>
{error.url && <li className="mt-2"> )}
{error.url && (
<li className="mt-2">
<span className="text-black">{t("widget.url")}:</span> {error.url} <span className="text-black">{t("widget.url")}:</span> {error.url}
</li>} </li>
{error.rawError && <li className="mt-2"> )}
{error.rawError && (
<li className="mt-2">
<span className="text-black">{t("widget.raw_error")}:</span> <span className="text-black">{t("widget.raw_error")}:</span>
<div className="ml-2"> <div className="ml-2">{displayError(error.rawError)}</div>
{displayError(error.rawError)} </li>
</div> )}
</li>} {error.data && (
{error.data && <li className="mt-2"> <li className="mt-2">
<span className="text-black">{t("widget.response_data")}:</span> <span className="text-black">{t("widget.response_data")}:</span>
<div className="ml-2"> <div className="ml-2">{displayData(error.data)}</div>
{displayData(error.data)} </li>
</div> )}
</li>}
</ul> </ul>
</div> </div>
</details> </details>

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