Compare commits

..

107 Commits

Author SHA1 Message Date
shamoon
b019295a06 Update services.md 2023-11-08 22:39:23 -08:00
shamoon
5fa790e9fe Use old mike 2023-11-08 22:26:17 -08:00
shamoon
7719ea17be Fix: handle immich v1.85.0 API stats breaking change (#2284) 2023-11-07 23:59:43 -08:00
shamoon
885a4051f3 Fix: support Unifi widget with Unifi OS v3.2.5+ (#2281) 2023-11-07 14:38:26 -08:00
Ingmar Delsink
67f5ee8df5 Fix: Access container memory_stats.stats safely by optional chaining (#2271) (#2272) 2023-11-05 07:39:26 -08:00
Reiss Cashmore
ebd384c62d Feature: iFrame widget (#2261)
---------

Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
2023-10-31 07:19:57 -07:00
shamoon
5512d05f00 Fix: Respect hideErrors for Calendar widget (#2259) 2023-10-29 20:14:06 -07:00
shamoon
654f16dbb5 Fix: Correct Synology DownloadStation units (#2249) 2023-10-27 14:39:57 -07:00
shamoon
bec1e5fff2 Fix: octoprint error when progress empty (#2247) 2023-10-27 09:29:36 -07:00
shamoon
1da9255578 Fix: authentik users endpoint URL (#2244) 2023-10-26 23:03:52 -07:00
shamoon
cc887214cf Fix: override some colors for white theme (#2242) 2023-10-26 21:59:18 -07:00
shamoon
98c3ca6dac Docs: Update broken links in readme
Closes #2233
2023-10-24 14:09:56 -07:00
Kirill Kuznetsov
3c4818a2b4 Feature: add date formatting option in custom api (#2228) 2023-10-23 16:54:04 -07:00
Avishek Sen
f773e026d5 docs: fix typos (#2222) 2023-10-21 11:42:37 -07:00
shamoon
3f1229555e Fix translation of no events today in calendar
See #2221
2023-10-21 07:48:17 -07:00
Denis Papec
6898faa3de Feature: Added agenda view for calendar, calendar improvements (#2216)
* Feature: Added agenda view for calendar, calendar improvements

* Fix duplicate event keys

* Additional hover on title, not date

* Show date once in list

* Rename monthly view for consistency

* Remove unneeded key props

* CSS cleanup, dont slice title to arbitrary 42 chars which can break column layouts

* Simplify agenda components

* Fix show date once in list

---------

Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>
2023-10-20 16:31:19 -07:00
shamoon
792f768a7f Feature: true ping, rename old ping to siteMonitor (#2215) 2023-10-20 00:09:33 -07:00
shamoon
0c8c759f8a Enable autoSelectFamily for http(s) requests (#2214) 2023-10-19 14:42:15 -07:00
shamoon
241c981444 Fix tab spacing on mobile (#2209) 2023-10-18 13:25:12 -07:00
shamoon
56349e57e5 Update development.md 2023-10-18 12:53:27 -07:00
shamoon
6763da57a6 Update CONTRIBUTING.md 2023-10-18 12:49:27 -07:00
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
457 changed files with 9985 additions and 7669 deletions

View File

@@ -27,5 +27,5 @@ What type of change does your PR introduce to Homepage?
- [ ] If adding a service widget or a change that requires it, I have added corresponding documentation changes. - [ ] 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/latest/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

@@ -20,6 +20,7 @@ on:
paths-ignore: paths-ignore:
- 'docs/**' - 'docs/**'
- 'mkdocs.yml' - 'mkdocs.yml'
merge_group:
env: env:
# Use docker.io for Docker Hub if empty # Use docker.io for Docker Hub if empty
@@ -29,10 +30,28 @@ env:
jobs: jobs:
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: build:
name: Docker Build & Push name: Docker Build & Push
if: github.repository == 'gethomepage/homepage' 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

@@ -11,16 +11,35 @@ on:
paths: paths:
- 'docs/**' - 'docs/**'
- 'mkdocs.yml' - 'mkdocs.yml'
merge_group:
workflow_dispatch: workflow_dispatch:
permissions: permissions:
contents: write contents: write
jobs: jobs:
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: test:
name: Test Build name: Test Build
if: github.repository == 'gethomepage/homepage' && github.event_name == 'pull_request' if: github.repository == 'gethomepage/homepage' && github.event_name == 'pull_request'
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs:
- pre-commit
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: actions/setup-python@v4 - uses: actions/setup-python@v4
@@ -42,6 +61,8 @@ jobs:
name: Build & Deploy name: Build & Deploy
if: github.repository == 'gethomepage/homepage' && github.event_name != 'pull_request' if: github.repository == 'gethomepage/homepage' && github.event_name != 'pull_request'
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs:
- pre-commit
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: with:
@@ -57,7 +78,7 @@ jobs:
restore-keys: | restore-keys: |
mkdocs-material- mkdocs-material-
- run: sudo apt-get install pngquant - run: sudo apt-get install pngquant
- run: pip install mike - run: pip install mike==1.1.2
- run: pip install git+https://${GH_TOKEN}@github.com/benphelps/mkdocs-material-insiders.git - run: pip install git+https://${GH_TOKEN}@github.com/benphelps/mkdocs-material-insiders.git
- name: Set Git config - name: Set Git config
run: | run: |

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/gethomepage/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/gethomepage/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/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. 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/#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

@@ -16,10 +16,12 @@
<p align="center"> <p align="center">
<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> <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>
@@ -43,11 +45,11 @@ Homepage has built-in support for Docker, and can automatically discover and add
## 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/latest/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/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/latest/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/widgets/) page for more information.
## Customization ## Customization
@@ -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
@@ -162,7 +166,7 @@ If you have any questions, suggestions, or general issues, please start a discus
For bug reports, please open an issue on the [Issues](https://github.com/gethomepage/homepage/issues) page. For bug reports, please open an issue on the [Issues](https://github.com/gethomepage/homepage/issues) page.
## Contributing & Contributers ## Contributing & Contributors
Contributions are welcome! Please see the [CONTRIBUTING.md](CONTRIBUTING.md) file for more information. Contributions are welcome! Please see the [CONTRIBUTING.md](CONTRIBUTING.md) file for more information.

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

@@ -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

@@ -5,7 +5,7 @@ description: Service Widget Configuration
Unless otherwise noted, URLs should not end with a `/` or other API path. Each widget will handle the path on its own. Unless otherwise noted, URLs should not end with a `/` or other API path. Each widget will handle the path on its own.
Each service can have one widget attached to it (often matching the service type, but thats not forced). Each service can have one widget attached to it (often matching the service type, but that's not forced).
In addition to the href of the service, you can also specify the target location in which to open that link. See [Link Target](settings.md#link-target) for more details. In addition to the href of the service, you can also specify the target location in which to open that link. See [Link Target](settings.md#link-target) for more details.

View File

@@ -101,30 +101,50 @@ To use a local icon, first create a Docker mount to `/app/public/icons` and then
## Ping ## Ping
Services may have an optional `ping` property that allows you to monitor the availability of an endpoint you chose and have the response time displayed. You do not need to set your ping URL equal to your href URL. Services may have an optional `ping` property that allows you to monitor the availability of an external host. As of v0.8.0, the ping feature attempts to use a true (ICMP) ping command on the underlying host.
!!! note
The ping feature works by making an http `HEAD` request to the URL, and falls back to `GET` in case that fails. It will not, for example, login if the URL requires auth or is behind e.g. Authelia. In the case of a reverse proxy and/or auth this usually requires the use of an 'internal' URL to make the ping feature correctly display status.
```yaml ```yaml
- Group A: - Group A:
- Sonarr: - Sonarr:
icon: sonarr.png icon: sonarr.png
href: http://sonarr.host/ href: http://sonarr.host/
ping: http://sonarr.host/ ping: sonarr.host
- Group B: - Group B:
- Radarr: - Radarr:
icon: radarr.png icon: radarr.png
href: http://radarr.host/ href: http://radarr.host/
ping: http://some.other.host/ ping: some.other.host
``` ```
<img width="1038" alt="Ping" src="https://github.com/gethomepage/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, see [settings](settings.md#status-style). You can also apply different styles to the ping indicator by using the `statusStyle` property, see [settings](settings.md#status-style).
## Site Monitor
Services may have an optional `siteMonitor` property (formerly `ping`) that allows you to monitor the availability of a URL you chose and have the response time displayed. You do not need to set your monitor URL equal to your href or ping URL.
!!! note
The site monitor feature works by making an http `HEAD` request to the URL, and falls back to `GET` in case that fails. It will not, for example, login if the URL requires auth or is behind e.g. Authelia. In the case of a reverse proxy and/or auth this usually requires the use of an 'internal' URL to make the site monitor feature correctly display status.
```yaml
- Group A:
- Sonarr:
icon: sonarr.png
href: http://sonarr.host/
siteMonitor: http://sonarr.host/
- Group B:
- Radarr:
icon: radarr.png
href: http://radarr.host/
siteMonitor: http://some.other.host/
```
You can also apply different styles to the site monitor indicator by using the `statusStyle` property, see [settings](settings.md#status-style).
## Docker Integration ## Docker Integration
Services may be connected to a Docker container, either running on the local machine, or a remote machine. Services may be connected to a Docker container, either running on the local machine, or a remote machine.

View File

@@ -67,7 +67,7 @@ background:
### Card Background Blur ### Card Background Blur
You can apply a blur filter to the service & bookmark cards. Note this option is incompatible with the backround blur, saturate and brightness filters. You can apply a blur filter to the service & bookmark cards. Note this option is incompatible with the background blur, saturate and brightness filters.
```yaml ```yaml
cardBlur: sm # sm, "", md, etc... see https://tailwindcss.com/docs/backdrop-blur cardBlur: sm # sm, "", md, etc... see https://tailwindcss.com/docs/backdrop-blur
@@ -329,7 +329,7 @@ You can then pass `provider` instead of `apiKey` in your widget configuration.
## Quick Launch ## Quick Launch
You can use the 'Quick Launch' feature to search services, perform a web search or open a URL. To use Quick Launch, just start typing while on your homepage (as long as the search widget doesnt have focus). You can use the 'Quick Launch' feature to search services, perform a web search or open a URL. To use Quick Launch, just start typing while on your homepage (as long as the search widget doesn't have focus).
<img width="1000" alt="quicklaunch" src="https://user-images.githubusercontent.com/4887959/216880811-90ff72cb-2990-4475-889b-7c3a31e6beef.png"> <img width="1000" alt="quicklaunch" src="https://user-images.githubusercontent.com/4887959/216880811-90ff72cb-2990-4475-889b-7c3a31e6beef.png">
@@ -382,16 +382,16 @@ If you have both set the per-service settings take precedence.
## Status Style ## Status Style
You can choose from the following styles for docker or k8s status and ping: `dot` or `basic` You can choose from the following styles for docker or k8s status, site monitor and ping: `dot` or `basic`
- The default is no value, and displays the ping response time in ms and the docker / k8s container status - The default is no value, and displays the montior and ping response time in ms and the docker / k8s container status
- `dot` shows a green dot for a successful ping or healthy status. - `dot` shows a green dot for a successful monitor ping or healthy status.
- `basic` shows either UP or DOWN for ping - `basic` shows either UP or DOWN for monitor & ping
For example: For example:
```yaml ```yaml
statusStyle: 'dot' statusStyle: "dot"
``` ```
or per-service (`services.yaml`) with: or per-service (`services.yaml`) with:
@@ -422,4 +422,4 @@ or per service widget (`services.yaml`) with:
hideErrors: true hideErrors: true
``` ```
If either value is set to true, the errror message will be hidden. If either value is set to true, the error message will be hidden.

View File

@@ -298,10 +298,32 @@ spec:
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

@@ -31,6 +31,14 @@ 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.
Once installed, hooks will run when you commit. If the formatting isn't quite right, the commit will be rejected and you'll need to look at the output and fix the issue. Most hooks will automatically format failing files, so all you need to do is `git add` those files again and retry your commit.
See the [pre-commit documentation](https://pre-commit.com/#install) to get started.
## 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

@@ -3,6 +3,6 @@ title: Homepage Move
description: Homepage Container Deprecation description: Homepage Container Deprecation
--- ---
As of v0.7.1 homepage migrated from benphelps/homepage to an "orgnization" located at gethomepage/homepage. The reason for this is to setup the project for longevity and allow for community maintenance. 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`. 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

@@ -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

@@ -3,7 +3,7 @@ title: OpenWeatherMap
description: OpenWeatherMap Information Widget Configuration description: OpenWeatherMap Information Widget Configuration
--- ---
The free tier "One Call API" is all thats required, you will need to [subscribe](https://home.openweathermap.org/subscriptions/unauth_subscribe/onecall_30/base) and grab your API key. The free tier "One Call API" is all that's required, you will need to [subscribe](https://home.openweathermap.org/subscriptions/unauth_subscribe/onecall_30/base) and grab your API key.
```yaml ```yaml
- openweathermap: - openweathermap:

View File

@@ -9,7 +9,7 @@ The disk path is the path reported by `df` (Mounted On), or the mount point of t
The cpu and memory resource information are the container's usage while [glances](glances.md) displays statistics for the host machine on which it is installed. The cpu and memory resource information are the container's usage while [glances](glances.md) displays statistics for the host machine on which it is installed.
_Note: unfortunately, the package used for getting CPU temp ([systeminformation](https://systeminformation.io)) is not compatibile with some setups and will not report any value(s) for CPU temp._ _Note: unfortunately, the package used for getting CPU temp ([systeminformation](https://systeminformation.io)) is not compatible with some setups and will not report any value(s) for CPU temp._
**Any disk you wish to access must be mounted to your container as a volume.** **Any disk you wish to access must be mounted to your container as a volume.**

View File

@@ -5,7 +5,7 @@ description: Weather API Information Widget Configuration
**Note: this widget is considered 'deprecated' since there is no longer a free Weather API tier for new members. See the openmeteo or openweathermap widgets for alternatives.** **Note: this widget is considered 'deprecated' since there is no longer a free Weather API tier for new members. See the openmeteo or openweathermap widgets for alternatives.**
The free tier is all thats required, you will need to [register](https://www.weatherapi.com/signup.aspx) and grab your API key. The free tier is all that's required, you will need to [register](https://www.weatherapi.com/signup.aspx) and grab your API key.
```yaml ```yaml
- weatherapi: - weatherapi:

View File

@@ -8,7 +8,7 @@ This widget has 2 functions:
1. Pipelines: checks if the relevant pipeline is running or not, and if not, reports the last status.\ 1. Pipelines: checks if the relevant pipeline is running or not, and if not, reports the last status.\
Allowed fields: `["result", "status"]`. Allowed fields: `["result", "status"]`.
2. Pull Requests: returns the amount of open PRs, the amount of the PRs you have open, and how many PRs that you open are marked as 'Approved' by atleast 1 person and not yet completed.\ 2. Pull Requests: returns the amount of open PRs, the amount of the PRs you have open, and how many PRs that you open are marked as 'Approved' by at least 1 person and not yet completed.\
Allowed fields: `["totalPrs", "myPrs", "approved"]`. Allowed fields: `["totalPrs", "myPrs", "approved"]`.
You will need to generate a personal access token for an existing user, see the [azure documentation](https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=Windows#create-a-pat) You will need to generate a personal access token for an existing user, see the [azure documentation](https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=Windows#create-a-pat)

View File

@@ -3,6 +3,8 @@ title: Calendar
description: Calendar widget description: Calendar widget
--- ---
## Monthly view
<img alt="calendar" src="https://user-images.githubusercontent.com/5442891/271131282-6767a3ea-573e-4005-aeb9-6e14ee01e845.png"> <img alt="calendar" src="https://user-images.githubusercontent.com/5442891/271131282-6767a3ea-573e-4005-aeb9-6e14ee01e845.png">
This widget shows monthly calendar, with optional integrations to show events from supported widgets. This widget shows monthly calendar, with optional integrations to show events from supported widgets.
@@ -11,6 +13,8 @@ This widget shows monthly calendar, with optional integrations to show events fr
widget: widget:
type: calendar type: calendar
firstDayInWeek: sunday # optional - defaults to monday firstDayInWeek: sunday # optional - defaults to monday
view: monthly # optional - possible values monthly, agenda
maxEvents: 10 # optional - defaults to 10
integrations: # optional integrations: # optional
- type: sonarr # active widget type that is currently enabled on homepage - possible values: radarr, sonarr, lidarr, readarr - type: sonarr # active widget type that is currently enabled on homepage - possible values: radarr, sonarr, lidarr, readarr
service_group: Media # group name where widget exists service_group: Media # group name where widget exists
@@ -20,6 +24,20 @@ widget:
unmonitored: true # optional - defaults to false, used with *arr stack unmonitored: true # optional - defaults to false, used with *arr stack
``` ```
## Agenda
This view shows only list of events from configured integrations
```yaml
widget:
type: calendar
view: agenda
maxEvents: 10 # optional - defaults to 10
integrations: # same as in Monthly view example
```
## Integrations
Currently integrated widgets are [sonarr](sonarr.md), [radarr](radarr.md), [lidarr](lidarr.md) and [readarr](readarr.md). Currently integrated widgets are [sonarr](sonarr.md), [radarr](radarr.md), [lidarr](lidarr.md) and [readarr](readarr.md).
Supported colors can be found on [color palette](../../configs/settings.md#color-palette). Supported colors can be found on [color palette](../../configs/settings.md#color-palette).

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

@@ -31,9 +31,13 @@ widget:
another: key3 another: key3
label: Field 3 label: Field 3
format: percent # optional - defaults to text format: percent # optional - defaults to text
- field: key # needs to be YAML string or object
label: Field 4
format: date # optional - defaults to text
dateStyle: long # optional - defaults to "long". Allowed values: `["full", "long", "medium", "short"]`.
``` ```
Supported formats for the values are `text`, `number`, `float`, `percent`, `bytes` and `bitrate`. Supported formats for the values are `text`, `number`, `float`, `percent`, `bytes`, `bitrate` and `date`.
## Example ## Example
@@ -60,7 +64,7 @@ For the following JSON object from the API:
} }
``` ```
Define the `mappings` section as an aray, for example: Define the `mappings` section as an array, for example:
```yaml ```yaml
mappings: mappings:

View File

@@ -3,7 +3,7 @@ title: Glances
description: Glances Widget Configuration description: Glances Widget Configuration
--- ---
<img width="1614" alt="glances" src="https://github.com/gethomepage/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](../info/glances.md))_ _(Find the Glances information widget [here](../info/glances.md))_
@@ -18,7 +18,7 @@ widget:
metric: cpu metric: cpu
``` ```
_Please note, this widget does not need an `href`, `icon` or `description` on its parent service. To achive the same effect as the examples above, see as an example:_ _Please note, this widget does not need an `href`, `icon` or `description` on its parent service. To achieve the same effect as the examples above, see as an example:_
```yaml ```yaml
- CPU Usage: - CPU Usage:
@@ -45,23 +45,23 @@ The metric field in the configuration determines the type of system monitoring d
`process`: Top 5 processes based on CPU usage. Gives an overview of which processes are consuming the most resources. `process`: Top 5 processes based on CPU usage. Gives an overview of which processes are consuming the most resources.
`network:<interface_name>`: Network data usage for the specified interface. Replace `<interface_name>` with the name of your network interface, e.g., `network:enp0s25`, as specificed in glances. `network:<interface_name>`: Network data usage for the specified interface. Replace `<interface_name>` with the name of your network interface, e.g., `network:enp0s25`, as specified in glances.
`sensor:<sensor_id>`: Temperature of the specified sensor, typically used to monitor CPU temperature. Replace `<sensor_id>` with the name of your sensor, e.g., `sensor:Package id 0` as specificed in glances. `sensor:<sensor_id>`: Temperature of the specified sensor, typically used to monitor CPU temperature. Replace `<sensor_id>` with the name of your sensor, e.g., `sensor:Package id 0` as specified in glances.
`disk:<disk_id>`: Disk I/O data for the specified disk. Replace `<disk_id>` with the id of your disk, e.g., `disk:sdb`, as specificed in glances. `disk:<disk_id>`: Disk I/O data for the specified disk. Replace `<disk_id>` with the id of your disk, e.g., `disk:sdb`, as specified in glances.
`gpu:<gpu_id>`: GPU usage for the specified GPU. Replace `<gpu_id>` with the id of your GPU, e.g., `gpu:0`, as specificed in glances. `gpu:<gpu_id>`: GPU usage for the specified GPU. Replace `<gpu_id>` with the id of your GPU, e.g., `gpu:0`, as specified in glances.
`fs:<mnt_point>`: Disk usage for the specified mount point. Replace `<mnt_point>` with the path of your disk, e.g., `/mnt/storage`, as specificed in glances. `fs:<mnt_point>`: Disk usage for the specified mount point. Replace `<mnt_point>` with the path of your disk, e.g., `/mnt/storage`, as specified in glances.
## Views ## Views
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/gethomepage/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 pass `chart: false` as an option to the widget, like so:
```yaml ```yaml
- Network Usage: - Network Usage:

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

@@ -0,0 +1,35 @@
---
title: iFrame
Description: Add a custom iFrame Widget
---
A basic iFrame widget to show external content, see the [MDN docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe) for more details about some of the options.
!!! warning
Requests made via the iFrame widget are inherently **not proxied** as they are made from the browser itself.
## Basic Example
```yaml
widget:
type: iframe
name: myIframe
src: http://example.com
```
## Full Example
```yaml
widget:
type: iframe
name: myIframe
src: http://example.com
classes: h-60 sm:h-60 md:h-60 lg:h-60 xl:h-60 2xl:h-72 # optional, use tailwind height classes, see https://tailwindcss.com/docs/height
referrerPolicy: same-origin # optional, no default
allowPolicy: autoplay fullscreen gamepad # optional, no default
allowFullscreen: false # optional, default: true
loadingStrategy: eager # optional, default: eager
allowScrolling: no # optional, default: yes
refreshInterval: 2000 # optional, no default
```

View File

@@ -14,4 +14,4 @@ widget:
key: yourpiholeapikey # optional key: yourpiholeapikey # optional
``` ```
_Added in v0.1.0, udpated in v0.6.18_ _Added in v0.1.0, updated in v0.6.18_

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

@@ -59,9 +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/iframe.md
- widgets/services/immich.md - widgets/services/immich.md
- widgets/services/jackett.md - widgets/services/jackett.md
- widgets/services/jdownloader.md - widgets/services/jdownloader.md
@@ -149,6 +151,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

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,17 @@ 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),
);
i18next.services.formatter.add("date", (value, lng, options) =>
new Intl.DateTimeFormat(lng, { ...options }).format(new Date(value)),
); );
}, },
type: "3rdParty", type: "3rdParty",

35
package-lock.json generated
View File

@@ -23,6 +23,7 @@
"minecraft-ping-js": "^1.0.2", "minecraft-ping-js": "^1.0.2",
"next": "^12.3.1", "next": "^12.3.1",
"next-i18next": "^12.0.1", "next-i18next": "^12.0.1",
"ping": "^0.4.4",
"pretty-bytes": "^6.0.0", "pretty-bytes": "^6.0.0",
"raw-body": "^2.5.1", "raw-body": "^2.5.1",
"react": "^18.2.0", "react": "^18.2.0",
@@ -30,7 +31,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 +44,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 +2264,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"
@@ -4862,6 +4862,14 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/ping": {
"version": "0.4.4",
"resolved": "https://registry.npmjs.org/ping/-/ping-0.4.4.tgz",
"integrity": "sha512-56ZMC0j7SCsMMLdOoUg12VZCfj/+ZO+yfOSjaNCRrmZZr6GLbN2X/Ui56T15dI8NhiHckaw5X2pvyfAomanwqQ==",
"engines": {
"node": ">=4.0.0"
}
},
"node_modules/pirates": { "node_modules/pirates": {
"version": "4.0.5", "version": "4.0.5",
"resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz",
@@ -5008,15 +5016,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 +5636,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

@@ -25,6 +25,7 @@
"minecraft-ping-js": "^1.0.2", "minecraft-ping-js": "^1.0.2",
"next": "^12.3.1", "next": "^12.3.1",
"next-i18next": "^12.0.1", "next-i18next": "^12.0.1",
"ping": "^0.4.4",
"pretty-bytes": "^6.0.0", "pretty-bytes": "^6.0.0",
"raw-body": "^2.5.1", "raw-body": "^2.5.1",
"react": "^18.2.0", "react": "^18.2.0",
@@ -32,7 +33,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 +46,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"

42
pnpm-lock.yaml generated
View File

@@ -50,6 +50,9 @@ dependencies:
next-i18next: next-i18next:
specifier: ^12.0.1 specifier: ^12.0.1
version: 12.1.0(next@12.3.4)(react-dom@18.2.0)(react@18.2.0) version: 12.1.0(next@12.3.4)(react-dom@18.2.0)(react@18.2.0)
ping:
specifier: ^0.4.4
version: 0.4.4
pretty-bytes: pretty-bytes:
specifier: ^6.0.0 specifier: ^6.0.0
version: 6.1.0 version: 6.1.0
@@ -71,9 +74,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 +115,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 +125,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 +136,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 +1503,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 +1628,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 +1640,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
@@ -3106,6 +3106,11 @@ packages:
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
dev: true dev: true
/ping@0.4.4:
resolution: {integrity: sha512-56ZMC0j7SCsMMLdOoUg12VZCfj/+ZO+yfOSjaNCRrmZZr6GLbN2X/Ui56T15dI8NhiHckaw5X2pvyfAomanwqQ==}
engines: {node: '>=4.0.0'}
dev: false
/pirates@4.0.5: /pirates@4.0.5:
resolution: {integrity: sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==} resolution: {integrity: sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==}
engines: {node: '>= 6'} engines: {node: '>= 6'}
@@ -3206,9 +3211,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 +3620,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

@@ -10,7 +10,8 @@
"bibitrate": "{{value, rate(bits: true; binary: true)}}", "bibitrate": "{{value, rate(bits: true; binary: true)}}",
"percent": "{{value, percent}}", "percent": "{{value, percent}}",
"number": "{{value, number}}", "number": "{{value, number}}",
"ms": "{{value, number}}" "ms": "{{value, number}}",
"date": "{{value, date}}"
}, },
"widget": { "widget": {
"missing_type": "Missing Widget Type: {{type}}", "missing_type": "Missing Widget Type: {{type}}",
@@ -82,7 +83,16 @@
"error": "Error", "error": "Error",
"ping": "Ping", "ping": "Ping",
"down": "Down", "down": "Down",
"up": "Up" "up": "Up",
"not_available": "Not Available"
},
"siteMonitor": {
"http_status": "HTTP status",
"error": "Error",
"response": "Response",
"down": "Down",
"up": "Up",
"not_available": "Not Available"
}, },
"emby": { "emby": {
"playing": "Playing", "playing": "Playing",
@@ -754,6 +764,7 @@
"calendar": { "calendar": {
"inCinemas": "In cinemas", "inCinemas": "In cinemas",
"physicalRelease": "Physical release", "physicalRelease": "Physical release",
"digitalRelease": "Digital release" "digitalRelease": "Digital release",
"noEventsToday": "No events for today!"
} }
} }

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",
@@ -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": "Lanzamiento en físico",
"inCinemas": "En cine", "inCinemas": "En cine",
"physicalRelease": "Lanzamiento en físico",
"digitalRelease": "Lanzamiento en digital" "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": "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": "Release physique",
"inCinemas": "En salle", "inCinemas": "En salle",
"digitalRelease": "Release digitale" "physicalRelease": "Sortie physique",
"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

@@ -4,6 +4,7 @@ import { useContext, useState } from "react";
import Status from "./status"; import Status from "./status";
import Widget from "./widget"; import Widget from "./widget";
import Ping from "./ping"; import Ping from "./ping";
import SiteMonitor from "./site-monitor";
import KubernetesStatus from "./kubernetes-status"; import KubernetesStatus from "./kubernetes-status";
import Docker from "widgets/docker/component"; import Docker from "widgets/docker/component";
@@ -14,8 +15,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 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);
@@ -34,9 +35,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">
@@ -65,19 +66,27 @@ 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 ${statusStyle === 'dot' ? 'gap-0' : '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={statusStyle} /> <Ping group={group} service={service.name} style={statusStyle} />
@@ -85,6 +94,13 @@ export default function Item({ service, group }) {
</div> </div>
)} )}
{service.siteMonitor && (
<div className="flex-shrink-0 flex items-center justify-center service-tag service-site-monitor">
<SiteMonitor group={group} service={service.name} style={statusStyle} />
<span className="sr-only">Site monitor status</span>
</div>
)}
{service.container && ( {service.container && (
<button <button
type="button" type="button"
@@ -95,7 +111,7 @@ export default function Item({ service, group }) {
<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))}
@@ -112,20 +128,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

@@ -8,7 +8,7 @@ export default function KubernetesStatus({ service, style }) {
let statusLabel = t("docker.unknown"); let statusLabel = t("docker.unknown");
let statusTitle = ""; let statusTitle = "";
let backgroundClass = "px-1.5 py-0.5 bg-theme-500/10 dark:bg-theme-900/50"; 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 "; let colorClass = "text-black/20 dark:text-white/40 opacity-20";
if (error) { if (error) {
statusTitle = t("docker.error"); statusTitle = t("docker.error");
@@ -28,15 +28,21 @@ export default function KubernetesStatus({ service, style }) {
} }
} }
if (style === 'dot') { if (style === "dot") {
colorClass = colorClass.replace('text-', 'bg-').replace(/\/\d\d$/, ''); colorClass = colorClass.replace(/text-/g, "bg-").replace(/\/\d\d/g, "");
backgroundClass = "p-3 hover:bg-theme-500/10 dark:hover:bg-theme-900/20"; backgroundClass = "p-4 hover:bg-theme-500/10 dark:hover:bg-theme-900/20";
} }
return ( return (
<div className={`w-auto text-center overflow-hidden ${backgroundClass} rounded-b-[3px] k8s-status`} title={statusTitle}> <div
{style !== 'dot' && <div className={`text-[8px] font-bold ${colorClass} uppercase`}>{statusLabel}</div>} className={`w-auto text-center overflow-hidden ${backgroundClass} rounded-b-[3px] k8s-status`}
{style === 'dot' && <div className={`rounded-full h-3 w-3 ${colorClass}`}/>} 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,53 +4,50 @@ 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 colorClass = "" let colorClass = "text-black/20 dark:text-white/40 opacity-20";
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 px-1.5 py-0.5";
let statusTitle = "HTTP status"; let statusTitle = t("ping.ping");
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.alive) {
} else if (data.status > 403) { colorClass = "text-rose-500/80";
colorClass = "text-rose-500/80" statusTitle += ` ${t("ping.down")}`;
statusTitle += ` ${data.status}` statusText = t("ping.down");
} else if (data.alive) {
const ping = t("common.ms", { value: data.time, style: "unit", unit: "millisecond", maximumFractionDigits: 0 });
statusTitle += ` ${t("ping.up")} (${ping})`;
colorClass = "text-emerald-500/80";
if (style === "basic") { if (style === "basic") {
statusText = t("ping.down") statusText = t("ping.up");
} else { } else {
statusText = data.status statusText = ping;
} colorClass += " lowercase";
} else {
const ping = t("common.ms", { value: data.latency, style: "unit", unit: "millisecond", maximumFractionDigits: 0 })
statusTitle += ` ${data.status} (${ping})`;
colorClass = "text-emerald-500/80"
if (style === "basic") {
statusText = t("ping.up")
} else {
statusText = ping
colorClass += " lowercase"
} }
} }
if (style === "dot") { if (style === "dot") {
backgroundClass = 'p-3'; backgroundClass = "p-4";
colorClass = colorClass.replace('text-', 'bg-').replace(/\/\d\d$/, ''); colorClass = colorClass.replace(/text-/g, "bg-").replace(/\/\d\d/g, "");
} }
return ( return (
<div className={`w-auto text-center rounded-b-[3px] overflow-hidden ping-status ${backgroundClass}`} title={statusTitle}> <div
{style !== 'dot' && <div className={`font-bold uppercase text-[8px] ${colorClass}`}>{statusText}</div>} className={`w-auto text-center rounded-b-[3px] overflow-hidden ping-status ${backgroundClass}`}
{style === 'dot' && <div className={`rounded-full h-3 w-3 ${colorClass}`}/>} 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

@@ -0,0 +1,63 @@
import { useTranslation } from "react-i18next";
import useSWR from "swr";
export default function SiteMonitor({ group, service, style }) {
const { t } = useTranslation();
const { data, error } = useSWR(`/api/siteMonitor?${new URLSearchParams({ group, service }).toString()}`, {
refreshInterval: 30000,
});
let colorClass = "text-black/20 dark:text-white/40 opacity-20";
let backgroundClass = "bg-theme-500/10 dark:bg-theme-900/50 px-1.5 py-0.5";
let statusTitle = t("siteMonitor.http_status");
let statusText = "";
if (error) {
colorClass = "text-rose-500";
statusText = t("siteMonitor.error");
statusTitle += ` ${t("siteMonitor.error")}`;
} else if (!data) {
statusText = t("siteMonitor.response");
statusTitle += ` ${t("siteMonitor.not_available")}`;
} else if (data.status > 403) {
colorClass = "text-rose-500/80";
statusTitle += ` ${data.status}`;
if (style === "basic") {
statusText = t("siteMonitor.down");
} else {
statusText = data.status;
}
} else if (data) {
const responseTime = t("common.ms", {
value: data.latency,
style: "unit",
unit: "millisecond",
maximumFractionDigits: 0,
});
statusTitle += ` ${data.status} (${responseTime})`;
colorClass = "text-emerald-500/80";
if (style === "basic") {
statusText = t("siteMonitor.up");
} else {
statusText = responseTime;
colorClass += " lowercase";
}
}
if (style === "dot") {
backgroundClass = "p-4";
colorClass = colorClass.replace(/text-/g, "bg-").replace(/\/\d\d/g, "");
}
return (
<div
className={`w-auto text-center rounded-b-[3px] overflow-hidden site-monitor-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>
);
}

View File

@@ -37,22 +37,29 @@ export default function Status({ service, style }) {
} }
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"));
colorClass = "text-orange-400/50 dark:text-orange-400/80"; colorClass = "text-orange-400/50 dark:text-orange-400/80";
} }
} }
if (style === 'dot') { if (style === "dot") {
colorClass = colorClass.replace('text-', 'bg-').replace(/\/\d\d$/, ''); colorClass = colorClass.replace(/text-/g, "bg-").replace(/\/\d\d/g, "");
backgroundClass = "p-3 hover:bg-theme-500/10 dark:hover:bg-theme-900/20"; backgroundClass = "p-4 hover:bg-theme-500/10 dark:hover:bg-theme-900/20";
statusTitle = statusLabel;
} }
return ( return (
<div className={`w-auto text-center overflow-hidden ${backgroundClass} rounded-b-[3px] docker-status`} title={statusTitle}> <div
{style !== 'dot' && <div className={`text-[8px] font-bold ${colorClass} uppercase`}>{statusLabel}</div>} className={`w-auto text-center overflow-hidden ${backgroundClass} rounded-b-[3px] docker-status`}
{style === 'dot' && <div className={`rounded-full h-3 w-3 ${colorClass}`}/>} 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>

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