mirror of
https://github.com/Lissy93/dashy.git
synced 2025-12-06 08:34:14 +01:00
Merge branch 'master' into master
This commit is contained in:
commit
34729784c4
48 changed files with 2878 additions and 2568 deletions
27
.github/workflows/add-comment-from-tag.yml
vendored
27
.github/workflows/add-comment-from-tag.yml
vendored
|
|
@ -1,27 +0,0 @@
|
|||
# Based on a label applied to an issue, the bot will add a comment with some additional info
|
||||
name: 🎯 Auto-Reply to Labeled Tickets
|
||||
on:
|
||||
issues:
|
||||
types:
|
||||
- labeled
|
||||
- unlabeled
|
||||
pull_request_target:
|
||||
types:
|
||||
- labeled
|
||||
- unlabeled
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
comment:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Label Commenter
|
||||
uses: peaceiris/actions-label-commenter@v1
|
||||
with:
|
||||
config_file: .github/issue-auto-comments.yml
|
||||
github_token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
21
.github/workflows/close-incomplete-issues.yml
vendored
21
.github/workflows/close-incomplete-issues.yml
vendored
|
|
@ -1,21 +0,0 @@
|
|||
# Close any issue that does not match any of the issue templates
|
||||
name: 🎯 Close Incomplete Issues
|
||||
on:
|
||||
issues:
|
||||
types: [opened, edited]
|
||||
jobs:
|
||||
auto_close_issues:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v1
|
||||
- name: Automatically close issues that don't follow the issue template
|
||||
uses: lucasbento/auto-close-issues@v1.0.2
|
||||
with:
|
||||
github-token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
closed-issues-label: '🙁 Auto-Closed'
|
||||
issue-close-message: |
|
||||
Hello @${issue.user.login} 👋
|
||||
Unfortunately your issue does not follow the format outlined in the template, and has therefore been auto-closed.
|
||||
To ensure that all relevant info is included, please either update or recreate your issue, and complete the sub-headings provided.
|
||||
Thank you :)
|
||||
68
.github/workflows/generate-credits.yml
vendored
68
.github/workflows/generate-credits.yml
vendored
|
|
@ -1,68 +0,0 @@
|
|||
# Inserts list of contributors and community members into ./docs/credits.md
|
||||
# Also generates an SVG showing all contributors, which is embedded into readme
|
||||
name: 📊 Generate Contributor Credits
|
||||
on:
|
||||
workflow_dispatch: # Manual dispatch
|
||||
schedule:
|
||||
- cron: '0 1 * * 0' # At 01:00 on Sunday.
|
||||
jobs:
|
||||
# Job #1 - Generate an embedded SVG asset, showing all contributors
|
||||
generate-contributors:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: bubkoo/contributors-list@v1
|
||||
with:
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
svgPath: docs/assets/CONTRIBUTORS.svg
|
||||
affiliation: all
|
||||
includeBots: false
|
||||
excludeUsers: BeginCI snyk-bot
|
||||
avatarSize: 96
|
||||
userNameHeight: 20
|
||||
svgWidth: 830
|
||||
commitMessage: ':blue_heart: Updates contributor SVG'
|
||||
# Job #2 - Fetches sponsors and inserts into readme and credits page
|
||||
insert-sponsors:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout 🛎️
|
||||
uses: actions/checkout@v2
|
||||
- name: Generate Sponsors in Readme 💖
|
||||
uses: JamesIves/github-sponsors-readme-action@1.0.5
|
||||
with:
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
file: 'README.md'
|
||||
- name: Generate Sponsors in Credits 💖
|
||||
uses: JamesIves/github-sponsors-readme-action@1.0.5
|
||||
with:
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
file: 'docs/credits.md'
|
||||
# Job #3 - Update the Credits page
|
||||
insert-credits:
|
||||
runs-on: ubuntu-latest
|
||||
name: Inserts contributors into credits.md
|
||||
steps:
|
||||
- name: Contributer List - Credits Page
|
||||
uses: akhilmhdh/contributors-readme-action@v2.3.6
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
image_size: 80
|
||||
readme_path: docs/credits.md
|
||||
columns_per_row: 6
|
||||
commit_message: ':purple_heart: Updates contributors list'
|
||||
collaborators: all
|
||||
committer_username: liss-bot
|
||||
committer_email: liss-bot@d0h.co
|
||||
- name: Sponsors List - Readme
|
||||
uses: akhilmhdh/contributors-readme-action@v2.2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
image_size: 80
|
||||
readme_path: README.md
|
||||
columns_per_row: 6
|
||||
commit_message: ':yellow_heart: Updates sponsors table'
|
||||
committer_username: liss-bot
|
||||
committer_email: liss-bot@d0h.co
|
||||
|
||||
17
.github/workflows/release-commenter.yml
vendored
17
.github/workflows/release-commenter.yml
vendored
|
|
@ -1,17 +0,0 @@
|
|||
# Adds a comment to all issues & PRs that were fixed on a new release
|
||||
name: 💡 Update Issue after Release
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: apexskier/github-release-commenter@v1
|
||||
with:
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }}
|
||||
label-template: 🛩️ Released {release_tag}
|
||||
comment-template: |
|
||||
**This has now been released in {release_name} ✨**
|
||||
|
||||
If you haven't done so already, please [update your instance](https://github.com/Lissy93/dashy/blob/master/docs/management.md#updating) to `{release_tag}` or later. See {release_link} for full info.
|
||||
169
README.md
169
README.md
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
- **Getting Started**
|
||||
- [🌈 Features](#features-)
|
||||
- [⚡Demo](#demo-)
|
||||
- [⚡ Demo](#demo-)
|
||||
- [🚀 Getting Started](#getting-started-)
|
||||
- [🔧 Configuring](#configuring-)
|
||||
- **Feature Overview**
|
||||
|
|
@ -198,7 +198,7 @@ Both sections and items can have an icon associated with them, defined under the
|
|||
|
||||
The following icon types are supported:
|
||||
- **Favicon** - Automatically fetch an apps icon from its Favicon or logo image
|
||||
- **Icon Packs** - Use any icon from [font-awesome], [simple-icons] or [material icons]
|
||||
- **Icon Packs** - Use any icon from [font-awesome], [simple-icons], [selfh.st/icons], or [material icons]
|
||||
- **Emoji** - Any valid emoji can be used as an icon
|
||||
- **Generative** - Unique, auto-generated images for easily identifying services
|
||||
- **URL** - Pass the URL of any valid image in to have it fetched and rendered
|
||||
|
|
@ -209,6 +209,7 @@ The following icon types are supported:
|
|||
[font-awesome]: https://fontawesome.com/icons
|
||||
[simple-icons]: https://simpleicons.org/
|
||||
[material icons]: https://github.com/Templarian/MaterialDesign
|
||||
[selfh.st/icons]: https://selfh.st/icons
|
||||
[dashboard-icons]: https://github.com/WalkxCode/dashboard-icons
|
||||
|
||||
|
||||
|
|
@ -241,7 +242,7 @@ Status indicators can be globally enabled by setting `appConfig.statusCheck: tru
|
|||
|
||||
> For full widget documentation, see: [**Widgets**](./docs/widgets.md)
|
||||
|
||||
You can display dynamic content from services in the form of widgets. There are several pre-built widgets availible for showing useful info, and integrations with commonly self-hosted services, but you can also easily create your own for almost any app.
|
||||
You can display dynamic content from services in the form of widgets. There are several pre-built widgets available for showing useful info, and integrations with commonly self-hosted services, but you can also easily create your own for almost any app.
|
||||
|
||||
|
||||
<p align="center">
|
||||
|
|
@ -417,13 +418,14 @@ Dashy supports multiple languages and locales. When available, your language sho
|
|||
- 🇵🇱 **Polish**: `pl` - Contributed by **[@skaarj1989](https://github.com/skaarj1989)**
|
||||
- 🇵🇹 **Portuguese**: `pt` - Contributed by **[@LeoColman](https://github.com/LeoColman)**
|
||||
- 🛰️ **Galician**: `gl` - Contributed by **[@pvillaverde](https://github.com/pvillaverde)**
|
||||
- 🇷🇺 **Russian**: `ru` - _Auto-generated_
|
||||
- 🇷🇺 **Russian**: `ru` -Contributed by **[@sasetz](https://github.com/sasetz)**
|
||||
- 🇸🇰 **Slovak**: `sk` - Contributed by **[@Smexhy](https://github.com/Smexhy)**
|
||||
- 🇸🇮 **Slovenian**: `sl` - Contributed by **[@UrekD](https://github.com/UrekD)**
|
||||
- 🇪🇸 **Spanish**: `es` - Contributed by **[@lu4t](https://github.com/lu4t)**
|
||||
- 🇸🇪 **Swedish**: `sv` - Contributed by **[@BOZG](https://github.com/BOZG)**
|
||||
- 🇹🇼 **Traditional Chinese**: `zh-TW` - Contributed by **[@stanly0726](https://github.com/stanly0726)**
|
||||
- 🇹🇷 **Turkish**: `tr` - Contributed by **[@imsakg](https://github.com/imsakg)**
|
||||
- 🇺🇦 **Ukrainian**: `uk` - Contributed by **[@allozavrr](https://github.com/allozavrr)**
|
||||
- 🏴☠️ **Pirate**: `pirate` - Contributed by **[@Lissy93](https://github.com/lissy93)**
|
||||
|
||||
#### Add your Language
|
||||
|
|
@ -522,164 +524,11 @@ Thank you so much to everyone who has helped with Dashy so far; every contributi
|
|||
#### Sponsors
|
||||
|
||||
Huge thanks to the sponsors helping to support Dashy's development!
|
||||
<!-- readme: sponsors -start -->
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/vincentkoc">
|
||||
<img src="https://avatars.githubusercontent.com/u/25068?u=fbd5b2d51142daa4bdbc21e21953a3b8b8188a4a&v=4" width="80;" alt="vincentkoc"/>
|
||||
<br />
|
||||
<sub><b>Vincent Koc</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/AnandChowdhary">
|
||||
<img src="https://avatars.githubusercontent.com/u/2841780?u=747e554b3a7f12eb20b7910e1c87d817844f714f&v=4" width="80;" alt="AnandChowdhary"/>
|
||||
<br />
|
||||
<sub><b>Anand Chowdhary</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/shrippen">
|
||||
<img src="https://avatars.githubusercontent.com/u/2873570?v=4" width="80;" alt="shrippen"/>
|
||||
<br />
|
||||
<sub><b>Shrippen</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/bile0026">
|
||||
<img src="https://avatars.githubusercontent.com/u/5022496?u=aec96ad173c0ea9baaba93807efa8a848af6595c&v=4" width="80;" alt="bile0026"/>
|
||||
<br />
|
||||
<sub><b>Zach Biles</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/UlisesGascon">
|
||||
<img src="https://avatars.githubusercontent.com/u/5110813?u=3c41facd8aa26154b9451de237c34b0f78d672a5&v=4" width="80;" alt="UlisesGascon"/>
|
||||
<br />
|
||||
<sub><b>Ulises Gascón</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/digitalarche">
|
||||
<img src="https://avatars.githubusercontent.com/u/6546135?u=564756d7f44ab2206819eb3148f6d822673f5066&v=4" width="80;" alt="digitalarche"/>
|
||||
<br />
|
||||
<sub><b>Digital Archeology</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/InDieTasten">
|
||||
<img src="https://avatars.githubusercontent.com/u/7047377?u=8d8f8017628b38bc46dcbf3620e194b01d3fb2d1&v=4" width="80;" alt="InDieTasten"/>
|
||||
<br />
|
||||
<sub><b>InDieTasten</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/araguaci">
|
||||
<img src="https://avatars.githubusercontent.com/u/7318668?v=4" width="80;" alt="araguaci"/>
|
||||
<br />
|
||||
<sub><b>Araguaci</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/bmcgonag">
|
||||
<img src="https://avatars.githubusercontent.com/u/7346620?u=2a0f9284f3e12ac1cc15288c254d1ec68a5081e8&v=4" width="80;" alt="bmcgonag"/>
|
||||
<br />
|
||||
<sub><b>Brian McGonagill</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/arcestia">
|
||||
<img src="https://avatars.githubusercontent.com/u/7936962?u=41e34bb816ad09323e1650f3efc0bec4fb2bc5dd&v=4" width="80;" alt="arcestia"/>
|
||||
<br />
|
||||
<sub><b>Laurensius Jeffrey</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/vlad-tim">
|
||||
<img src="https://avatars.githubusercontent.com/u/11474041?u=eee43705b54d2ec9f51fc4fcce5ad18dd17c87e4&v=4" width="80;" alt="vlad-tim"/>
|
||||
<br />
|
||||
<sub><b>Vlad</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/helixzz">
|
||||
<img src="https://avatars.githubusercontent.com/u/12218889?u=d06d0c103dfbdb99450623064f7da3c5a3675fb6&v=4" width="80;" alt="helixzz"/>
|
||||
<br />
|
||||
<sub><b>HeliXZz</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/patvdv">
|
||||
<img src="https://avatars.githubusercontent.com/u/12430107?u=e8911c2fb91af4d30432f76da8c40927b2830bd7&v=4" width="80;" alt="patvdv"/>
|
||||
<br />
|
||||
<sub><b>Patrick Van Der Veken</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/mryesiller">
|
||||
<img src="https://avatars.githubusercontent.com/u/24632172?u=0d20f2d615158f87cd60a3398d3efb026c32f291&v=4" width="80;" alt="mryesiller"/>
|
||||
<br />
|
||||
<sub><b>Göksel Yeşiller</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/sushibait">
|
||||
<img src="https://avatars.githubusercontent.com/u/26634535?v=4" width="80;" alt="sushibait"/>
|
||||
<br />
|
||||
<sub><b>Shiverme Timbers</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/undefined">
|
||||
<img src="" width="80;" alt="undefined"/>
|
||||
<br />
|
||||
<sub><b>Undefined</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/OlliVHH">
|
||||
<img src="https://avatars.githubusercontent.com/u/84959562?v=4" width="80;" alt="OlliVHH"/>
|
||||
<br />
|
||||
<sub><b>HamburgerJung</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/frankdez93">
|
||||
<img src="https://avatars.githubusercontent.com/u/87549420?v=4" width="80;" alt="frankdez93"/>
|
||||
<br />
|
||||
<sub><b>Frankdez93</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/st617">
|
||||
<img src="https://avatars.githubusercontent.com/u/128325650?v=4" width="80;" alt="st617"/>
|
||||
<br />
|
||||
<sub><b>St617</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/hudsonrock-partnerships">
|
||||
<img src="https://avatars.githubusercontent.com/u/163282900?u=5f2667f7fe5d284ac7a2da6b0800ea8970b0fcbf&v=4" width="80;" alt="hudsonrock-partnerships"/>
|
||||
<br />
|
||||
<sub><b>Hudsonrock-partnerships</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/CarterPerez-dev">
|
||||
<img src="https://avatars.githubusercontent.com/u/188120068?u=0e409c671324f8872efe4e2f7e5c12ebb8670010&v=4" width="80;" alt="CarterPerez-dev"/>
|
||||
<br />
|
||||
<sub><b>Carter Perez</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
</table>
|
||||
<!-- readme: sponsors -end -->
|
||||
|
||||

|
||||
|
||||
#### Contributors
|
||||
[](./docs/credits.md)
|
||||
[](./docs/credits.md)
|
||||
|
||||
#### Stats
|
||||
[](https://github.com/Lissy93/dashy/blob/master/docs/credits.md)
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 34 MiB After Width: | Height: | Size: 39 MiB |
|
|
@ -286,6 +286,7 @@ appConfig:
|
|||
clientId: [registered client id]
|
||||
endpoint: [OIDC endpoint]
|
||||
scope: [The scope(s) to request from the OIDC provider]
|
||||
adminGroup: admin
|
||||
```
|
||||
|
||||
Because Dashy is a SPA, a [public client](https://datatracker.ietf.org/doc/html/rfc6749#section-2.1) registration with PKCE is needed.
|
||||
|
|
|
|||
|
|
@ -93,7 +93,9 @@ The following file provides a reference of all supported configuration options.
|
|||
**Field** | **Type** | **Required**| **Description**
|
||||
--- | --- | --- | ---
|
||||
**`name`** | `string` | Required | A unique name for that page
|
||||
**`path`** | `string` | Required | The path (local or remote) to the config file to use.<br>For files located within `/public`, you only need to specify filename, for externally hosted files you must include the full URL
|
||||
**`path`** | `string` | Required | The path (local or remote) to the config file to use.<br>For files located within `/user-data`, you only need to specify filename, for externally hosted files you must include the full URL
|
||||
|
||||
For more info, see the[Multi-Page docs](/docs/pages-and-sections.md#multi-page-support)
|
||||
|
||||
**[⬆️ Back to Top](#configuring)**
|
||||
|
||||
|
|
@ -202,6 +204,8 @@ For more info, see the **[Authentication Docs](/docs/authentication.md)**
|
|||
--- | --- | --- | ---
|
||||
**`clientId`** | `string` | Required | The client id registered in the OIDC server
|
||||
**`endpoint`** | `string` | Required | The URL of the OIDC server that should be used.
|
||||
**`adminRole`** | `string` | _Optional_ | The role that will be considered as admin.
|
||||
**`adminGroup`** | `string` | _Optional_ | The group that will be considered as admin.
|
||||
**`scope`** | `string` | Required | The scope(s) to request from the OIDC provider
|
||||
|
||||
**[⬆️ Back to Top](#configuring)**
|
||||
|
|
@ -320,7 +324,7 @@ For more info, see the **[Authentication Docs](/docs/authentication.md)**
|
|||
|
||||
**Field** | **Type** | **Required**| **Description**
|
||||
--- | --- | --- | ---
|
||||
**`icon`** | `string` | _Optional_ | The icon for a given item or section. <br>See [Icon Docs](/docs/icons.md) for all available supported icon types, including: auto-fetched favicons, generative icons, emoji icons, home-lab service logos, font-awesome, simple-icons, material icons, and icons specified by URL
|
||||
**`icon`** | `string` | _Optional_ | The icon for a given item or section. <br>See [Icon Docs](/docs/icons.md) for all available supported icon types, including: auto-fetched favicons, generative icons, emoji icons, home-lab service logos, font-awesome, simple-icons, material icons, selfh.st icons, and icons specified by URL
|
||||
|
||||
**[⬆️ Back to Top](#configuring)**
|
||||
|
||||
|
|
|
|||
1327
docs/credits.md
1327
docs/credits.md
File diff suppressed because it is too large
Load diff
|
|
@ -7,6 +7,7 @@ Both sections and items can have an icon, which is specified using the `icon` at
|
|||
- [Simple Icons](#simple-icons)
|
||||
- [Generative Icons](#generative-icons)
|
||||
- [Emoji Icons](#emoji-icons)
|
||||
- [selfh.st Icons](#selfhst-icons)
|
||||
- [Home-Lab Icons](#home-lab-icons)
|
||||
- [Material Icons](#material-design-icons)
|
||||
- [Icons by URL](#icons-by-url)
|
||||
|
|
@ -63,7 +64,7 @@ Font-Awesome has a wide variety of free icons, but you can also use their pro ic
|
|||
|
||||
## Simple Icons
|
||||
|
||||
[SimpleIcons.org](https://simpleicons.org/) is a collection of 2000+ high quality, free and open source brand and logo SVG icons. Usage of which is very similar to font-awesome icons. First find the glyph you want to use on the [website](https://simpleicons.org/), then just set your icon the the simple icon slug, prefixed with `si-`.
|
||||
[SimpleIcons.org](https://simpleicons.org/) is a collection of 2000+ high quality, free and open source brand and logo SVG icons. Usage of which is very similar to font-awesome icons. First find the glyph you want to use on the [website](https://simpleicons.org/), then just set your icon to the simple icon slug, prefixed with `si-`.
|
||||
|
||||
<p align="center">
|
||||
<img width="580" src="https://i.ibb.co/MVhkXfC/simple-icons-example.png" />
|
||||
|
|
@ -109,6 +110,18 @@ For example, these will all render the same rocket (🚀) emoji: `icon: ':rocket
|
|||
|
||||
---
|
||||
|
||||
## selfh.st Icons
|
||||
|
||||
The [selfh.st](https://selfh.st/) project provides a set of icons, originally for self-hosted services, but now expanded to include a wide variety of services. These icons can be used by specifying the icon name (without extension and with all spaces replaced with -) preceded by `sh-`. See https://selfh.st/icons/ for a full list of all available icons. For example, the Home Assistant icon is `sh-home-assistant`.
|
||||
|
||||
Note: These icons are fetched from the jsdelivr CDN, so if you require offline access, the [Local Icons](#local-icons) method may be a better option for you.
|
||||
|
||||
<p align="center">
|
||||
<img width="580" src="https://i.ibb.co/pfy09LH/Screenshot-from-2025-01-08-22-04-21.png" />
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
## Home-Lab Icons
|
||||
|
||||
The [dashboard-icons](https://github.com/walkxcode/Dashboard-Icons) repo by [@WalkxCode](https://github.com/WalkxCode) provides a comprehensive collection of 360+ high-quality PNG icons for commonly self-hosted services. Dashy natively supports these icons, and you can use them just by specifying the icon name (without extension) preceded by `hl-`. See [here](https://github.com/walkxcode/Dashboard-Icons/tree/main/png) for a full list of all available icons. Note that these are fetched and cached straight from GitHub, so if you require offline access, the [Local Icons](#local-icons) method may be a better option for you.
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ Any files placed here will be served up to the root of the domain, and override
|
|||
For example, if you had `user-data/favicon.ico` this would be accessible at `http://my-dashy-instance.local/favicon.ico`
|
||||
|
||||
Example Files in `user-data`:
|
||||
- `conf.yml` - This is the only file that is compulsary, it's your main Dashy config
|
||||
- `conf.yml` - This is the only file that is compulsory, it's your main Dashy config
|
||||
- `**.yml` - Include more config files, if you'd like to have multiple pages, see [Multi-page support](/docs/pages-and-sections.md#multi-page-support) for docs
|
||||
- `favicon.ico` - The default favicon, shown in the browser's tab title
|
||||
- `initialization.html` - Static HTML page displayed before the app has finished compiling, see [`public/initialization.html`](https://github.com/Lissy93/dashy/blob/master/public/initialization.html)
|
||||
|
|
@ -61,7 +61,7 @@ Example Files in `user-data`:
|
|||
|
||||
Now that you've got Dashy running, you are going to want to set it up with your own content.
|
||||
Config is written in [YAML Format](https://yaml.org/), and saved in [`/user-data/conf.yml`](https://github.com/Lissy93/dashy/blob/master/user-data/conf.yml).
|
||||
The format on the config file is pretty straight forward. There are three root attributes:
|
||||
The format on the config file is pretty straight forward. There are four root attributes:
|
||||
|
||||
- [`pageInfo`](https://github.com/Lissy93/dashy/blob/master/docs/configuring.md#pageinfo) - Dashboard meta data, like title, description, nav bar links and footer text
|
||||
- [`appConfig`](https://github.com/Lissy93/dashy/blob/master/docs/configuring.md#appconfig-optional) - Dashboard settings, like themes, authentication, language and customization
|
||||
|
|
|
|||
499
docs/widgets.md
499
docs/widgets.md
|
|
@ -29,6 +29,7 @@ Dashy has support for displaying dynamic content in the form of widgets. There a
|
|||
- [Stock Price History](#stock-price-history)
|
||||
- [ETH Gas Prices](#eth-gas-prices)
|
||||
- [Joke of the Day](#joke)
|
||||
- [Chuck Norris quotes](#chucknorris)
|
||||
- [XKCD Comics](#xkcd-comics)
|
||||
- [Flight Data](#flight-data)
|
||||
- [NASA APOD](#astronomy-picture-of-the-day)
|
||||
|
|
@ -40,15 +41,19 @@ Dashy has support for displaying dynamic content in the form of widgets. There a
|
|||
- [Mvg Connection](#mvg-connection)
|
||||
- [Custom search](#custom-search)
|
||||
- [Rescuetime overview](#rescuetime-overview)
|
||||
- [Minecraft Server](#minecraft-server)
|
||||
- **[Self-Hosted Services Widgets](#self-hosted-services-widgets)**
|
||||
- [System Info](#system-info)
|
||||
- [Cron Monitoring](#cron-monitoring-health-checks)
|
||||
- [CPU History](#cpu-history-netdata)
|
||||
- [Memory History](#memory-history-netdata)
|
||||
- [System Load History](#load-history-netdata)
|
||||
- [Pi Hole Stats](#pi-hole-stats)
|
||||
- [Pi Hole Queries](#pi-hole-queries)
|
||||
- [Pi Hole Recent Traffic](#pi-hole-recent-traffic)
|
||||
- [Pi-Hole Stats](#pi-hole-stats)
|
||||
- [Pi-Hole Stats v6](#pi-hole-stats-v6)
|
||||
- [Pi-Hole Queries](#pi-hole-queries)
|
||||
- [Pi-Hole Queries v6](#pi-hole-queries-v6)
|
||||
- [Pi-Hole Recent Traffic](#pi-hole-recent-traffic)
|
||||
- [Pi-Hole Recent Traffic v6](#pi-hole-recent-traffic-v6)
|
||||
- [Stat Ping Statuses](#stat-ping-statuses)
|
||||
- [Synology Download Station](#synology-download-station)
|
||||
- [AdGuard Home Block Stats](#adguard-home-block-stats)
|
||||
|
|
@ -111,7 +116,7 @@ Dashy has support for displaying dynamic content in the form of widgets. There a
|
|||
|
||||
A simple, live-updating time and date widget with time-zone support. All fields are optional.
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/vjb4RTv/clock.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/clock.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -144,7 +149,7 @@ _No external data requests._
|
|||
|
||||
A simple, live-updating local weather component, showing temperature, conditions and more info.
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/r6MCfsL/weather.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/weather.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -181,7 +186,7 @@ A simple, live-updating local weather component, showing temperature, conditions
|
|||
|
||||
Displays the weather (temperature and conditions) for the next few days for a given location. Note that this requires either the free [OpenWeatherMap Student Plan](https://home.openweathermap.org/students), or the Premium Plan.
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/vshwgZB/weather-forecast.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/weather-forecast.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -217,7 +222,7 @@ Displays the weather (temperature and conditions) for the next few days for a gi
|
|||
|
||||
Display news and updates from any RSS-enabled service.
|
||||
|
||||
<p align="center"><img width="600" src="https://i.ibb.co/N9mvLh4/rss-feed.png" /></p>
|
||||
<p align="center"><img width="600" src="https://storage.googleapis.com/as93-screenshots/dashy/rss.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -262,7 +267,7 @@ If you'd like to embed a live screenshot, of all or just part of a website, then
|
|||
|
||||
Or what about showing a photo of the day? Try `https://source.unsplash.com/random/400x300` or `https://picsum.photos/400/300`
|
||||
|
||||
<p align="center"><img width="300" src="https://i.ibb.co/P48Y443/image-widget.png" /></p>
|
||||
<p align="center"><img width="300" src="https://storage.googleapis.com/as93-screenshots/dashy/image.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -290,7 +295,7 @@ Unless image fetched from remote source, no external data request is made.
|
|||
|
||||
Often find yourself searching "What's my IP", just so you can check your VPN is still connected? This widget displays your public IP address, along with ISP name and approx location. Data can be fetched from either [IpApi.co](https://ipapi.co/), [IP-API.com](https://ip-api.com/), [IpGeolocation.io](https://ipgeolocation.io/) or [IP2Location.io](https://ip2location.io/).
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/vc3c8zN/public-ip.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/public-ip.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -330,7 +335,7 @@ Or
|
|||
|
||||
Notice certain web pages aren't loading? This widget quickly shows which blacklists your IP address (or host, or email) appears on, using data from [blacklistchecker.com](https://blacklistchecker.com/).
|
||||
|
||||
<p align="center"><img width="600" src="https://i.ibb.co/hX0fp5Z/ip-blacklist.png" /></p>
|
||||
<p align="center"><img width="600" src="https://storage.googleapis.com/as93-screenshots/dashy/ip-blacklist.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -362,7 +367,7 @@ Notice certain web pages aren't loading? This widget quickly shows which blackli
|
|||
|
||||
Keep an eye on the expiry dates of your domain names, using public whois records fetched from [whoapi.com](https://whoapi.com/). Click the domain name to view additional info, like registrar, name servers and date last updated.
|
||||
|
||||
<p align="center"><img width="600" src="https://i.ibb.co/7XjByG9/domain-monitor.png" /></p>
|
||||
<p align="center"><img width="600" src="https://storage.googleapis.com/as93-screenshots/dashy/domain-monitor.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -400,7 +405,7 @@ Keep an eye on the expiry dates of your domain names, using public whois records
|
|||
|
||||
Keep track of price changes of your favorite crypto assets. Data is fetched from [CoinGecko](https://www.coingecko.com/). All fields are optional.
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/WtS6jQ8/crypto-prices.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/crypto-prices.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -448,7 +453,7 @@ Or
|
|||
|
||||
Shows recent price history for a given crypto asset, using price data fetched from [CoinGecko](https://www.coingecko.com/)
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/jr38m6S/crypto-price-history.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/crypto-price-history.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -483,7 +488,7 @@ Shows recent price history for a given crypto asset, using price data fetched fr
|
|||
|
||||
Keep track of your crypto balances and see recent transactions. Data is fetched from [BlockCypher](https://www.blockcypher.com/dev/)
|
||||
|
||||
<p align="center"><img width="600" src="https://i.ibb.co/27HG4nj/wallet-balances.png" /></p>
|
||||
<p align="center"><img width="600" src="https://storage.googleapis.com/as93-screenshots/dashy/crypto-wallet.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -516,7 +521,7 @@ Keep track of your crypto balances and see recent transactions. Data is fetched
|
|||
|
||||
Display your coding summary. [Code::Stats](https://codestats.net/) is a free and open source app that aggregates statistics about your programming activity. Dashy supports both the public instance, as well as self-hosted versions.
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/dc0DTBW/code-stats.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/code-stats.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -552,7 +557,7 @@ Display your coding summary. [Code::Stats](https://codestats.net/) is a free and
|
|||
|
||||
Shows your Mullvad VPN connection status, as well as server info. Fetched from [am.i.mullvad.net](https://mullvad.net/en/check/)
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/3BCb2YV/mullvad-check.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/mullvad.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -580,7 +585,7 @@ _No Options._
|
|||
|
||||
This widget display email addresses / aliases from addy.io. Click an email address to copy to clipboard, or use the toggle switch to enable/ disable it. Shows usage stats (bandwidth, used aliases etc), as well as total messages received, blocked and sent. Works with both self-hosted and managed instances of addy.io.
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/ZhfyRdV/anonaddy.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/addy.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -623,7 +628,7 @@ This widget display email addresses / aliases from addy.io. Click an email addre
|
|||
|
||||
Keep track of recent security advisories and vulnerabilities, with optional filtering by score, exploits, vendor and product. All fields are optional.
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/DYJMpjp/vulnerability-feed.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/cve.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -668,7 +673,7 @@ or
|
|||
|
||||
Display current FX rates in your native currency. Hover over a row to view more info, or click to show rates in that currency.
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/fMdyLTB/exchange-rates.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/currencies.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -706,9 +711,9 @@ Display current FX rates in your native currency. Hover over a row to view more
|
|||
|
||||
Counting down to the next day off work? This widget displays upcoming public holidays for your country. Data is fetched from [Enrico](http://kayaposoft.com/enrico/)
|
||||
|
||||
Note, config for this widget is case-sensetive (see [#1268](https://github.com/Lissy93/dashy/issues/1268))
|
||||
Note, config for this widget is case-sensitive (see [#1268](https://github.com/Lissy93/dashy/issues/1268))
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/VC6fZqn/public-holidays.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/holidays.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -746,7 +751,7 @@ Note, config for this widget is case-sensetive (see [#1268](https://github.com/L
|
|||
|
||||
Keep track of the current COVID-19 status. Optionally also show cases by country, and a time-series chart. Uses live data from various sources, computed by [disease.sh](https://disease.sh/)
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/7XjbyRg/covid-19-status.png?" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/covid.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -791,9 +796,9 @@ Or
|
|||
|
||||
### Sports Scores
|
||||
|
||||
Show recent scores and upcoming matches from your favourite sports team. Data is fetched from [TheSportsDB.com](https://www.thesportsdb.com/). From the UI, you can click any other team to view their scores and upcoming games, or click a league name to see all teams.
|
||||
Show recent scores and upcoming matches from your favorite sports team. Data is fetched from [TheSportsDB.com](https://www.thesportsdb.com/). From the UI, you can click any other team to view their scores and upcoming games, or click a league name to see all teams.
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/8XhXGkN/sports-scores.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/sports.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -828,7 +833,7 @@ Show recent scores and upcoming matches from your favourite sports team. Data is
|
|||
|
||||
Displays the latest news, click to read full article. Date is fetched from various news sources using [Currents API](https://currentsapi.services/en)
|
||||
|
||||
<p align="center"><img width="380" src="https://i.ibb.co/6NDWW0z/news-headlines.png" /></p>
|
||||
<p align="center"><img width="380" src="https://storage.googleapis.com/as93-screenshots/dashy/news.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -865,7 +870,7 @@ Displays the latest news, click to read full article. Date is fetched from vario
|
|||
|
||||
Shows real-time tube status of the London Underground. All fields are optional.
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/LRDhXDn/tfl-status.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/tfl.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -906,7 +911,7 @@ Shows real-time tube status of the London Underground. All fields are optional.
|
|||
|
||||
Shows recent price history for a given publicly-traded stock or share
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/XZHRb4f/stock-price.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/stocks.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -941,7 +946,7 @@ Shows recent price history for a given publicly-traded stock or share
|
|||
|
||||
Renders the current Gas cost of transactions on the Ethereum network (in both GWEI and USD), along with recent historical prices. Useful for spotting a good time to transact. Uses data from [ethgas.watch](https://ethgas.watch/)
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/LhHfQyp/eth-gas-prices.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/eth-gas.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -967,7 +972,7 @@ _No config options._
|
|||
|
||||
Renders a programming or generic joke. Data is fetched from the [JokesAPI](https://github.com/Sv443/JokeAPI) by @Sv443. All fields are optional.
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/sQJGkyR/joke.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/joke.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -997,11 +1002,41 @@ Renders a programming or generic joke. Data is fetched from the [JokesAPI](https
|
|||
|
||||
---
|
||||
|
||||
### Chuck Norris quotes
|
||||
|
||||
Renders a Chuck Norris quote. Data is fetched from the [ChuckNorrisAPI](https://api.chucknorris.io/) by @matchilling. All fields are optional.
|
||||
|
||||
<p align="center"><img width="400" src="https://tbd" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
**Field** | **Type** | **Required** | **Description**
|
||||
--- | --- | --- | ---
|
||||
**`categories`** | `string` | _Optional_ | Set the category of jokes to return. Use a string to specify a single category, or an array to pass in multiple options. Available options are: `animal`,`career`,`celebrity`,`dev`,`explicit`,`fashion`,`food`,`history`,`money`,`movie`,`music`,`political`,`religion`,`science`,`sport` and `travel`. An up-to-date list of supported categories can be found [here](https://api.chucknorris.io/jokes/categories). Defaults to not explicitely set and therefore any of the categories can come up.
|
||||
|
||||
#### Example
|
||||
|
||||
```yaml
|
||||
- type: chucknorris
|
||||
options:
|
||||
categories: history,sport
|
||||
```
|
||||
|
||||
#### Info
|
||||
|
||||
- **CORS**: 🟢 Enabled
|
||||
- **Auth**: 🟢 Not Required
|
||||
- **Price**: 🟢 Free
|
||||
- **Host**: Managed Instance
|
||||
- **Privacy**: _See [matchilling's Privacy Policy](https://api.chucknorris.io/privacy)_
|
||||
|
||||
---
|
||||
|
||||
### XKCD Comics
|
||||
|
||||
Have a laugh with the daily comic from [XKCD](https://xkcd.com/). A classic webcomic website covering everything from Linux, math, romance, science and language. All fields are optional.
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/kqV68hy/xkcd-comic.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/xkcd.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -1030,7 +1065,7 @@ Have a laugh with the daily comic from [XKCD](https://xkcd.com/). A classic webc
|
|||
|
||||
Displays airport departure and arrival flights, using data from [AeroDataBox](https://www.aerodatabox.com/). Useful if you live near an airport and often wonder where the flight overhead is going to. Hover over a row for more flight data.
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/yPMBJSY/flight-data.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/flights.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -1066,7 +1101,7 @@ Displays airport departure and arrival flights, using data from [AeroDataBox](ht
|
|||
|
||||
Show the NASA Astronomy Picture of the Day. Data is fetched from [APOD](https://apod.nasa.gov/apod/) using [@Lissy93/go-apod](https://github.com/lissy93/go-apod) / hosted at [apod.as93.net](https://apod.as93.net/).
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/ZMkgLFK/apod.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/apod.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -1092,7 +1127,7 @@ _No config options._
|
|||
|
||||
Displays currently trending projects on GitHub. Optionally specify a language and time-frame. Data is fetched from [Lissy93/gh-trending-no-cors](https://github.com/Lissy93/gh-trending-no-cors) using the GitHub API. All fields are optional.
|
||||
|
||||
<p align="center"><img width="380" src="https://i.ibb.co/BGy7Q3g/github-trending.png" /></p>
|
||||
<p align="center"><img width="380" src="https://storage.googleapis.com/as93-screenshots/dashy/github-trending.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -1125,7 +1160,7 @@ Displays currently trending projects on GitHub. Optionally specify a language an
|
|||
|
||||
Display stats from your GitHub profile, using embedded cards from [anuraghazra/github-readme-stats](https://github.com/anuraghazra/github-readme-stats)
|
||||
|
||||
<p align="center"><img width="380" src="https://i.ibb.co/L0K1zNN/github-profile-stats.png" /></p>
|
||||
<p align="center"><img width="380" src="https://storage.googleapis.com/as93-screenshots/dashy/github-stats.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -1163,7 +1198,7 @@ Display stats from your GitHub profile, using embedded cards from [anuraghazra/g
|
|||
|
||||
Display status of one or more HealthChecks project(s). Works with healthchecks.io and your selfhosted instance.
|
||||
|
||||
<p align="center"><img width="380" src="https://i.ibb.co/W5dP6VN/Bildschirm-foto-2023-01-07-um-11-07-11.png" /></p>
|
||||
<p align="center"><img width="380" src="https://storage.googleapis.com/as93-screenshots/dashy/healthchecks.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -1297,6 +1332,155 @@ In other words: Private, noncomercial, moderate use of the API is tolerated. The
|
|||
|
||||
---
|
||||
|
||||
### Custom List
|
||||
|
||||
Renders custom schema-compliant JOSN in a list.
|
||||
|
||||
#### Options
|
||||
**Field** | **Type** | **Required** | **Description**
|
||||
--- | --- | --- | ---
|
||||
**`url`** | `text` | Required | A string containing the url of a json file.
|
||||
**`title`** | `text` | optional | A title for the widget. Can be helpful if stacking multiple lists in the same section.
|
||||
**`daysForNew`** | `number` | Optional | Used to highlight new items.
|
||||
|
||||
#### Json Schema
|
||||
The input file should comply with the following schema:
|
||||
```json
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"type": "array",
|
||||
"items": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"link": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
"url": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"text",
|
||||
"url",
|
||||
"title"
|
||||
]
|
||||
},
|
||||
"value": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"text",
|
||||
"title"
|
||||
]
|
||||
},
|
||||
"date": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"link",
|
||||
"value",
|
||||
"date"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Example: This json data was generated by a data worflow that gets the new releases of a few projects from GitHub. The system used to build the data workflow is n8n.
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"link": {
|
||||
"text": "jellyfin/jellyfin",
|
||||
"url": "https://github.com/jellyfin/jellyfin/releases/tag/v10.10.7",
|
||||
"title": ""
|
||||
},
|
||||
"value": {
|
||||
"text": "v10.10.7",
|
||||
"title": "2025-04-05"
|
||||
},
|
||||
"date": "2025-04-05T19:14:59Z"
|
||||
},
|
||||
{
|
||||
"link": {
|
||||
"text": "jellyfin/jellyfin-web",
|
||||
"url": "https://github.com/jellyfin/jellyfin-web/releases/tag/v10.10.7",
|
||||
"title": ""
|
||||
},
|
||||
"value": {
|
||||
"text": "v10.10.7",
|
||||
"title": "2025-04-05"
|
||||
},
|
||||
"date": "2025-04-05T19:15:00Z"
|
||||
},
|
||||
{
|
||||
"link": {
|
||||
"text": "lissy93/dashy",
|
||||
"url": "https://github.com/Lissy93/dashy/releases/tag/3.1.1",
|
||||
"title": ""
|
||||
},
|
||||
"value": {
|
||||
"text": "3.1.1",
|
||||
"title": "2024-05-30"
|
||||
},
|
||||
"date": "2024-05-30T17:20:53Z"
|
||||
},
|
||||
{
|
||||
"link": {
|
||||
"text": "VSCodium/vscodium",
|
||||
"url": "https://github.com/VSCodium/vscodium/releases/tag/1.102.14746",
|
||||
"title": ""
|
||||
},
|
||||
"value": {
|
||||
"text": "1.102.14746",
|
||||
"title": "2025-07-16"
|
||||
},
|
||||
"date": "2025-07-16T18:27:49Z"
|
||||
}
|
||||
]
|
||||
```
|
||||
#### Notes
|
||||
- This widget is designed to render data generated by another system that complies with the schema. The example JSON data above was generated using a n8n workflow, and other ETL or workflow systems can generate similar results.
|
||||
- To avoid requests to a different system in each refresh, you can save the input files locally in the user-data folder inside your Dashy installation.
|
||||
- To use json files from a different domain, remember to add `useProxy: true` to the widget configuration. I have not tested this use case because I save all my input data locally on the Dashy server. Please open a ticket if you have an issue in this use case.
|
||||
|
||||
#### Example
|
||||
|
||||
This widget renders a json file that from a `json-data` directory inside the `user-data` directory on the Dashy server.
|
||||
```yaml
|
||||
- type: custom-list
|
||||
options:
|
||||
url: /json-data/github-releases.json
|
||||
title: 'Github Releases'
|
||||
daysForNew: 5
|
||||
```
|
||||
|
||||
#### Info
|
||||
|
||||
- **CORS**: 🟢 Not needed for files hosted inside the `user-data` directory. Use `useProxy: true` to bypass CORS restrictions when using data from a different server.
|
||||
- **Auth**: 🟢 Not Required
|
||||
- **Price**: 🟢 Free
|
||||
- **Host**: user defined
|
||||
- **Privacy**: depends on the user defined host.
|
||||
|
||||
---
|
||||
|
||||
### Custom search
|
||||
|
||||
Allows web search using multiple user-defined search engines and other websites.
|
||||
|
|
@ -1351,7 +1535,7 @@ This widget allows searching multiple search engines from dashy.
|
|||
|
||||
Show an overview of how you have spent your time for the current day.
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/bvx3PQM/rescuetime.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/rescue-time.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -1378,6 +1562,45 @@ Show an overview of how you have spent your time for the current day.
|
|||
|
||||
---
|
||||
|
||||
### Minecraft Server
|
||||
|
||||
Show minecraft server status
|
||||
|
||||
<p align="center"><img width="380" src="https://i.ibb.co/hcmd4Wf/minecraft-widget.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
**Field** | **Type** | **Required** | **Description**
|
||||
--- | --- | --- | ---
|
||||
**`title`** | `string` | _Optional_ | Display title for server uses server address if not set.
|
||||
**`server`** | `string` | Required | Server hostname or ip(:port) will use srv records.
|
||||
**`bedrock`** | `boolean` | _Optional_ | If server is a bedrock edition server. (default false)
|
||||
**`showMods`** | `boolean` | _Optional_ | Display mod list if available
|
||||
**`showPlayers`** | `boolean` | _Optional_ | Display player list if available
|
||||
**`showPlugins`** | `boolean` | _Optional_ | Display plugin list if available
|
||||
|
||||
#### Example
|
||||
|
||||
```yaml
|
||||
- type: minecraft-status
|
||||
options:
|
||||
title: Venity Network
|
||||
server: play.venitymc.com
|
||||
bedrock: true
|
||||
showMods: true
|
||||
showPlayers: true
|
||||
showPlugins: true
|
||||
```
|
||||
#### Info
|
||||
|
||||
- **CORS**: 🟢 Enabled
|
||||
- **Auth**: 🟢 Not Required
|
||||
- **Price**: 🟢 Free
|
||||
- **Host**: [Minecraft Server Status](https://mcsrvstat.us/)
|
||||
- **Privacy**: _See [Minecraft Server Status FAQ](https://mcsrvstat.us/faq)_
|
||||
|
||||
---
|
||||
|
||||
|
||||
|
||||
## Self-Hosted Services Widgets
|
||||
|
|
@ -1386,7 +1609,7 @@ Show an overview of how you have spent your time for the current day.
|
|||
_See [MVG Datenschutz](https://www.mvg.de/datenschutz-mvg.html)_
|
||||
Displays info about the server which Dashy is hosted on. Includes user + host, operating system, uptime and basic memory & load data.
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/rvDPBDF/system-info.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/system-info.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -1410,7 +1633,7 @@ Note that this widget is not available if you are running Dashy in a container o
|
|||
|
||||
Cron job monitoring using [Health Checks](https://github.com/healthchecks/healthchecks). Both managed and self-hosted instances are supported.
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/Ptf2kwm/health-checks.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/cron-monitor.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -1441,7 +1664,7 @@ Cron job monitoring using [Health Checks](https://github.com/healthchecks/health
|
|||
|
||||
Pull recent CPU usage history from NetData.
|
||||
|
||||
<p align="center"><img width="600" src="https://i.ibb.co/ZdyR5nJ/nd-cpu-history.png" /></p>
|
||||
<p align="center"><img width="600" src="https://storage.googleapis.com/as93-screenshots/dashy/cpu-history.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -1505,7 +1728,7 @@ Pull recent system RAM usage from NetData, and show as a breakdown of different
|
|||
|
||||
Pull recent load usage in 1, 5 and 15 minute intervals, from NetData.
|
||||
|
||||
<p align="center"><img width="600" src="https://i.ibb.co/qR9C2tJ/nd-load-history.png" /></p>
|
||||
<p align="center"><img width="600" src="https://storage.googleapis.com/as93-screenshots/dashy/load-history.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -1533,11 +1756,11 @@ Pull recent load usage in 1, 5 and 15 minute intervals, from NetData.
|
|||
|
||||
---
|
||||
|
||||
### Pi Hole Stats
|
||||
### Pi-Hole Stats
|
||||
|
||||
Displays the number of queries blocked by [Pi-Hole](https://pi-hole.net/).
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/zftCLJN/pi-hole-stats.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/pi-hole.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -1574,16 +1797,62 @@ Displays the number of queries blocked by [Pi-Hole](https://pi-hole.net/).
|
|||
- **CORS**: 🟢 Enabled
|
||||
- **Auth**: 🔴 Required
|
||||
- **Price**: 🟢 Free
|
||||
- **Host**: Self-Hosted (see [GitHub - Pi-hole](https://github.com/pi-hole/pi-hole))
|
||||
- **Host**: Self-Hosted (see [GitHub - Pi-Hole](https://github.com/pi-hole/pi-hole))
|
||||
- **Privacy**: _See [Pi-Hole Privacy Guide](https://pi-hole.net/privacy/)_
|
||||
|
||||
---
|
||||
|
||||
### Pi Hole Queries
|
||||
### Pi-Hole Stats v6
|
||||
|
||||
Displays the number of queries blocked by [Pi-Hole](https://pi-hole.net/). Use this version of the widget if you have a v6+ Pi-Hole instance.
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/zftCLJN/pi-hole-stats.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
**Field** | **Type** | **Required** | **Description**
|
||||
--- | --- | --- | ---
|
||||
**`hostname`** | `string` | Required | The URL to your Pi-Hole instance
|
||||
**`hideStatus`** / **`hideChart`** / **`hideInfo`** | `boolean` | _Optional_ | Optionally hide any of the three parts of the widget
|
||||
**`apiKey`** | `string` | Required | Your Pi-Hole web password or application password. It **IS** your Pi-Hole admin interface password **UNLESS** you have 2FA turned on (in contrast to the old widget). If you have 2FA turned on you will need to create an application password. Refer to Pi-Hole documentation for how to create an application password.
|
||||
|
||||
#### Example
|
||||
|
||||
```yaml
|
||||
- type: pi-hole-stats-v6
|
||||
options:
|
||||
hostname: http://192.168.130.1
|
||||
apiKey: xxxxxxxxxxxxxxxxxxxxxxx
|
||||
```
|
||||
|
||||
> [!TIP]
|
||||
> In order to avoid leaking secret data, both `hostname` and `apiKey` can leverage environment variables. Simply pass the name of the variable, which MUST start with `VUE_APP_`.
|
||||
|
||||
```yaml
|
||||
- type: pi-hole-stats-v6
|
||||
options:
|
||||
hostname: VUE_APP_pihole_ip
|
||||
apiKey: VUE_APP_pihole_key
|
||||
```
|
||||
|
||||
> [!IMPORTANT]
|
||||
> You will need to restart the server (or the docker image) if adding/editing an env var for this to be refreshed.
|
||||
|
||||
#### Info
|
||||
|
||||
- **CORS**: 🟢 Enabled
|
||||
- **Auth**: 🔴 Required
|
||||
- **Price**: 🟢 Free
|
||||
- **Host**: Self-Hosted (see [GitHub - Pi-Hole](https://github.com/pi-hole/pi-hole))
|
||||
- **Privacy**: _See [Pi-Hole Privacy Guide](https://pi-hole.net/privacy/)_
|
||||
|
||||
---
|
||||
|
||||
### Pi-Hole Queries
|
||||
|
||||
Shows top queries that were blocked and allowed by [Pi-Hole](https://pi-hole.net/).
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/pXR0bdQ/pi-hole-queries.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/pi-hole-queries.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -1612,11 +1881,44 @@ Shows top queries that were blocked and allowed by [Pi-Hole](https://pi-hole.net
|
|||
|
||||
---
|
||||
|
||||
### Pi Hole Recent Traffic
|
||||
### Pi-Hole Queries v6
|
||||
|
||||
Shows top queries that were blocked and allowed by [Pi-Hole](https://pi-hole.net/). Use this version of the widget if you have a v6+ Pi-Hole instance.
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/pXR0bdQ/pi-hole-queries.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
**Field** | **Type** | **Required** | **Description**
|
||||
--- | --- | --- | ---
|
||||
**`hostname`** | `string` | Required | The URL to your Pi-Hole instance
|
||||
**`apiKey`** | `string` | Required | Your Pi-Hole web password or application password. It **IS** your Pi-Hole admin interface password **UNLESS** you have 2FA turned on (in contrast to the old widget). If you have 2FA turned on you will need to create an application password. Refer to Pi-Hole documentation for how to create an application password.
|
||||
**`count`** | `number` | _Optional_ | The number of queries to display. Defaults to `10`
|
||||
|
||||
#### Example
|
||||
|
||||
```yaml
|
||||
- type: pi-hole-top-queries-v6
|
||||
options:
|
||||
hostname: https://pi-hole.local
|
||||
apiKey: xxxxxxxxxxxxxxxxxxxxxxx
|
||||
```
|
||||
|
||||
#### Info
|
||||
|
||||
- **CORS**: 🟢 Enabled
|
||||
- **Auth**: 🔴 Required
|
||||
- **Price**: 🟢 Free
|
||||
- **Host**: Self-Hosted (see [GitHub - Pi-hole](https://github.com/pi-hole/pi-hole))
|
||||
- **Privacy**: _See [Pi-Hole Privacy Guide](https://pi-hole.net/privacy/)_
|
||||
|
||||
---
|
||||
|
||||
### Pi-Hole Recent Traffic
|
||||
|
||||
Shows number of recent traffic, using allowed and blocked queries from [Pi-Hole](https://pi-hole.net/)
|
||||
|
||||
<p align="center"><img width="500" src="https://i.ibb.co/7kdxxwx/pi-hole-recent-queries.png" /></p>
|
||||
<p align="center"><img width="500" src="https://storage.googleapis.com/as93-screenshots/dashy/pi-hole-trafic.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -1644,11 +1946,43 @@ Shows number of recent traffic, using allowed and blocked queries from [Pi-Hole]
|
|||
|
||||
---
|
||||
|
||||
### Pi-Hole Recent Traffic v6
|
||||
|
||||
Shows number of recent traffic, using allowed and blocked queries from [Pi-Hole](https://pi-hole.net/). Use this version of the widget if you have a v6+ Pi-Hole instance.
|
||||
|
||||
<p align="center"><img width="500" src="https://i.ibb.co/7kdxxwx/pi-hole-recent-queries.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
**Field** | **Type** | **Required** | **Description**
|
||||
--- | --- | --- | ---
|
||||
**`hostname`** | `string` | Required | The URL to your Pi-Hole instance
|
||||
**`apiKey`** | `string` | Required | Your Pi-Hole web password or application password. It **IS** your Pi-Hole admin interface password **UNLESS** you have 2FA turned on (in contrast to the old widget). If you have 2FA turned on you will need to create an application password. Refer to Pi-Hole documentation for how to create an application password.
|
||||
|
||||
#### Example
|
||||
|
||||
```yaml
|
||||
- type: pi-hole-traffic-v6
|
||||
options:
|
||||
hostname: https://pi-hole.local
|
||||
apiKey: xxxxxxxxxxxxxxxxxxxxxxx
|
||||
```
|
||||
|
||||
#### Info
|
||||
|
||||
- **CORS**: 🟢 Enabled
|
||||
- **Auth**: 🔴 Required
|
||||
- **Price**: 🟢 Free
|
||||
- **Host**: Self-Hosted (see [GitHub - Pi-hole](https://github.com/pi-hole/pi-hole))
|
||||
- **Privacy**: _See [Pi-Hole Privacy Guide](https://pi-hole.net/privacy/)_
|
||||
|
||||
---
|
||||
|
||||
### Stat Ping Statuses
|
||||
|
||||
Displays the current and recent uptime of your running services, via a self-hosted instance of [StatPing](https://github.com/statping/statping)
|
||||
|
||||
<p align="center"><img width="300" src="https://i.ibb.co/Fq7JDjQ/stat-ping.png" /></p>
|
||||
<p align="center"><img width="300" src="https://storage.googleapis.com/as93-screenshots/dashy/statping.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -1696,7 +2030,7 @@ Note, the Group Id is not directly visible in StatPing UI, you can inspect the g
|
|||
|
||||
Displays the current downloads/torrents tasks of your Synology NAS
|
||||
|
||||
<p align="center"><img width="500" src="https://i.ibb.co/N2kKWTN/image.png" /></p>
|
||||
<p align="center"><img width="500" src="https://storage.googleapis.com/as93-screenshots/dashy/synology-downloads.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -1733,7 +2067,7 @@ Displays the current downloads/torrents tasks of your Synology NAS
|
|||
Fetches data from your [AdGuard Home](https://adguard.com/en/adguard-home/overview.html) instance, and
|
||||
displays total number of allowed and blocked queries, plus a pie chart showing breakdown by block type.
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/qgkcxsN/adguard-block-percent-2.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/adguard-stats.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -1768,7 +2102,7 @@ displays total number of allowed and blocked queries, plus a pie chart showing b
|
|||
|
||||
Fetches data from your [AdGuard Home](https://adguard.com/en/adguard-home/overview.html) instance, to display the current status of each of your filter lists. Includes filter name, last updated, number of items, and a link to the list.
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/WsJkf5g/adguard-filters-list.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/adguard-filters.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -1805,7 +2139,7 @@ Fetches data from your [AdGuard Home](https://adguard.com/en/adguard-home/overvi
|
|||
|
||||
Fetches data from your [AdGuard Home](https://adguard.com/en/adguard-home/overview.html) instance, and displays the current status (Enabled / Disabled) of AdGuard DNS. Click show more to view detailed info, including upstream DNS provider, active ports, and the status of DNSSEC, EDNS CS, PTR and IPv6.
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/G0JngBb/adguard-dns-info.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/adguard-dns.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -1842,7 +2176,7 @@ Fetches data from your [AdGuard Home](https://adguard.com/en/adguard-home/overvi
|
|||
|
||||
Fetches data from your [AdGuard Home](https://adguard.com/en/adguard-home/overview.html) instance, and displays a list of the most queried, and most blocked domains.
|
||||
|
||||
<p align="center"><img width="600" src="https://i.ibb.co/qRhYYTk/adguard-top-domains.png" /></p>
|
||||
<p align="center"><img width="600" src="https://storage.googleapis.com/as93-screenshots/dashy/adguard-domains.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -1887,7 +2221,7 @@ Shows quota usage when quota is enabled for the user or disk usage when not enab
|
|||
|
||||
Known issues: the User API incorrectly reports available disk space as total for admin users when quota is not enabled (which usually is the case for admins).
|
||||
|
||||
<p align="center"><img width="450" src="https://i.ibb.co/F8Fdm3t/nextcloud-user.png" alt="nextcloud-user" /></p>
|
||||
<p align="center"><img width="450" src="https://storage.googleapis.com/as93-screenshots/dashy/nextcloud-user.png" alt="nextcloud-user" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -1922,7 +2256,7 @@ Known issues: the User API incorrectly reports available disk space as total for
|
|||
|
||||
Show user statuses for selected users.
|
||||
|
||||
<p align="center"><img width="450" src="https://i.ibb.co/Lk4DFT5/nextcloud-userstatus.png" alt="nextcloud-userstatus" /></p>
|
||||
<p align="center"><img width="450" src="https://storage.googleapis.com/as93-screenshots/dashy/nextcloud-user-status.png" alt="nextcloud-userstatus" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -1960,7 +2294,7 @@ Show user statuses for selected users.
|
|||
|
||||
Displays your notifications and allows deleting them.
|
||||
|
||||
<p align="center"><img width="450" src="https://i.ibb.co/yQCS51k/nextcloud-notifications.png" alt="nextcloud-notifications" /></p>
|
||||
<p align="center"><img width="450" src="https://storage.googleapis.com/as93-screenshots/dashy/next-cloud-notifications.png" alt="nextcloud-notifications" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -1997,7 +2331,7 @@ Displays your notifications and allows deleting them.
|
|||
|
||||
Visualises overall memory utilisation and CPU load averages, shows server versions.
|
||||
|
||||
<p align="center"><img width="450" src="https://i.ibb.co/KW4t6nG/nextcloud-system.png" alt="nextcloud-system" /></p>
|
||||
<p align="center"><img width="450" src="https://storage.googleapis.com/as93-screenshots/dashy/next-cloud-sysyem.png" alt="nextcloud-system" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -2032,7 +2366,7 @@ Visualises overall memory utilisation and CPU load averages, shows server versio
|
|||
|
||||
Shows key usage statistics about your Nextcloud server.
|
||||
|
||||
<p align="center"><img width="450" src="https://i.ibb.co/pPXPQFB/nextcloud-stats.png" alt="nextcloud-stats" /></p>
|
||||
<p align="center"><img width="450" src="https://storage.googleapis.com/as93-screenshots/dashy/nextcloud-stats.png" alt="nextcloud-stats" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -2067,7 +2401,7 @@ Shows key usage statistics about your Nextcloud server.
|
|||
|
||||
Shows statistics about PHP OPcache performance on your Nextcloud server.
|
||||
|
||||
<p align="center"><img width="450" src="https://i.ibb.co/xf6M4J2/nextcloud-phpopcache.png" alt="nextcloud-phpopcache" /></p>
|
||||
<p align="center"><img width="450" src="https://storage.googleapis.com/as93-screenshots/dashy/nextcloud-php.png" alt="nextcloud-phpopcache" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -2169,7 +2503,7 @@ This will show the list of VMs, with a title and a linked fotter, hiding VM temp
|
|||
|
||||
Shows queue information regarding your self hosted Sabnzbd server.
|
||||
|
||||
<p align="center"><img width="450" src="https://i.ibb.co/5TTSRyM/sabnzbd.png" alt="Sabnzbd" /></p>
|
||||
<p align="center"><img width="450" src="https://storage.googleapis.com/as93-screenshots/dashy/sabnzbd.png" alt="Sabnzbd" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -2205,7 +2539,7 @@ Shows queue information regarding your self hosted Sabnzbd server.
|
|||
|
||||
Display info from the Gluetun VPN container public IP API. This can show the IP and location data for the exit VPN node.
|
||||
|
||||
<p align="center"><img width="380" src="https://i.ibb.co/xjXbZ7Z/Screenshot-from-2022-07-20-21-42-34.png" /></p>
|
||||
<p align="center"><img width="380" src="https://storage.googleapis.com/as93-screenshots/dashy/guletn-vpn.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -2238,7 +2572,7 @@ Display info from the Gluetun VPN container public IP API. This can show the IP
|
|||
|
||||
Display the last builds from a [Drone CI](https://www.drone.ci) instance. A self-hosted CI system that uses docker.
|
||||
|
||||
<p align="center"><img width="380" src="https://i.ibb.co/nQM3BXj/Bildschirm-foto-2023-01-07-um-01-31-45.png" /></p>
|
||||
<p align="center"><img width="380" src="https://storage.googleapis.com/as93-screenshots/dashy/drone-ci.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -2340,6 +2674,7 @@ Linkding is a self-hosted bookmarking service, which has a clean interface and i
|
|||
|
||||
[Tactical RMM](https://github.com/amidaware/tacticalrmm) is a self-hosted remote monitoring & management tool.
|
||||
|
||||
|
||||
<p align="center"><a href="https://github.com/user-attachments/assets/152a7205-e5de-401f-bad8-19063ddfaf3c">
|
||||
<img src="https://github.com/user-attachments/assets/5921d46f-d84c-494d-8aaf-6b20cc592640" alt="Capture" border="0"></a></p>
|
||||
|
||||
|
|
@ -2401,7 +2736,7 @@ Here an example for Docker
|
|||
|
||||
Glances can be launched with the `glances` command. You'll need to run it in web server mode, using the `-w` option for the API to be reachable. If you don't plan on using the Web UI, then you can disable it using `--disable-webui`. See the [command reference docs](https://glances.readthedocs.io/en/latest/cmds.html) for more info.
|
||||
|
||||
If Glaces is running on a Windows system it is recommanded to add the following arguments ```--disable-plugin all --enable-plugin cpu,mem,diskio,ip,network,containers,quicklook,load,fs,alert -w``` This is due to Glances not being that stable on windows, so disabling all plugins that aren't used by Dashy widgets can save on ressources.
|
||||
If Glances is running on a Windows system it is recommended to add the following arguments ```--disable-plugin all --enable-plugin cpu,mem,diskio,ip,network,containers,quicklook,load,fs,alert -w``` This is due to Glances not being that stable on windows, so disabling all plugins that aren't used by Dashy widgets can save on ressources.
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -2427,7 +2762,7 @@ Note that if auth is configured, requests must be proxied with `useProxy: true`
|
|||
|
||||
#### Screenshot
|
||||
|
||||
[](https://ibb.co/pR6dMZT)
|
||||
[](https://ibb.co/pR6dMZT)
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -2435,7 +2770,7 @@ Note that if auth is configured, requests must be proxied with `useProxy: true`
|
|||
|
||||
Live-updating current CPU usage, as a combined average across all cores
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/qkLgxLp/gl-cpu-usage.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/current-cpu.png" /></p>
|
||||
|
||||
#### Example
|
||||
|
||||
|
|
@ -2451,7 +2786,7 @@ Live-updating current CPU usage, as a combined average across all cores
|
|||
|
||||
Speedometer styled version of the Current CPU Usage widget
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/7RHTRNq/gl-cpu-speedometer.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/current-cpu-speedometer.png" /></p>
|
||||
|
||||
#### Example
|
||||
|
||||
|
|
@ -2467,7 +2802,7 @@ Speedometer styled version of the Current CPU Usage widget
|
|||
|
||||
Live-updating CPU usage breakdown per core
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/512MYhT/gl-cpu-cores.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/cpu-per-core.png" /></p>
|
||||
|
||||
#### Example
|
||||
|
||||
|
|
@ -2483,7 +2818,7 @@ Live-updating CPU usage breakdown per core
|
|||
|
||||
Recent CPU usage history, across all cores, and displayed by user and system
|
||||
|
||||
<p align="center"><img width="500" src="https://i.ibb.co/zs8BDzR/gl-cpu-history.png" /></p>
|
||||
<p align="center"><img width="500" src="https://storage.googleapis.com/as93-screenshots/dashy/cpu-history-chart.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -2506,7 +2841,7 @@ Recent CPU usage history, across all cores, and displayed by user and system
|
|||
|
||||
Real-time memory usage gauge, with more info visible on click
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/rynp52J/gl-mem-usage.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/current-mem.png" /></p>
|
||||
|
||||
#### Example
|
||||
|
||||
|
|
@ -2522,7 +2857,7 @@ Real-time memory usage gauge, with more info visible on click
|
|||
|
||||
Speedometer styled version of the Current Memory Usage widget
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/wsNW7Xr/gl-mem-speedometer.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/current-mem-speedometer.png" /></p>
|
||||
|
||||
#### Example
|
||||
|
||||
|
|
@ -2538,7 +2873,7 @@ Speedometer styled version of the Current Memory Usage widget
|
|||
|
||||
Recent memory usage chart
|
||||
|
||||
<p align="center"><img width="500" src="https://i.ibb.co/V3wSgW0/gl-mem-history.png" /></p>
|
||||
<p align="center"><img width="500" src="https://storage.googleapis.com/as93-screenshots/dashy/mem-history-glances.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -2561,7 +2896,7 @@ Recent memory usage chart
|
|||
|
||||
List connected disks, showing free / used space and other info (file system, mount point and space available)
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/25y94bB/gl-disk-usage.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/diskspace-glances.png" /></p>
|
||||
|
||||
#### Example
|
||||
|
||||
|
|
@ -2577,7 +2912,7 @@ List connected disks, showing free / used space and other info (file system, mou
|
|||
|
||||
Shows real-time read and write speeds and operations per sec for each disk
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/JdgjCjG/gl-disk-io.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/disk-io-glances.png" /></p>
|
||||
|
||||
#### Example
|
||||
|
||||
|
|
@ -2593,7 +2928,7 @@ Shows real-time read and write speeds and operations per sec for each disk
|
|||
|
||||
Shows the number of processes waiting in the run-queue, averaged across all cores. Displays for past 5, 10 and 15 minutes
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/090FfNy/gl-system-load.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/system-load-glances.png" /></p>
|
||||
|
||||
#### Example
|
||||
|
||||
|
|
@ -2609,7 +2944,7 @@ Shows the number of processes waiting in the run-queue, averaged across all core
|
|||
|
||||
Shows recent historical system load, calculated from the number of processes waiting in the run-queue, in 1, 5 and 15 minute intervals, and averaged across all cores. Optionally specify `limit` to set number of results returned, defaults to `500`, max `100000`, but the higher the number the longer the load and render times will be.
|
||||
|
||||
<p align="center"><img width="500" src="https://i.ibb.co/C2rGMLg/system-load-history.png" /></p>
|
||||
<p align="center"><img width="500" src="https://storage.googleapis.com/as93-screenshots/dashy/system-load-history-glances.png" /></p>
|
||||
|
||||
#### Example
|
||||
|
||||
|
|
@ -2625,7 +2960,7 @@ Shows recent historical system load, calculated from the number of processes wai
|
|||
|
||||
Lists visible network interfaces, including real-time upload/ download stats
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/FnhgHfG/gl-network-interfaces.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/network-interfaces-glances.png" /></p>
|
||||
|
||||
#### Example
|
||||
|
||||
|
|
@ -2641,7 +2976,7 @@ Lists visible network interfaces, including real-time upload/ download stats
|
|||
|
||||
Shows amount of data recently uploaded/ downloaded across all network interfaces. Optionally set the `limit` option to specify number historical of data points to return
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/12RN6KT/gl-network-traffic.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/network-traffic-glances.png" /></p>
|
||||
|
||||
#### Example
|
||||
|
||||
|
|
@ -2674,7 +3009,7 @@ Lists recent high resource usage alerts (e.g. CPU, mem, IO, load, temp)
|
|||
|
||||
Shows public and private IP address. Note that the ip plugin is not available on all instances of Glances.
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/ZhXBxZr/gl-ip-address.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/ip-addresses-glances.png" /></p>
|
||||
|
||||
#### Example
|
||||
|
||||
|
|
@ -2693,7 +3028,7 @@ Displays temperature data from system CPUs.
|
|||
Note: This widget uses the [`sensors`](https://github.com/nicolargo/glances/blob/develop/glances/plugins/glances_sensors.py) plugin, which is disabled by default, and may cause [performance issues](https://github.com/nicolargo/glances/issues/1664#issuecomment-632063558).
|
||||
You'll need to enable the sensors plugin to use this widget, using: `--enable-plugin sensors` when you start Glances.
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/xSs4Gqd/gl-cpu-temp.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/cpu-temp-glances.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -2718,7 +3053,7 @@ You'll need to enable the sensors plugin to use this widget, using: `--enable-pl
|
|||
|
||||
Embed any webpage into your dashboard as a widget.
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/t4VHnh3/iframe-widget.gif" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/iframe.gif" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -2743,7 +3078,7 @@ Many websites and apps provide their own embeddable widgets. These can be used w
|
|||
|
||||
⚠️ **NOTE:** Use with extreme caution. Embedding a script from an untrustworthy source may have serious unintended consequences.
|
||||
|
||||
<p align="center"><img width="400" src="https://i.ibb.co/fkwNnxT/embed-widget-2.png" /></p>
|
||||
<p align="center"><img width="400" src="https://storage.googleapis.com/as93-screenshots/dashy/html-embed.png" /></p>
|
||||
|
||||
#### Options
|
||||
|
||||
|
|
@ -2810,7 +3145,7 @@ Display data from any service with a Prometheus exporter.
|
|||
|
||||
Show live data from an RSS-enabled service. The only required parameter is `rssUrl`, which is the URL to the ATOM feed. See [RSS Widget](#rss-feed) for full list of available options.
|
||||
|
||||
<p align="center"><img width="700" src="https://i.ibb.co/1r88pvL/rss-feed-example-1.png" /></p>
|
||||
<p align="center"><img width="700" src="https://storage.googleapis.com/as93-screenshots/dashy/data-feed.png" /></p>
|
||||
|
||||
#### Example
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@
|
|||
"remedial": "^1.0.8",
|
||||
"rss-parser": "3.13.0",
|
||||
"rsup-progress": "^3.2.0",
|
||||
"simple-icons": "^12.2.0",
|
||||
"simple-icons": "^14.4.0",
|
||||
"v-jsoneditor": "^1.4.5",
|
||||
"v-tooltip": "^2.1.3",
|
||||
"vue": "^2.7.0",
|
||||
|
|
|
|||
|
|
@ -147,6 +147,7 @@ const app = express()
|
|||
.use(ENDPOINTS.statusCheck, (req, res) => {
|
||||
try {
|
||||
statusCheck(req.url, async (results) => {
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
await res.end(results);
|
||||
});
|
||||
} catch (e) {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
const { exec } = require('child_process');
|
||||
|
||||
module.exports = () => new Promise((resolve, reject) => {
|
||||
const buildProcess = exec('npm run build'); // Trigger the build command
|
||||
const buildProcess = exec('NODE_OPTIONS="--max-old-space-size=512" npm run build'); // Trigger the build command
|
||||
|
||||
let output = ''; // Will store console output
|
||||
|
||||
|
|
|
|||
10
src/App.vue
10
src/App.vue
|
|
@ -155,11 +155,21 @@ export default {
|
|||
e.preventDefault();
|
||||
return 'You may have unsaved edits. Are you sure you want to exit the page?';
|
||||
},
|
||||
/* Detect and apply theme based on OS preference */
|
||||
applyThemeBasedOnOSPreference() {
|
||||
const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
const osTheme = prefersDark ? this.appConfig.nightTheme : this.appConfig.dayTheme;
|
||||
if (osTheme) {
|
||||
this.$store.commit(Keys.SET_THEME, osTheme);
|
||||
this.updateTheme(osTheme);
|
||||
}
|
||||
},
|
||||
},
|
||||
/* Basic initialization tasks on app load */
|
||||
async mounted() {
|
||||
await this.$store.dispatch(Keys.INITIALIZE_CONFIG); // Initialize config before moving on
|
||||
this.applyLanguage(); // Apply users local language
|
||||
this.applyThemeBasedOnOSPreference(); // Apply theme based on OS preference
|
||||
this.hideSplash(); // Hide the splash screen, if visible
|
||||
if (this.appConfig.customCss) { // Inject users custom CSS, if present
|
||||
const cleanedCss = this.appConfig.customCss.replace(/<\/?[^>]+(>|$)/g, '');
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
"home": {
|
||||
"no-results": "Ingen søgeresultater",
|
||||
"no-data": "Ingen data konfigureret",
|
||||
"no-items-section": "Ingen genstander at vise endnu"
|
||||
"no-items-section": "Ingen genstande at vise endnu"
|
||||
},
|
||||
"search": {
|
||||
"search-label": "Søg",
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
"remember-me-hour": "4 timer",
|
||||
"remember-me-day": "1 dag",
|
||||
"remember-me-week": "1 uge",
|
||||
"remember-me-long-time": "en lang tid",
|
||||
"remember-me-long-time": "lang tid",
|
||||
"error-missing-username": "Mangler brugernavn",
|
||||
"error-missing-password": "Manglende adgangskode",
|
||||
"error-incorrect-username": "Bruger ikke fundet",
|
||||
|
|
@ -54,7 +54,7 @@
|
|||
"reset-config-msg-l3": "Er du sikker på at du vil fortsætte?",
|
||||
"data-cleared-msg": "Data blev succesfuldt ryddet",
|
||||
"actions-label": "Handlinger",
|
||||
"copy-config-label": "Kopiera Config",
|
||||
"copy-config-label": "Kopiere Config",
|
||||
"data-copied-msg": "Konfigurationen er blevet kopieret til clipboard",
|
||||
"reset-config-label": "Nulstil konfiguration",
|
||||
"css-save-btn": "Gem ændringer",
|
||||
|
|
@ -95,7 +95,7 @@
|
|||
"language-switcher": {
|
||||
"title": "Skift applikationssprog",
|
||||
"dropdown-label": "Valg en sprog",
|
||||
"save-button": "Gemme",
|
||||
"save-button": "Gem",
|
||||
"success-msg": "Sprog opdateret til"
|
||||
},
|
||||
"theme-maker": {
|
||||
|
|
@ -104,17 +104,17 @@
|
|||
"reset-button": "Nulstil styles for",
|
||||
"show-all-button": "Vis alle variabler",
|
||||
"change-fonts-button": "Skift skrifttyper",
|
||||
"save-button": "Gemme",
|
||||
"cancel-button": "Ophæve",
|
||||
"saved-toast": "{theme} opdateret med succes",
|
||||
"save-button": "Gem",
|
||||
"cancel-button": "Annuller",
|
||||
"saved-toast": "{theme} opdateret succesfuldt",
|
||||
"copied-toast": "Temadata for {theme} kopieret til udklipsholder",
|
||||
"reset-toast": "Tilpassede farver for {theme} fjernet"
|
||||
},
|
||||
"config-editor": {
|
||||
"save-location-label": "Gemme beliggenhed",
|
||||
"location-local-label": "Anbringe lokalt",
|
||||
"save-location-label": "Lokation for gem",
|
||||
"location-local-label": "Gem lokalt",
|
||||
"location-disk-label": "Skriv ændringer til konfigurationsfil",
|
||||
"save-button": "Gemme ændringer",
|
||||
"save-button": "Gem ændringer",
|
||||
"preview-button": "Forhåndsvisning af ændringer",
|
||||
"valid-label": "Konfigurationen er gyldig",
|
||||
"status-success-msg": "Opgave fuldført",
|
||||
|
|
@ -155,7 +155,7 @@
|
|||
"password-label-update": "Skriv dit kodeord",
|
||||
"backup-button-setup": "Sikkerhedskopiering",
|
||||
"backup-button-update": "Opdater sikkerhedskopiering",
|
||||
"backup-id-label": "Din sikkerhedskopi-ID",
|
||||
"backup-id-label": "Dit sikkerhedskopi-ID",
|
||||
"backup-id-note": "Dette bruges til at gendanne fra sikkerhedskopier senere. Så gem det sammen med din adgangskode et sikkert sted.",
|
||||
"restore-title": "Gendan en sikkerhedskopi",
|
||||
"restore-id-label": "Gendan-ID",
|
||||
|
|
@ -165,7 +165,7 @@
|
|||
"backup-error-unknown": "Kan ikke behandle anmodningen",
|
||||
"backup-error-password": "Forkert kodeord. Indtast venligst din nuværende adgangskode.",
|
||||
"backup-success-msg": "Afsluttet med succes",
|
||||
"restore-success-msg": "Konfiguration gendan med succes"
|
||||
"restore-success-msg": "Konfiguration gendannet med succes"
|
||||
},
|
||||
"menu": {
|
||||
"open-section-title": "Åbn i",
|
||||
|
|
@ -174,9 +174,9 @@
|
|||
"modal": "Pop-Up Modal",
|
||||
"workspace": "Arbejdsrumsvisning",
|
||||
"options-section-title": "Muligheder",
|
||||
"edit-item": "Redigere",
|
||||
"edit-item": "Rediger",
|
||||
"move-item": "Kopier eller flyt",
|
||||
"remove-item": "Fjerne"
|
||||
"remove-item": "Fjern"
|
||||
},
|
||||
"context-menus": {
|
||||
"item": {
|
||||
|
|
@ -187,14 +187,14 @@
|
|||
"workspace": "Arbejdsrumsvisning",
|
||||
"clipboard": "Kopier til udklipsholder",
|
||||
"options-section-title": "Muligheder",
|
||||
"edit-item": "Redigere",
|
||||
"edit-item": "Rediger",
|
||||
"move-item": "Kopier eller flyt",
|
||||
"remove-item": "Fjerne",
|
||||
"copied-toast": "URL er blevet kopieret til udklipsholder"
|
||||
},
|
||||
"section": {
|
||||
"open-section": "Åbn sektion",
|
||||
"edit-section": "Redigere",
|
||||
"edit-section": "Rediger",
|
||||
"expand-collapse": "Udvid / Skjul",
|
||||
"move-section": "Flytte til",
|
||||
"remove-section": "Fjerne"
|
||||
|
|
@ -206,35 +206,35 @@
|
|||
"edit-site-data-subheading": "Rediger webstedsdata",
|
||||
"edit-page-info-btn": "Rediger sideoplysninger",
|
||||
"edit-page-info-tooltip": "Apptitel, beskrivelse, navigationslinks, sidefodstekst osv.",
|
||||
"edit-app-config-btn": "Redigere appkonfiguration",
|
||||
"edit-app-config-btn": "Rediger appkonfiguration",
|
||||
"edit-app-config-tooltip": "Alle andre appkonfigurationsmuligheder",
|
||||
"edit-pages-btn": "Redigere sider",
|
||||
"edit-pages-btn": "Rediger sider",
|
||||
"edit-pages-tooltip": "Tilføj eller fjern yderligere visninger",
|
||||
"config-save-methods-subheading": "Indstillinger for lagring af konfiguration",
|
||||
"save-locally-btn": "Gemme lokalt",
|
||||
"save-locally-btn": "Gem lokalt",
|
||||
"save-locally-tooltip": "Gem konfigurationen lokalt i browserlageret. Dette vil ikke påvirke din konfigurationsfil, men ændringer vil kun blive gemt på denne enhed",
|
||||
"save-disk-btn": "Gemme til disk",
|
||||
"save-disk-btn": "Gem til disk",
|
||||
"save-disk-tooltip": "Gem konfigurationen i filen conf.yml på disken. Dette vil sikkerhedskopiere og derefter overskrive din eksisterende konfiguration",
|
||||
"export-config-btn": "Exportere konfiguration",
|
||||
"export-config-btn": "Exporter konfiguration",
|
||||
"export-config-tooltip": "Se og eksporter ny konfiguration, enten til en fil eller til udklipsholder",
|
||||
"cloud-backup-btn": "Sikkerhedskopier til cloud",
|
||||
"cloud-backup-tooltip": "Gem krypteret backup af konfiguration til cloud",
|
||||
"edit-raw-config-btn": "Rediger rå konfiguration",
|
||||
"edit-raw-config-tooltip": "Se og rediger rå config via JSON-editor",
|
||||
"cancel-changes-btn": "Avbryd redigering",
|
||||
"cancel-changes-btn": "Afbryd redigering",
|
||||
"cancel-changes-tooltip": "Nulstil aktuelle ændringer, og afslut redigeringstilstand. Dette vil ikke påvirke din gemte konfiguration",
|
||||
"edit-mode-name": "Redigeringstilstand",
|
||||
"edit-mode-subtitle": "Du er i redigeringstilstand",
|
||||
"edit-mode-description": "Det betyder, at du kan foretage ændringer i din konfiguration og se resultaterne, men indtil du gemmer, vil ingen af dine ændringer blive bevaret.",
|
||||
"save-stage-btn": "Gemme",
|
||||
"cancel-stage-btn": "Avbryd",
|
||||
"save-stage-btn": "Gem",
|
||||
"cancel-stage-btn": "Afbryd",
|
||||
"save-locally-warning": "Hvis du fortsætter, vil ændringer kun blive gemt i din browser. Du bør eksportere en kopi af din konfiguration til brug på andre maskiner. Vil du fortsætte?"
|
||||
},
|
||||
"edit-item": {
|
||||
"missing-title-err": "En varetitel er påkrævet"
|
||||
},
|
||||
"edit-section": {
|
||||
"edit-section-title": "Redigere sektion",
|
||||
"edit-section-title": "Rediger sektion",
|
||||
"add-section-title": "Tilføj ny sektion",
|
||||
"edit-tooltip": "Klik for at redigere, eller højreklik for at få flere muligheder",
|
||||
"remove-confirm": "Er du sikker på, at du vil fjerne denne sektion? Denne handling kan fortrydes senere."
|
||||
|
|
@ -273,11 +273,11 @@
|
|||
"cpu-chart-title": "CPU-historie",
|
||||
"mem-chart-title": "Hukommelsesbrug",
|
||||
"mem-breakdown-title": "Hukommelsesnedbrydning",
|
||||
"load-chart-title": "Systeminlæsning"
|
||||
"load-chart-title": "Systemindlæsning"
|
||||
},
|
||||
"glances": {
|
||||
"disk-space-free": "Ledig",
|
||||
"disk-space-used": "I bruk",
|
||||
"disk-space-used": "I brug",
|
||||
"disk-mount-point": "Mount Point",
|
||||
"disk-file-system": "Filsystem",
|
||||
"disk-io-read": "Læs",
|
||||
|
|
@ -329,7 +329,7 @@
|
|||
"disk-space": "Diskudrymme",
|
||||
"dnd": "Forstyr ikke",
|
||||
"email": "email",
|
||||
"enabled": "aktivert",
|
||||
"enabled": "aktiveret",
|
||||
"federated-shares-ucfirst": "Fødereret deler",
|
||||
"federated-shares": "fødereret deler",
|
||||
"files": "fil{plural}",
|
||||
|
|
@ -363,7 +363,7 @@
|
|||
"other": "andet",
|
||||
"overall": "Samlet set",
|
||||
"private-link": "privat link",
|
||||
"public-link": "publik link",
|
||||
"public-link": "offentlig link",
|
||||
"quota-enabled": "Diskkvote er {not} aktiveret for denne bruger",
|
||||
"received": "modtaget",
|
||||
"scripts": "scripts",
|
||||
|
|
@ -371,7 +371,7 @@
|
|||
"started": "Startede",
|
||||
"storages-by-type": "Opbevaring efter type",
|
||||
"storages": "Opbevaring{plural}",
|
||||
"strings-use": "strings brug",
|
||||
"strings-use": "tråde brug",
|
||||
"tasks": "Opgaver",
|
||||
"total-files": "samlede filer",
|
||||
"total-users": "samlede bruger",
|
||||
|
|
@ -379,7 +379,7 @@
|
|||
"until": "Så længe",
|
||||
"updates-available-for": "Opdateringer er tilgængelige for",
|
||||
"updates-available": "opdatering{plural} tilgængelig",
|
||||
"used": "brugd",
|
||||
"used": "brugt",
|
||||
"user": "bruger",
|
||||
"using": "ved brug af",
|
||||
"version": "version",
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"home": {
|
||||
"no-results": "Ingen søkeresultater",
|
||||
"no-data": "Ingen data konfigurert"
|
||||
"no-data": "Ingen data tilgjengelig"
|
||||
},
|
||||
"search": {
|
||||
"search-label": "Søk",
|
||||
|
|
@ -43,7 +43,7 @@
|
|||
"cloud-sync-button": "Aktiver skysynkronisering",
|
||||
"edit-cloud-sync-button": "Rediger skysynkronisering",
|
||||
"rebuild-app-button": "Bygg program",
|
||||
"change-language-button": "Endre appspråk",
|
||||
"change-language-button": "Endre språk",
|
||||
"reset-settings-button": "Tilbakestill lokale innstillinger",
|
||||
"app-info-button": "Appinfo",
|
||||
"backup-note": "Det anbefales å ta en sikkerhetskopi av konfigurasjonen din før du gjør endringer.",
|
||||
|
|
@ -91,7 +91,7 @@
|
|||
"unsupported-version-l2": "For den beste opplevelsen og de siste sikkerhetsoppdateringene, vennligst oppdater til"
|
||||
},
|
||||
"language-switcher": {
|
||||
"title": "Endre applikasjonsspråk",
|
||||
"title": "Endre språk",
|
||||
"dropdown-label": "Velg et språk",
|
||||
"save-button": "Lagre",
|
||||
"success-msg": "Språk oppdatert til"
|
||||
|
|
@ -115,7 +115,7 @@
|
|||
"valid-label": "Konfigurasjon er gyldig",
|
||||
"status-success-msg": "Oppgaven fullført",
|
||||
"status-fail-msg": "Oppgaven mislyktes",
|
||||
"success-msg-disk": "Konfigurasjonsfil skrevet til disk med hell",
|
||||
"success-msg-disk": "Konfigurasjonsfil skrevet til disk vellykket",
|
||||
"success-msg-local": "Lokale endringer er lagret",
|
||||
"success-note-l1": "Appen bør bygge om automatisk.",
|
||||
"success-note-l2": "Dette kan ta opptil et minutt.",
|
||||
|
|
@ -131,10 +131,10 @@
|
|||
"rebuild-note-l1": "En ombygging er nødvendig for at endringer skrevet i conf.yml-filen skal tre i kraft.",
|
||||
"rebuild-note-l2": "Dette bør skje automatisk, men hvis det ikke har blitt gjort, kan du manuelt utløse det her.",
|
||||
"rebuild-note-l3": "Dette er ikke nødvendig for endringer som er lagret lokalt.",
|
||||
"rebuild-button": "Start Build",
|
||||
"rebuilding-status-1": "Building ...",
|
||||
"rebuild-button": "Start Bygging",
|
||||
"rebuilding-status-1": "Bygger ...",
|
||||
"rebuilding-status-2": "Dette kan ta noen minutter",
|
||||
"error-permission": "Du har ikke tillatelse til å utløse denne handlingen",
|
||||
"error-permission": "Du har ikke tillatelse til å utføre denne handlingen",
|
||||
"success-msg": "Byggingen er fullført",
|
||||
"fail-msg": "Byggoperasjonen mislyktes",
|
||||
"reload-note": "En sideinnlasting er nå nødvendig for at endringer skal tre i kraft",
|
||||
|
|
|
|||
|
|
@ -1,50 +1,96 @@
|
|||
{
|
||||
"home": {
|
||||
"no-results": "Нет Результатов Поиска",
|
||||
"no-data": "Данные не настроены"
|
||||
"no-results": "Нет результатов",
|
||||
"no-data": "Данные не настроены",
|
||||
"no-items-section": "Данные загружаются"
|
||||
},
|
||||
"search": {
|
||||
"search-label": "Поиск",
|
||||
"search-placeholder": "Начните вводить, чтобы отфильтровать",
|
||||
"clear-search-tooltip": "Очистить поиск",
|
||||
"search-placeholder": "Начните вводить фильтр",
|
||||
"clear-search-tooltip": "Очистить",
|
||||
"enter-to-search-web": "Нажмите \"Ввод\" для поиска в Интернете"
|
||||
},
|
||||
"splash-screen": {
|
||||
"loading": "Загрузка"
|
||||
},
|
||||
"login": {
|
||||
"title": "Даши",
|
||||
"title": "Dashy",
|
||||
"guest-label": "Гостевой доступ",
|
||||
"username-label": "Имя пользователя",
|
||||
"password-label": "Пароль",
|
||||
"login-button": "Авторизоваться",
|
||||
"remember-me-label": "Помни меня за",
|
||||
"login-button": "Войти",
|
||||
"remember-me-label": "Запомнить меня на",
|
||||
"remember-me-never": "Никогда",
|
||||
"remember-me-hour": "4 часа",
|
||||
"remember-me-day": "1 день",
|
||||
"remember-me-week": "1 неделя",
|
||||
"remember-me-week": "1 неделю",
|
||||
"remember-me-long-time": "Надолго",
|
||||
"error-missing-username": "Отсутствует имя пользователя",
|
||||
"error-missing-password": "Отсутствует пароль",
|
||||
"error-incorrect-username": "Пользователь не найден",
|
||||
"error-incorrect-password": "Неверный пароль",
|
||||
"success-message": "Вход в систему...",
|
||||
"logout-message": "Вышли из",
|
||||
"already-logged-in-title": "Уже вошли в систему",
|
||||
"logout-message": "Вы вышли из системы",
|
||||
"already-logged-in-title": "Вы уже вошли в систему",
|
||||
"already-logged-in-text": "Вы вошли как",
|
||||
"proceed-to-dashboard": "Перейти на панель управления",
|
||||
"proceed-to-dashboard": "Перейти к панели управления",
|
||||
"log-out-button": "Выйти",
|
||||
"proceed-guest-button": "Продолжить как гость"
|
||||
"proceed-guest-button": "Продолжить как гость",
|
||||
"guest-intro-1": "Этот экземпляр приложения имеет гостевой доступ.",
|
||||
"guest-intro-2": "Гости имеют имеют доступ к панелям управления только для чтения, так что они не могут записать изменения на диск.",
|
||||
"error": "Ошибка",
|
||||
"error-no-user-configured": "Аутентификация отключена или не было настроено ни одного пользователя.",
|
||||
"error-go-home-button": "Домой",
|
||||
"logged-in-guest": "Вы вошли как гость, переадресация...",
|
||||
"error-guest-access": "Гостевой доступ запрещён"
|
||||
},
|
||||
"app-info": {
|
||||
"title": "Информация о Приложении",
|
||||
"error-log": "Журнал Ошибок",
|
||||
"no-errors": "Ошибок не зафиксировано",
|
||||
"help-support": "Помощь и Поддержка",
|
||||
"help-support-description" : "Для получения поддержки в запуске и настройке Dashy, обратитесь за помощью на",
|
||||
"help-support-discussions": "страницу Discussions",
|
||||
"support-dashy": "Поддержать Dashy",
|
||||
"support-dashy-description": "Если вы хотите поддержать проект, пожалуйста посетите страницу",
|
||||
"support-dashy-link": "Contributions",
|
||||
"report-bug": "Сообщить об ошибке",
|
||||
"report-bug-description": "Если вы считаете, что нашли ошибку, пожалуйста",
|
||||
"report-bug-link": "сообщите о проблеме",
|
||||
"more-info": "Больше информации",
|
||||
"source": "Исходный код",
|
||||
"documentation": "Документация",
|
||||
"privacy-and-security": "Приватность и Безопасность",
|
||||
"privacy-and-security-l1": "Для получения подробной информации о том, как Dashy управляет вашими данными, см.",
|
||||
"privacy-and-security-privacy-policy": "Политика Приватности",
|
||||
"privacy-and-security-advice": "Для получения рекомендаций по обеспечению безопасности вашей панели управления вы можете обратиться к",
|
||||
"privacy-and-security-advice-link": "Документации по Управлению",
|
||||
"privacy-and-security-security-issue": "Если вы обнаружили потенциальную проблему безопасности, сообщите о ней, в соответствии с нашей",
|
||||
"privacy-and-security-security-policy": "Политикой Безопасности",
|
||||
"license": "Лицензия",
|
||||
"license-under": "Лицензировано под",
|
||||
"licence-third-party": "Лицензии на модули сторонних производителей см.",
|
||||
"licence-third-party-link": "Legal",
|
||||
"list-contributors": "Чтобы посмотреть полный список авторов и благодарностей, см.",
|
||||
"list-contributors-link": "Credits",
|
||||
"version": "Версия"
|
||||
},
|
||||
"config": {
|
||||
"main-tab": "Главное меню",
|
||||
"view-config-tab": "Просмотр конфигурации",
|
||||
"view-config-tab": "Посмотреть конфигурацию",
|
||||
"edit-config-tab": "Изменить конфигурацию",
|
||||
"custom-css-tab": "Пользовательские стили",
|
||||
"custom-css-tab": "Пользовательский CSS",
|
||||
"heading": "Варианты конфигурации",
|
||||
"download-config-button": "Скачать конфигурацию",
|
||||
"edit-config-button": "Изменить конфигурацию",
|
||||
"edit-css-button": "Редактировать собственный CSS",
|
||||
"edit-css-button": "Редактировать пользовательский CSS",
|
||||
"cloud-sync-button": "Включить облачную синхронизацию",
|
||||
"edit-cloud-sync-button": "Изменить Cloud Sync",
|
||||
"rebuild-app-button": "Восстановить приложение",
|
||||
"change-language-button": "Изменить язык приложения",
|
||||
"edit-cloud-sync-button": "Изменить облачную синхронизацию",
|
||||
"rebuild-app-button": "Пересобрать приложение",
|
||||
"change-language-button": "Выбрать язык",
|
||||
"reset-settings-button": "Сбросить локальные настройки",
|
||||
"disabled-note": "Некоторые пункты конфигурации были отключены вашим администратором",
|
||||
"small-screen-note": "Вы используете слишком маленький дисплей, некоторые страницы могут не быть оптимальны",
|
||||
"app-info-button": "Информация о приложении",
|
||||
"backup-note": "Перед внесением изменений рекомендуется сделать резервную копию вашей конфигурации.",
|
||||
"reset-config-msg-l1": "Это удалит все пользовательские настройки из локального хранилища, но не повлияет на ваш файл conf.yml.",
|
||||
|
|
@ -52,69 +98,77 @@
|
|||
"reset-config-msg-l3": "Вы уверены, что хотите продолжить?",
|
||||
"data-cleared-msg": "Данные успешно очищены",
|
||||
"actions-label": "Действия",
|
||||
"copy-config-label": "Копировать конфигурацию",
|
||||
"copy-config-label": "Скопировать конфигурацию",
|
||||
"data-copied-msg": "Конфиг скопирован в буфер обмена",
|
||||
"reset-config-label": "Сбросить конфигурацию",
|
||||
"css-save-btn": "Сохранить изменения",
|
||||
"css-note-label": "Примечание",
|
||||
"css-note-l1": "Вам нужно будет обновить страницу, чтобы изменения вступили в силу.",
|
||||
"css-note-l2": "Переопределения стилей хранятся только локально, поэтому рекомендуется сделать копию вашего CSS.",
|
||||
"css-note-l3": "Чтобы удалить все пользовательские стили, удалите содержимое и нажмите «Сохранить изменения»."
|
||||
"css-note-l3": "Чтобы удалить все пользовательские стили, удалите содержимое и нажмите «Сохранить изменения».",
|
||||
"custom-css": {
|
||||
"title": "Пользовательский CSS",
|
||||
"base-theme": "Базовая Тема"
|
||||
}
|
||||
},
|
||||
"alternate-views": {
|
||||
"alternate-view-heading": "Переключить вид",
|
||||
"default": "Дефолт",
|
||||
"default": "По умолчанию",
|
||||
"workspace": "Рабочая среда",
|
||||
"minimal": "Минимальный"
|
||||
},
|
||||
"settings": {
|
||||
"theme-label": "Тема",
|
||||
"layout-label": "Макет",
|
||||
"layout-label": "Сетка",
|
||||
"layout-auto": "Авто",
|
||||
"layout-horizontal": "По горизонтали",
|
||||
"layout-vertical": "Вертикальный",
|
||||
"layout-horizontal": "Горизонтальная",
|
||||
"layout-vertical": "Вертикальная",
|
||||
"item-size-label": "Размер элемента",
|
||||
"item-size-small": "Небольшой",
|
||||
"item-size-medium": "Середина",
|
||||
"item-size-small": "Маленький",
|
||||
"item-size-medium": "Средний",
|
||||
"item-size-large": "Большой",
|
||||
"config-launcher-label": "Конфиг",
|
||||
"config-launcher-tooltip": "Обновить конфигурацию",
|
||||
"config-launcher-label": "Конфигурация",
|
||||
"config-launcher-tooltip": "Редактировать конфигурацию",
|
||||
"sign-out-tooltip": "Выход",
|
||||
"sign-in-tooltip": "Авторизоваться",
|
||||
"sign-in-welcome": "Здравствуйте, {username}!"
|
||||
"sign-in-welcome": "Здравствуйте, {username}!",
|
||||
"hide": "Скрыть",
|
||||
"open": "Открыть"
|
||||
},
|
||||
"updates": {
|
||||
"app-version-note": "Даши версия",
|
||||
"up-to-date": "Своевременно",
|
||||
"app-version-note": "Dashy версия",
|
||||
"up-to-date": "Последняя версия",
|
||||
"out-of-date": "Доступно обновление",
|
||||
"unsupported-version-l1": "Вы используете неподдерживаемую версию Dashy",
|
||||
"unsupported-version-l2": "Для оптимальной работы и получения последних исправлений безопасности, пожалуйста, обновите до"
|
||||
"unsupported-version-l2": "Для оптимальной работы и получения последних исправлений безопасности, пожалуйста, обновите приложение до версии"
|
||||
},
|
||||
"language-switcher": {
|
||||
"title": "Изменить язык приложения",
|
||||
"title": "Выбрать язык приложения",
|
||||
"dropdown-label": "Выберите язык",
|
||||
"save-button": "Сохранить",
|
||||
"success-msg": "Язык обновлен до"
|
||||
"success-msg": "Выбран язык: "
|
||||
},
|
||||
"theme-maker": {
|
||||
"title": "Конфигуратор темы",
|
||||
"export-button": "Экспорт пользовательских переменных",
|
||||
"reset-button": "Сбросить стили для",
|
||||
"reset-button": "Сбросить стили для темы",
|
||||
"show-all-button": "Показать все переменные",
|
||||
"change-fonts-button": "Выбрать шрифты",
|
||||
"save-button": "Сохранить",
|
||||
"cancel-button": "Отмена",
|
||||
"saved-toast": "{theme} Обновлено успешно",
|
||||
"copied-toast": "Данные темы для {theme} скопированы в буфер обмена",
|
||||
"reset-toast": "Пользовательские цвета для {theme} удалены"
|
||||
"saved-toast": "Тема {theme} успешно обновлена",
|
||||
"copied-toast": "Данные для темы {theme} скопированы в буфер обмена",
|
||||
"reset-toast": "Пользовательские цвета для темы {theme} удалены"
|
||||
},
|
||||
"config-editor": {
|
||||
"save-location-label": "Сохранить местоположение",
|
||||
"location-local-label": "Применять локально",
|
||||
"location-disk-label": "Запись изменений в файл конфигурации",
|
||||
"save-location-label": "Место сохранения",
|
||||
"location-local-label": "Применить локально",
|
||||
"location-disk-label": "Записать изменения в файл конфигурации на диск",
|
||||
"save-button": "Сохранить изменения",
|
||||
"valid-label": "Конфигурация действительна",
|
||||
"preview-button": "Предпросмотр",
|
||||
"valid-label": "Конфигурация верна",
|
||||
"status-success-msg": "Задача завершена",
|
||||
"status-fail-msg": "Сбой задачи",
|
||||
"status-fail-msg": "Задача была провалена",
|
||||
"success-msg-disk": "Файл конфигурации успешно записан на диск",
|
||||
"success-msg-local": "Локальные изменения успешно сохранены",
|
||||
"success-note-l1": "Приложение должно перестроиться автоматически.",
|
||||
|
|
@ -123,38 +177,39 @@
|
|||
"error-msg-save-mode": "Пожалуйста, выберите режим сохранения: локальный или файл",
|
||||
"error-msg-cannot-save": "Произошла ошибка при сохранении конфигурации",
|
||||
"error-msg-bad-json": "Ошибка в JSON, возможно, неверный формат",
|
||||
"warning-msg-validation": "Предупреждение о проверке",
|
||||
"warning-msg-validation": "Предупреждение валидатора",
|
||||
"not-admin-note": "Вы не можете записать измененные на диск, потому что вы не вошли в систему как администратор"
|
||||
},
|
||||
"app-rebuild": {
|
||||
"title": "Восстановить приложение",
|
||||
"rebuild-note-l1": "Чтобы изменения, записанные в файл conf.yml, вступили в силу, требуется перестройка.",
|
||||
"rebuild-note-l2": "Это должно произойти автоматически, но если этого не произошло, вы можете запустить это вручную здесь.",
|
||||
"rebuild-note-l3": "Это не требуется для изменений, хранящихся локально.",
|
||||
"title": "Пересобрать приложение",
|
||||
"rebuild-note-l1": "Чтобы изменения, записанные в файл conf.yml, вступили в силу, требуется пересборка.",
|
||||
"rebuild-note-l2": "Это должно произойти автоматически, но если этого не произошло, вы можете запустить её вручную здесь.",
|
||||
"rebuild-note-l3": "Заметьте, что эта функция доступна только для экземпляров приложения, которые запущены с помощью Node или Docker, но не для тех, которые запущенны статично",
|
||||
"rebuild-button": "Начать сборку",
|
||||
"rebuilding-status-1": "Строительство...",
|
||||
"rebuilding-status-1": "Сборка...",
|
||||
"rebuilding-status-2": "Это может занять несколько минут",
|
||||
"error-permission": "У вас нет разрешения запускать это действие",
|
||||
"error-permission": "У вас нет разрешения на запуск этого действия",
|
||||
"success-msg": "Сборка успешно завершена",
|
||||
"fail-msg": "Не удалось выполнить операцию сборки",
|
||||
"reload-note": "Теперь требуется перезагрузка страницы, чтобы изменения вступили в силу.",
|
||||
"reload-note": "Теперь нужно перезагрузить страницу, чтобы изменения вступили в силу.",
|
||||
"reload-button": "Перезагрузить страницу"
|
||||
},
|
||||
"cloud-sync": {
|
||||
"title": "Резервное копирование и восстановление в облаке",
|
||||
"intro-l1": "Резервное копирование и восстановление в облако - это дополнительная функция, которая позволяет вам загрузить свою конфигурацию в Интернет, а затем восстановить ее на любом другом устройстве или экземпляре Dashy.",
|
||||
"intro-l2": "Все данные полностью зашифрованы с помощью AES с использованием вашего пароля в качестве ключа.",
|
||||
"title": "Облачная конфигурация",
|
||||
"intro-l1": "Облачная конфигурация - это дополнительная функция, которая позволяет вам загрузить свою конфигурацию в Интернет, а затем восстановить ее на любом другом устройстве или экземпляре Dashy.",
|
||||
"intro-l2": "Все данные полностью зашифрованы с помощью сквозного шифрования, используя AES и ваш пароль в качестве ключа.",
|
||||
"intro-l3": "Для получения дополнительной информации см.",
|
||||
"backup-title-setup": "Сделать резервную копию",
|
||||
"intro-docs": "документацию",
|
||||
"backup-title-setup": "Создать резервную копию",
|
||||
"backup-title-update": "Обновить резервную копию",
|
||||
"password-label-setup": "Выберите пароль",
|
||||
"password-label-update": "Введите ваш пароль",
|
||||
"backup-button-setup": "Резервное копирование",
|
||||
"backup-button-setup": "Создать резервную копию",
|
||||
"backup-button-update": "Обновить резервную копию",
|
||||
"backup-id-label": "Ваш резервный идентификатор",
|
||||
"backup-id-note": "Это используется для восстановления из резервных копий позже. Так что храните его вместе со своим паролем в надежном месте.",
|
||||
"backup-id-note": "Он используется для восстановления из резервных копий позже. Так что сохраните его вместе со своим паролем в надежном месте.",
|
||||
"restore-title": "Восстановить резервную копию",
|
||||
"restore-id-label": "Восстановить ID",
|
||||
"restore-id-label": "Восстановить резервный идентификатор",
|
||||
"restore-password-label": "Пароль",
|
||||
"restore-button": "Восстановить",
|
||||
"backup-missing-password": "Отсутствует пароль",
|
||||
|
|
@ -164,9 +219,167 @@
|
|||
"restore-success-msg": "Конфигурация успешно восстановлена"
|
||||
},
|
||||
"menu": {
|
||||
"sametab": "Открыть в текущей вкладке",
|
||||
"newtab": "Открыть в новой вкладке",
|
||||
"modal": "Открыть в модальном всплывающем окне",
|
||||
"workspace": "Открыть в представлении рабочей области"
|
||||
"open-section-title": "Открыть в",
|
||||
"sametab": "Текущей вкладке",
|
||||
"newtab": "Новой вкладке",
|
||||
"modal": "Всплывающем окне",
|
||||
"workspace": "Рабочей области",
|
||||
"options-section-title": "Настройки",
|
||||
"edit-item": "Редактировать",
|
||||
"move-item": "Скопировать или переместить",
|
||||
"remove-item": "Удалить"
|
||||
},
|
||||
"context-menus": {
|
||||
"item": {
|
||||
"open-section-title": "Открыть в",
|
||||
"sametab": "Текущей вкладке",
|
||||
"newtab": "Новой вкладке",
|
||||
"modal": "Всплывающем окне",
|
||||
"workspace": "Рабочей области",
|
||||
"clipboard": "Копировать в буфер обмена",
|
||||
"options-section-title": "Настройки",
|
||||
"edit-item": "Редактировать",
|
||||
"move-item": "Скопировать или переместить",
|
||||
"remove-item": "Удалить",
|
||||
"copied-toast": "Ссылка была скопирована в буфер обмена"
|
||||
},
|
||||
"section": {
|
||||
"open-section": "Открыть секцию",
|
||||
"edit-section": "Редактировать",
|
||||
"expand-collapse": "Раскрыть / Свернуть",
|
||||
"move-section": "Переместить в",
|
||||
"remove-section": "Удалить"
|
||||
}
|
||||
},
|
||||
"footer": {
|
||||
"dev-by": "Разработано ",
|
||||
"licensed-under": "Лицензировано под",
|
||||
"get-the": "Получите",
|
||||
"source-code": "Исходный код"
|
||||
},
|
||||
"interactive-editor": {
|
||||
"menu": {
|
||||
"start-editing-tooltip": "Войти в режим редактирования",
|
||||
"edit-site-data-subheading": "Редактировать параметры сайта",
|
||||
"edit-page-info-btn": "Редактировать страницу",
|
||||
"edit-page-info-tooltip": "Заголовок приложения, описание, ссылки, текст снизу страницы и т. д.",
|
||||
"edit-app-config-btn": "Редактировать конфигурацию",
|
||||
"edit-app-config-tooltip": "Конфигурация всего остального приложения",
|
||||
"edit-pages-btn": "Редактировать страницы",
|
||||
"edit-pages-tooltip": "Добавить или удалить дополнительные страницы панели управления",
|
||||
"config-save-methods-subheading": "Сохранить конфигурацию",
|
||||
"save-locally-btn": "Локально",
|
||||
"save-locally-tooltip": "Сохранить конфигурацию локально, в хранилище браузера. Это не повлияет на ваш конфигурационный файл на диске, но изменения останутся на этом устройстве",
|
||||
"save-disk-btn": "На диск",
|
||||
"save-disk-tooltip": "Сначала создастся резервная копия текущей конфигурации, а затем она перезапишется новой версией",
|
||||
"export-config-btn": "Экспорт конфигурации",
|
||||
"export-config-tooltip": "Просмотреть и экспортировать новую конфигурацию, либо как файл, либо в буфер обмена",
|
||||
"cloud-backup-btn": "Облачное сохранение",
|
||||
"cloud-backup-tooltip": "Сохранить зашифрованный файл конфигурации в облачное хранилище",
|
||||
"edit-raw-config-btn": "Редактировать JSON конфигурации",
|
||||
"edit-raw-config-tooltip": "Просмотреть и редактировать файл конфигурации напрямую, через редактор JSON",
|
||||
"cancel-changes-btn": "Сбросить изменения",
|
||||
"cancel-changes-tooltip": "Сбросить текущие изменения и выйти из режима редактирования. Это не изменит сохранённую конфигурацию",
|
||||
"edit-mode-name": "Режим редактирования",
|
||||
"edit-mode-subtitle": "Вы находитесь в режиме редактирования",
|
||||
"edit-mode-description": "Это означает, что вы сможете делать изменения вашей конфигурации и просматривать их результат, но они не вступят в силу, пока вы не сохраните их",
|
||||
"save-stage-btn": "Сохранить",
|
||||
"cancel-stage-btn": "Отмена",
|
||||
"save-locally-warning": "Если вы продолжите, изменения будут сохранены только в вашем браузере. Чтобы использовать новую конфигурацию на других устройствах, экспортируйте её. Продолжить?"
|
||||
},
|
||||
"edit-item": {
|
||||
"missing-title-err": "Отсутствует заголовок элемента"
|
||||
},
|
||||
"edit-section": {
|
||||
"edit-section-title": "Редактировать секцию",
|
||||
"add-section-title": "Добавить новую секцию",
|
||||
"edit-tooltip": "Нажмите ЛКМ, чтобы редактировать или ПКМ для дополнительных опций",
|
||||
"remove-confirm": "Вы уверены, что хотите удалить эту секцию? Это действие можно отменить позже"
|
||||
},
|
||||
"edit-app-config": {
|
||||
"warning-msg-title": "Продолжайте с осторожностью",
|
||||
"warning-msg-l1": "Следующие настройки предназначены для продвинутой настройки приложения.",
|
||||
"warning-msg-l2": "Если вы сомневаетесь в том, что значит то или иное поле, пожалуйста ознакомьтесь с",
|
||||
"warning-msg-docs": "документацией",
|
||||
"warning-msg-l3": "для избежания непредвиденных последствий."
|
||||
},
|
||||
"export": {
|
||||
"export-title": "Экспорт конфигурации",
|
||||
"copy-clipboard-btn": "Скопировано в буфер обмена",
|
||||
"copy-clipboard-tooltip": "Скопировать всю конфигурацию приложения, в формате YAML",
|
||||
"download-file-btn": "Скачать как файл",
|
||||
"download-file-tooltip": "Скачать файл конфигурации на ваше устройство в формате YAML",
|
||||
"view-title": "Просмотреть конфигурацию"
|
||||
}
|
||||
},
|
||||
"critical-error": {
|
||||
"title": "Ошибка загрузки конфигурации",
|
||||
"subtitle": "Приложение не смогло загрузиться из-за ошибки в конфигурации.",
|
||||
"sub-ensure-that": "Удостоверьтесь, что",
|
||||
"sub-error-details": "Сведения об ошибке",
|
||||
"sub-next-steps": "Следующие шаги",
|
||||
"ignore-button": "Игнорировать критические ошибки"
|
||||
},
|
||||
"widgets": {
|
||||
"general": {
|
||||
"loading": "Загрузка...",
|
||||
"show-more": "Развернуть сведения",
|
||||
"cpu-details": "Сведения о ЦПУ",
|
||||
"mem-details": "Сведения о памяти",
|
||||
"show-less": "Показать меньше",
|
||||
"open-link": "Продолжить чтение"
|
||||
},
|
||||
"pi-hole": {
|
||||
"status-heading": "Статус"
|
||||
},
|
||||
"stat-ping": {
|
||||
"up": "Онлайн",
|
||||
"down": "Оффлайн"
|
||||
},
|
||||
"net-data": {
|
||||
"cpu-chart-title": "История ЦПУ",
|
||||
"mem-chart-title": "Использование памяти",
|
||||
"mem-breakdown-title": "Подробности об использовании памяти",
|
||||
"load-chart-title": "Нагрузка системы"
|
||||
},
|
||||
"glances": {
|
||||
"disk-space-free": "Свободно",
|
||||
"disk-space-used": "Использовано",
|
||||
"disk-mount-point": "Путь монитрования",
|
||||
"disk-file-system": "Файловая система",
|
||||
"disk-io-read": "Чтение",
|
||||
"disk-io-write": "Запись",
|
||||
"system-load-desc": "Количество процессов, ожидающих в очереди запуска, усреднённое между всеми ядрами процессора"
|
||||
},
|
||||
"system-info": {
|
||||
"uptime": "Время работы"
|
||||
},
|
||||
"flight-data": {
|
||||
"arrivals": "Прибытия",
|
||||
"departures": "Отправления"
|
||||
},
|
||||
"tfl-status": {
|
||||
"good-service-all": "Хорошее обслуживание на всех линиях",
|
||||
"good-service-rest": "Хорошее обслуживание на всех остальных линиях"
|
||||
},
|
||||
"synology-download": {
|
||||
"download": "Скачивание",
|
||||
"upload": "Загрузка",
|
||||
"downloaded": "Скачано",
|
||||
"uploaded": "Загружено",
|
||||
"remaining": "Остаётся",
|
||||
"up": "Вверх",
|
||||
"down": "Вниз"
|
||||
},
|
||||
"gluetun-status": {
|
||||
"vpn-ip": "VPN IP",
|
||||
"country": "Страна",
|
||||
"region": "Регион",
|
||||
"city": "Город",
|
||||
"post-code": "Индекс",
|
||||
"location": "Местоположение",
|
||||
"timezone": "Часовой пояс",
|
||||
"organization": "Организация"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,9 @@
|
|||
"clear-search-tooltip":"Rensa sök",
|
||||
"enter-to-search-web":"Tryck på retur för att söka på webben"
|
||||
},
|
||||
"splash-screen": {
|
||||
"loading": "Laddar"
|
||||
},
|
||||
"login":{
|
||||
"title":"Dashy",
|
||||
"username-label":"Användarnamn",
|
||||
|
|
@ -83,7 +86,9 @@
|
|||
"config-launcher-tooltip":"Uppdatera konfiguration",
|
||||
"sign-out-tooltip":"Logga ut",
|
||||
"sign-in-tooltip":"Logga in",
|
||||
"sign-in-welcome":"Hej {username}!"
|
||||
"sign-in-welcome":"Hej {username}!",
|
||||
"hide": "Göm",
|
||||
"open": "Öppna"
|
||||
},
|
||||
"updates":{
|
||||
"app-version-note":"Dashy-version",
|
||||
|
|
@ -185,14 +190,17 @@
|
|||
"newtab":"Ny flik",
|
||||
"modal":"Pop-Up Modal",
|
||||
"workspace":"Workspace View",
|
||||
"clipboard": "Kopiera till urklipp",
|
||||
"options-section-title":"Alternativ",
|
||||
"edit-item":"Redigera",
|
||||
"move-item":"Kopiera eller flytta",
|
||||
"remove-item":"Ta bort"
|
||||
"remove-item":"Ta bort",
|
||||
"copied-toast": "URLen har blivit kopierad till urklipp"
|
||||
},
|
||||
"section":{
|
||||
"open-section":"Öppna sektion",
|
||||
"edit-section":"Redigera",
|
||||
"expand-collapse": "Expandera / Minimera",
|
||||
"move-section":"Flytta till",
|
||||
"remove-section":"Ta bort"
|
||||
}
|
||||
|
|
@ -205,6 +213,8 @@
|
|||
"edit-page-info-tooltip":"Appnamn, beskrivning, navigeringslänkar, sidfotstext, etc",
|
||||
"edit-app-config-btn":"Redigera appkonfiguration",
|
||||
"edit-app-config-tooltip":"Övriga appkonfigurationsalternativ",
|
||||
"edit-pages-btn": "Editera sidor",
|
||||
"edit-pages-tooltip": "Lägg till eller ta bort ytterligare vyer",
|
||||
"config-save-methods-subheading":"Alternativ för konfigurationssparande",
|
||||
"save-locally-btn":"Spara lokalt",
|
||||
"save-locally-tooltip":"Spara konfigurationen lokalt, till webbläsarens lagring. Detta påverkar inte din konfigurationsfil, men ändringarna sparas bara på denna enhet",
|
||||
|
|
@ -269,6 +279,15 @@
|
|||
"mem-breakdown-title":"Memory Breakdown",
|
||||
"load-chart-title":"System Load"
|
||||
},
|
||||
"glances": {
|
||||
"disk-space-free": "Ledigt",
|
||||
"disk-space-used": "Utnyttjat",
|
||||
"disk-mount-point": "Mount Point",
|
||||
"disk-file-system": "Filsystem",
|
||||
"disk-io-read": "Läs",
|
||||
"disk-io-write": "Skriv",
|
||||
"system-load-desc": "Antal processer som väntar i run-queue, i genomsnitt över alla kärnor"
|
||||
},
|
||||
"system-info":{
|
||||
"uptime":"Uptime"
|
||||
},
|
||||
|
|
@ -279,6 +298,87 @@
|
|||
"tfl-status":{
|
||||
"good-service-all":"God service på alla linjer",
|
||||
"good-service-rest":"God Service på övriga linjer"
|
||||
},
|
||||
"gluetun-status": {
|
||||
"vpn-ip": "VPN IP",
|
||||
"country": "Land",
|
||||
"region": "Region",
|
||||
"city": "Stad",
|
||||
"post-code": "Postnummer",
|
||||
"location": "Plats",
|
||||
"timezone": "Tidszon",
|
||||
"organization": "Organisation"
|
||||
},
|
||||
"nextcloud": {
|
||||
"active": "aktiv",
|
||||
"and": "och",
|
||||
"applications": "applikationer",
|
||||
"available": "Tillgänglig",
|
||||
"away": "Borta",
|
||||
"cache-full": "CACHE FULL",
|
||||
"chat-room": "chattrum",
|
||||
"delete-all": "Ta bort alla",
|
||||
"delete-notification": "Ta bort notifikationer",
|
||||
"disabled": "Inaktiverad",
|
||||
"disk-quota": "Disk Quota",
|
||||
"disk-space": "Diskutrymme",
|
||||
"dnd": "Stör ej",
|
||||
"email": "mejl",
|
||||
"enabled": "aktiverad",
|
||||
"federated-shares-ucfirst": "Federated shares",
|
||||
"federated-shares": "federated shares",
|
||||
"files": "file{plural}",
|
||||
"free": "ledig",
|
||||
"groups": "grupper",
|
||||
"hit-rate": "hit rate",
|
||||
"hits": "hits",
|
||||
"home": "hem",
|
||||
"in": "in",
|
||||
"keys": "nycklar",
|
||||
"last-24-hours": "senaste 24 timmarna",
|
||||
"last-5-minutes": "under de senaste 5 minuterna",
|
||||
"last-hour": "under den senaste timmen",
|
||||
"last-login": "Senaste inlogg",
|
||||
"last-restart": "Senaste omstart",
|
||||
"load-averages": "Genomsnittlig belastning över alla CPU kärnor",
|
||||
"local-shares": "Local shares",
|
||||
"local": "local",
|
||||
"max-keys": "maximalt antal nycklar",
|
||||
"memory-used": "memory used",
|
||||
"memory-utilisation": "memory utilization",
|
||||
"memory": "minne",
|
||||
"misses": "misses",
|
||||
"no-notifications": "Inga notifieringar",
|
||||
"no-pending-updates": "Inga avvacktande uppdateringar",
|
||||
"nothing-to-show": "Inget att visa för tillfället",
|
||||
"of-which": "av vilket",
|
||||
"of": "av",
|
||||
"offline": "Offline",
|
||||
"online": "Online",
|
||||
"other": "other",
|
||||
"overall": "Totalt",
|
||||
"private-link": "privat länk",
|
||||
"public-link": "publik länk",
|
||||
"quota-enabled": "Disk Quota är {not}aktiverat för denna användare",
|
||||
"received": "mottaget",
|
||||
"scripts": "skript",
|
||||
"sent": "skickat",
|
||||
"started": "Startat",
|
||||
"storages-by-type": "Lagring efter typ",
|
||||
"storages": "lagring{plural}",
|
||||
"strings-use": "strings use",
|
||||
"tasks": "Uppgifter",
|
||||
"total-files": "totalt antal filer",
|
||||
"total-users": "totalt antal användare",
|
||||
"total": "totalt",
|
||||
"until": "Tills",
|
||||
"updates-available-for": "Uppdateringar är tillgängliga för",
|
||||
"updates-available": "uppdatering{plural} tillgänglig",
|
||||
"used": "använt",
|
||||
"user": "användare",
|
||||
"using": "använder",
|
||||
"version": "version",
|
||||
"wasted": "onödig"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,446 +0,0 @@
|
|||
{
|
||||
"home": {
|
||||
"no-results": "Немає результатів пошуку",
|
||||
"no-data": "Дані не налаштовано",
|
||||
"no-items-section": "Поки що немає елементів для показу"
|
||||
},
|
||||
"search": {
|
||||
"search-label": "Пошук",
|
||||
"search-placeholder": "Почніть друкувати для фільтрування",
|
||||
"clear-search-tooltip": "Очистити пошук",
|
||||
"enter-to-search-web": "Натисніть enter для пошуку в Інтернеті"
|
||||
},
|
||||
"splash-screen": {
|
||||
"loading": "Завантаження"
|
||||
},
|
||||
"login": {
|
||||
"title": "Dashy",
|
||||
"guest-label": "Гостьовий доступ",
|
||||
"username-label": "Ім'я користувача",
|
||||
"password-label": "Пароль",
|
||||
"login-button": "Увійти",
|
||||
"remember-me-label": "Запам'ятати мене для",
|
||||
"remember-me-never": "Ніколи не запамʼятовувати",
|
||||
"remember-me-hour": "4 години",
|
||||
"remember-me-day": "1 день",
|
||||
"remember-me-week": "1 тиждень",
|
||||
"remember-me-long-time": "Довгий час",
|
||||
"error-missing-username": "Відсутнє ім'я користувача",
|
||||
"error-missing-password": "Відсутній пароль",
|
||||
"error-incorrect-username": "Користувача не знайдено",
|
||||
"error-incorrect-password": "Неправильний пароль",
|
||||
"success-message": "Вхід...",
|
||||
"logout-message": "Вихід",
|
||||
"already-logged-in-title": "Вхід вже виконано",
|
||||
"already-logged-in-text": "Ви ввійшли як",
|
||||
"proceed-to-dashboard": "Перейти до інформаційної панелі",
|
||||
"log-out-button": "Вийти",
|
||||
"proceed-guest-button": "Продовжити як гість",
|
||||
"guest-intro-1": "Цей інстанс має гостьовий доступ.",
|
||||
"guest-intro-2": "Гості мають доступ лише для перегляду до інформаційних панелей, тому не можуть записати жодних змін на диск.",
|
||||
"error": "Помилка",
|
||||
"error-no-user-configured": "Автентифікацію не ввімкнено, або користувачі не налаштовані",
|
||||
"error-go-home-button": "Повернутися додому",
|
||||
"logged-in-guest": "Увійшли як гість, переспрямування...",
|
||||
"error-guest-access": "Гостьовий доступ заборонено"
|
||||
},
|
||||
"app-info": {
|
||||
"title": "Інформація про програму",
|
||||
"error-log": "Журнал помилок",
|
||||
"no-errors": "Останніх помилок не виявлено",
|
||||
"help-support": "Допомога та підтримка",
|
||||
"help-support-description": "Щоб отримати підтримку щодо запуску чи налаштування Dashy, див.",
|
||||
"help-support-discussions": "Обговорення",
|
||||
"support-dashy": "Підтримка Dashy",
|
||||
"support-dashy-description": "Щоб дізнатися, як ви можете взяти участь, перегляньте",
|
||||
"support-dashy-link": "Сторінка внесків",
|
||||
"report-bug": "Повідомити про помилку",
|
||||
"report-bug-description": "Якщо ви вважаєте, що знайшли помилку, будь ласка",
|
||||
"report-bug-link": "повідомте про проблему",
|
||||
"more-info": "Докладніше",
|
||||
"source": "Джерело",
|
||||
"documentation": "Документація",
|
||||
"privacy-and-security": "Конфіденційність та безпека",
|
||||
"privacy-and-security-l1": "Для детальної інформації про те, як Dashy керує вашими даними, див.",
|
||||
"privacy-and-security-privacy-policy": "Політика конфіденційності",
|
||||
"privacy-and-security-advice": "Щоб отримати поради щодо захисту вашої інформаційної панелі, ви можете звернутися до розділу",
|
||||
"privacy-and-security-advice-link": "Документи керування",
|
||||
"privacy-and-security-security-issue": "Якщо ви виявили потенційну проблему з безпекою, повідомте про це до розділу",
|
||||
"privacy-and-security-security-policy": "Політика безпеки",
|
||||
"license": "Ліцензія",
|
||||
"license-under": "Ліцензія згідно",
|
||||
"licence-third-party": "Ліцензії на сторонні модулі див.",
|
||||
"licence-third-party-link": "Юридична інформація",
|
||||
"list-contributors": "Повний список співавторів та подяки див.",
|
||||
"list-contributors-link": "Кредити",
|
||||
"version": "Версія"
|
||||
},
|
||||
"config": {
|
||||
"main-tab": "Головне меню",
|
||||
"view-config-tab": "Переглянути конфігурацію",
|
||||
"edit-config-tab": "Редагувати конфігурацію",
|
||||
"custom-css-tab": "Власні стилі",
|
||||
"heading": "Параметри конфігурації",
|
||||
"download-config-button": "Переглянути / Експортувати конфігурацію",
|
||||
"edit-config-button": "Редагувати конфігурацію",
|
||||
"edit-css-button": "Редагувати власний CSS",
|
||||
"cloud-sync-button": "Увімкнути хмарну синхронізацію",
|
||||
"edit-cloud-sync-button": "Редагувати хмарну синхронізацію",
|
||||
"rebuild-app-button": "Перебудувати програму",
|
||||
"change-language-button": "Змінити мову програми",
|
||||
"reset-settings-button": "Скинути локальні налаштування",
|
||||
"disabled-note": "Деякі функції конфігурації були відключені вашим адміністратором",
|
||||
"small-screen-note": "Ви використовуєте дуже маленький екран, і деякі екрани в цьому меню можуть бути не найкращими",
|
||||
"app-info-button": "Інформація про програму",
|
||||
"backup-note": "Рекомендовано зробити резервну копію конфігурації перед внесенням змін.",
|
||||
"reset-config-msg-l1": "Це видалить усі налаштування користувача з локального сховища, але не вплине на ваш файл 'conf.yml'.",
|
||||
"reset-config-msg-l2": "Ви повинні спочатку створити резервну копію будь-яких змін, які ви внесли локально, якщо ви хочете використовувати їх у майбутньому.",
|
||||
"reset-config-msg-l3": "Ви впевнені, що бажаєте продовжити?",
|
||||
"data-cleared-msg": "Дані успішно видалено",
|
||||
"actions-label": "Дії",
|
||||
"copy-config-label": "Копіювати конфігурацію",
|
||||
"data-copied-msg": "Конфігурацію скопійовано до буфера обміну",
|
||||
"reset-config-label": "Скинути конфігурацію",
|
||||
"css-save-btn": "Зберегти зміни",
|
||||
"css-note-label": "Примітка",
|
||||
"css-note-l1": "Вам потрібно буде оновити сторінку, щоб ваші зміни набули чинності.",
|
||||
"css-note-l2": "Заміни стилів зберігаються лише локально, тому рекомендується зробити копію вашого CSS.",
|
||||
"css-note-l3": "Щоб видалити всі спеціальні стилі, видаліть вміст та натисніть Зберегти зміни",
|
||||
"custom-css": {
|
||||
"title": "Власні стилі",
|
||||
"base-theme": "Базова тема"
|
||||
}
|
||||
},
|
||||
"alternate-views": {
|
||||
"alternate-view-heading": "Змінити перегляд",
|
||||
"default": "За замовчуванням",
|
||||
"workspace": "Робоча область",
|
||||
"minimal": "Мінімальний"
|
||||
},
|
||||
"settings": {
|
||||
"theme-label": "Тема",
|
||||
"layout-label": "Макет",
|
||||
"layout-auto": "Авто",
|
||||
"layout-horizontal": "Горизонтально",
|
||||
"layout-vertical": "Вертикально",
|
||||
"item-size-label": "Розмір",
|
||||
"item-size-small": "Маленький",
|
||||
"item-size-medium": "Середній",
|
||||
"item-size-large": "Великий",
|
||||
"config-launcher-label": "Конфіг",
|
||||
"config-launcher-tooltip": "Оновити конфігурацію",
|
||||
"sign-out-tooltip": "Вийти",
|
||||
"sign-in-tooltip": "Увійти",
|
||||
"sign-in-welcome": "Привіт {username}!",
|
||||
"hide": "Приховати",
|
||||
"open": "Відкрити"
|
||||
},
|
||||
"updates": {
|
||||
"app-version-note": "Версія Dashy",
|
||||
"up-to-date": "Оновити",
|
||||
"out-of-date": "Оновлення доступне",
|
||||
"unsupported-version-l1": "Ви використовуєте непідтримувану версію Dashy",
|
||||
"unsupported-version-l2": "Для найкращого досвіду та останніх виправлень безпеки, будь ласка, оновіться"
|
||||
},
|
||||
"language-switcher": {
|
||||
"title": "Змінити мову програми",
|
||||
"dropdown-label": "Оберіть мову",
|
||||
"save-button": "Зберегти",
|
||||
"success-msg": "Мову оновлено"
|
||||
},
|
||||
"theme-maker": {
|
||||
"title": "Конфігуратор теми",
|
||||
"export-button": "Експорт змінних користувача",
|
||||
"reset-button": "Скинути стилі",
|
||||
"show-all-button": "Показати всі змінні",
|
||||
"change-fonts-button": "Змінити шрифти",
|
||||
"save-button": "Зберегти",
|
||||
"cancel-button": "Скасувати",
|
||||
"saved-toast": "{theme} успішно оновлена",
|
||||
"copied-toast": "Дані теми для {theme} скопійовано в буфер обміну",
|
||||
"reset-toast": "Кольори користувача для {theme} видалено"
|
||||
},
|
||||
"config-editor": {
|
||||
"save-location-label": "Зберегти розташування",
|
||||
"location-local-label": "Застосувати локально",
|
||||
"location-disk-label": "Записати зміни до файлу конфігурації",
|
||||
"save-button": "Зберегти зміни",
|
||||
"preview-button": "Попередній перегляд змін",
|
||||
"valid-label": "Конфігурація дійсна",
|
||||
"status-success-msg": "Завдання виконано",
|
||||
"status-fail-msg": "Завдання не виконано",
|
||||
"success-msg-disk": "Файл конфігурації успішно записаний на диск",
|
||||
"success-msg-local": "Локальні зміни успішно збережено",
|
||||
"success-note-l1": "Програма повинна автоматично перебудуватися.",
|
||||
"success-note-l2": "Це може зайняти до хвилини.",
|
||||
"success-note-l3": "Вам потрібно буде оновити сторінку, щоб зміни набули чинності.",
|
||||
"error-msg-save-mode": "Будь ласка, виберіть режим збереження: локальний або файловий",
|
||||
"error-msg-cannot-save": "Під час збереження конфігурації сталася помилка",
|
||||
"error-msg-bad-json": "Помилка в JSON, можливо, неправильний формат",
|
||||
"warning-msg-validation": "Попередження про перевірку",
|
||||
"not-admin-note": "Ви не можете записати зміни на диск, оскільки ви не увійшли як адміністратор"
|
||||
},
|
||||
"app-rebuild": {
|
||||
"title": "Перебудувати програму",
|
||||
"rebuild-note-l1": "Перебудова потрібна, щоб зміни, записані у файл conf.yml, набули чинності.",
|
||||
"rebuild-note-l2": "Це має статися автоматично, але якщо цього не сталося, ви можете запустити це звідси вручну.",
|
||||
"rebuild-note-l3": "Це не потрібно для змін, які зберігаються локально.",
|
||||
"rebuild-button": "Почати збірку",
|
||||
"rebuilding-status-1": "Збираємо...",
|
||||
"rebuilding-status-2": "Це може зайняти кілька хвилин",
|
||||
"error-permission": "У вас немає дозволу ініціювати цю дію",
|
||||
"success-msg": "Збірку завершено успішно",
|
||||
"fail-msg": "Помилка операції збирання",
|
||||
"reload-note": "Тепер потрібно перезавантажити сторінку, щоб зміни набули чинності",
|
||||
"reload-button": "Перезавантажити сторінку"
|
||||
},
|
||||
"cloud-sync": {
|
||||
"title": "Резервне копіювання та відновлення в хмарі",
|
||||
"intro-l1": "Резервне копіювання та відновлення в хмарі є додатковою функцією, яка дає змогу завантажити вашу конфігурацію в Інтернет, а потім відновити її на будь-якому іншому пристрої чи екземплярі Dashy.",
|
||||
"intro-l2": "Усі дані повністю зашифровані за допомогою AES із використанням вашого пароля як ключа.",
|
||||
"intro-l3": "Для отримання додаткової інформації див.",
|
||||
"intro-docs": "документи",
|
||||
"backup-title-setup": "Створити резервну копію",
|
||||
"backup-title-update": "Оновити резервну копію",
|
||||
"password-label-setup": "Оберіть пароль",
|
||||
"password-label-update": "Введіть свій пароль",
|
||||
"backup-button-setup": "Резервна копія",
|
||||
"backup-button-update": "Оновити резервну копію",
|
||||
"backup-id-label": "Ваш ID резервної копії",
|
||||
"backup-id-note": "Це використовується для відновлення з резервних копій пізніше. Тож має зберігатися разом із паролем у безпечному місці.",
|
||||
"restore-title": "Відновити резервну копію",
|
||||
"restore-id-label": "Відновити ID",
|
||||
"restore-password-label": "Пароль",
|
||||
"restore-button": "Відновити",
|
||||
"backup-missing-password": "Відсутній пароль",
|
||||
"backup-error-unknown": "Неможливо обробити запит",
|
||||
"backup-error-password": "Неправильний пароль. Будь ласка введіть поточний пароль.",
|
||||
"backup-success-msg": "Успішно завершено",
|
||||
"restore-success-msg": "Конфігурацію успішно відновлено"
|
||||
},
|
||||
"menu": {
|
||||
"open-section-title": "Відкрити в",
|
||||
"sametab": "Поточна вкладка",
|
||||
"newtab": "Нова вкладка",
|
||||
"modal": "Модальне спливаюче вікно",
|
||||
"workspace": "Перегляд робочої області",
|
||||
"options-section-title": "Параметри",
|
||||
"edit-item": "Редагувати",
|
||||
"move-item": "Копіювати або перемістити",
|
||||
"remove-item": "Видалити"
|
||||
},
|
||||
"context-menus": {
|
||||
"item": {
|
||||
"open-section-title": "Відкрити в",
|
||||
"sametab": "Поточна вкладка",
|
||||
"newtab": "Нова вкладка",
|
||||
"modal": "Модальне спливаюче вікно",
|
||||
"workspace": "Перегляд робочої області",
|
||||
"clipboard": "Копіювати до буфера обміну",
|
||||
"options-section-title": "Параметри",
|
||||
"edit-item": "Редагувати",
|
||||
"move-item": "Копіювати або перемістити",
|
||||
"remove-item": "Видалити",
|
||||
"copied-toast": "URL скопійовано до буфера обміну"
|
||||
},
|
||||
"section": {
|
||||
"open-section": "Відкрити розділ",
|
||||
"edit-section": "Редагувати",
|
||||
"expand-collapse": "Розгорнути / Згорнути",
|
||||
"move-section": "Перемістити до",
|
||||
"remove-section": "Видалити"
|
||||
}
|
||||
},
|
||||
"footer": {
|
||||
"dev-by": "Розроблено",
|
||||
"licensed-under": "Ліцензія згідно",
|
||||
"get-the": "Отримати",
|
||||
"source-code": "вихідний код"
|
||||
},
|
||||
"interactive-editor": {
|
||||
"menu": {
|
||||
"start-editing-tooltip": "Увійти в інтерактивний редактор",
|
||||
"edit-site-data-subheading": "Редагувати дані сайту",
|
||||
"edit-page-info-btn": "Редагувати інформацію про сторінку",
|
||||
"edit-page-info-tooltip": "Назва програми, опис, навігаційні посилання, текст нижнього колонтитула тощо",
|
||||
"edit-app-config-btn": "Редагувати конфігурацію програми",
|
||||
"edit-app-config-tooltip": "Усі інші параметри конфігурації програми",
|
||||
"edit-pages-btn": "Редагувати сторінки",
|
||||
"edit-pages-tooltip": "Додати або видалити додаткові перегляди",
|
||||
"config-save-methods-subheading": "Параметри збереження конфігурації",
|
||||
"save-locally-btn": "Зберегти локально",
|
||||
"save-locally-tooltip": "Зберегти конфігурацію локально у сховище браузера. Це не вплине на файл конфігурації, але зміни буде збережено лише на цьому пристрої",
|
||||
"save-disk-btn": "Зберегти на диск",
|
||||
"save-disk-tooltip": "Збережіть конфігурацію у файл conf.yml на диску. Це створить резервну копію, а потім перезапише існуючу конфігурацію",
|
||||
"export-config-btn": "Експорт конфігурації",
|
||||
"export-config-tooltip": "Переглянути та експортувати нову конфігурацію у файл або в буфер обміну",
|
||||
"cloud-backup-btn": "Резервне копіювання у хмару",
|
||||
"cloud-backup-tooltip": "Зберегти зашифровану резервну копію конфігурації у хмару",
|
||||
"edit-raw-config-btn": "Редагувати необроблену конфігурацію",
|
||||
"edit-raw-config-tooltip": "Переглянути та змінити необроблену конфігурацію за допомогою редактора JSON",
|
||||
"cancel-changes-btn": "Скасувати редагування",
|
||||
"cancel-changes-tooltip": "Скинути поточні зміни та вийти з режиму редагування. Це не вплине на вашу збережену конфігурацію",
|
||||
"edit-mode-name": "Режим редагування",
|
||||
"edit-mode-subtitle": "Ви перебуваєте в режимі редагування",
|
||||
"edit-mode-description": "Це означає, що ви можете вносити зміни до конфігурації та переглядати результати, але поки ви не оберете збереження, жодні ваші зміни не будуть записані.",
|
||||
"save-stage-btn": "Зберегти",
|
||||
"cancel-stage-btn": "Скасувати",
|
||||
"save-locally-warning": "Якщо ви продовжите, зміни буде збережено лише у вашому браузері. Вам слід експортувати копію вашої конфігурації для використання на інших машинах. Бажаєте продовжити?"
|
||||
},
|
||||
"edit-item": {
|
||||
"missing-title-err": "Потрібна назва елемента"
|
||||
},
|
||||
"edit-section": {
|
||||
"edit-section-title": "Редагувати розділ",
|
||||
"add-section-title": "Додати новий розділ",
|
||||
"edit-tooltip": "Натисніть, щоб редагувати, або клацніть правою кнопкою миші, щоб отримати додаткові параметри",
|
||||
"remove-confirm": "Ви впевнені, що хочете видалити цей розділ? Цю дію можна скасувати пізніше."
|
||||
},
|
||||
"edit-app-config": {
|
||||
"warning-msg-title": "Дійте з обережністю",
|
||||
"warning-msg-l1": "Ці параметри призначені для розширеної конфігурації програми.",
|
||||
"warning-msg-l2": "Якщо ви не впевнені щодо будь-якого значення, зверніться до",
|
||||
"warning-msg-docs": "Документація",
|
||||
"warning-msg-l3": ", щоб уникнути небажаних наслідків."
|
||||
},
|
||||
"export": {
|
||||
"export-title": "Експорт конфігурації",
|
||||
"copy-clipboard-btn": "Копіювати до буфера обміну",
|
||||
"copy-clipboard-tooltip": "Скопіювати всі конфігурації програми до системного буфера обміну у форматі YAML",
|
||||
"download-file-btn": "Завантажити як файл",
|
||||
"download-file-tooltip": "Завантажте всю конфігурацію програми на свій пристрій у файлі YAML",
|
||||
"view-title": "Переглянути конфігурацію"
|
||||
}
|
||||
},
|
||||
"widgets": {
|
||||
"general": {
|
||||
"loading": "Завантаження...",
|
||||
"show-more": "Розгорнути детальніше",
|
||||
"show-less": "Показати менше",
|
||||
"open-link": "Продовжити читання"
|
||||
},
|
||||
"pi-hole": {
|
||||
"status-heading": "Статус"
|
||||
},
|
||||
"stat-ping": {
|
||||
"up": "Онлайн",
|
||||
"down": "Офлайн"
|
||||
},
|
||||
"net-data": {
|
||||
"cpu-chart-title": "Історія CPU",
|
||||
"mem-chart-title": "Використання пам'яті",
|
||||
"mem-breakdown-title": "Переривання пам'яті",
|
||||
"load-chart-title": "Завантаження системи"
|
||||
},
|
||||
"glances": {
|
||||
"disk-space-free": "Вільно",
|
||||
"disk-space-used": "Використано",
|
||||
"disk-mount-point": "Точка монтування",
|
||||
"disk-file-system": "Файлова система",
|
||||
"disk-io-read": "Читання",
|
||||
"disk-io-write": "Запис",
|
||||
"system-load-desc": "Середня кількість процесів, що очікують у черзі виконання, для всіх ядер"
|
||||
},
|
||||
"system-info": {
|
||||
"uptime": "Час роботи"
|
||||
},
|
||||
"flight-data": {
|
||||
"arrivals": "Прибуття",
|
||||
"departures": "Відправлення"
|
||||
},
|
||||
"tfl-status": {
|
||||
"good-service-all": "Якісний сервіс на всіх лініях",
|
||||
"good-service-rest": "Якісний сервіс на всіх інших лініях"
|
||||
},
|
||||
"synology-download": {
|
||||
"download": "Завантажити (Download)",
|
||||
"upload": "Вивантажити (Upload)",
|
||||
"downloaded": "Завантажено",
|
||||
"uploaded": "Вивантажено",
|
||||
"remaining": "Залишилося",
|
||||
"up": "Вгору",
|
||||
"down": "Вниз"
|
||||
},
|
||||
"gluetun-status": {
|
||||
"vpn-ip": "VPN IP",
|
||||
"country": "Країна",
|
||||
"region": "Регіон",
|
||||
"city": "Місто",
|
||||
"post-code": "Поштовий індекс",
|
||||
"location": "Розташування",
|
||||
"timezone": "Часовий пояс",
|
||||
"organization": "Організація"
|
||||
},
|
||||
"nextcloud": {
|
||||
"active": "активно",
|
||||
"and": "і",
|
||||
"applications": "програми",
|
||||
"available": "доступно",
|
||||
"away": "відсутнє",
|
||||
"cache-full": "КЕШ ЗАПОВНЕНИЙ",
|
||||
"chat-room": "кімната чату",
|
||||
"delete-all": "Видалити все",
|
||||
"delete-notification": "Видалити сповіщення",
|
||||
"disabled": "вимкнено",
|
||||
"disk-quota": "Дискова квота",
|
||||
"disk-space": "Простір на диску",
|
||||
"dnd": "Не турбувати",
|
||||
"email": "електронна пошта",
|
||||
"enabled": "увімкнено",
|
||||
"federated-shares-ucfirst": "Об'єднані спільні ресурси",
|
||||
"federated-shares": "об'єднані спільні ресурси",
|
||||
"files": "файл{множина}",
|
||||
"free": "вільний",
|
||||
"groups": "групи",
|
||||
"hit-rate": "швидкість процесів",
|
||||
"hits": "процеси",
|
||||
"home": "дім",
|
||||
"in": "у",
|
||||
"keys": "ключі",
|
||||
"last-24-hours": "за останні 24 години",
|
||||
"last-5-minutes": "останні 5 хвилин",
|
||||
"last-hour": "за останню годину",
|
||||
"last-login": "Останній вхід",
|
||||
"last-restart": "Останній перезапуск",
|
||||
"load-averages": "Завантажити середні значення для всіх ядер ЦПУ",
|
||||
"local-shares": "Локальні спільні ресурси",
|
||||
"local": "локальний",
|
||||
"max-keys": "макс. ключі",
|
||||
"memory-used": "використана пам'ять",
|
||||
"memory-utilisation": "використання пам'яті",
|
||||
"memory": "пам'ять",
|
||||
"misses": "пропуски",
|
||||
"no-notifications": "Немає сповіщень",
|
||||
"no-pending-updates": "Немає очікуваних оновлень",
|
||||
"nothing-to-show": "Зараз тут нічого показувати",
|
||||
"of-which": "з яких",
|
||||
"of": "з",
|
||||
"offline": "Офлайн",
|
||||
"online": "Онлайн",
|
||||
"other": "інше",
|
||||
"overall": "Загалом",
|
||||
"private-link": "приватне посилання",
|
||||
"public-link": "публічне посилання",
|
||||
"quota-enabled": "Дискова квота {не}ввімкнена для цього користувача",
|
||||
"received": "отримано",
|
||||
"scripts": "скрипти",
|
||||
"sent": "надіслано",
|
||||
"started": "Розпочато",
|
||||
"storages-by-type": "Сховища за типом",
|
||||
"storages": "сховище{множина}",
|
||||
"strings-use": "рядки використання",
|
||||
"tasks": "Завдання",
|
||||
"total-files": "загальна кількість файлів",
|
||||
"total-users": "загальна кількість користувачів",
|
||||
"total": "усього",
|
||||
"until": "Доки",
|
||||
"updates-available-for": "Оновлення доступні для",
|
||||
"updates-available": "доступне оновлення{множина}",
|
||||
"used": "використано",
|
||||
"user": "користувач",
|
||||
"using": "використовуючи",
|
||||
"version": "версія",
|
||||
"wasted": "витрачено"
|
||||
}
|
||||
}
|
||||
}
|
||||
456
src/assets/locales/uk.json
Normal file
456
src/assets/locales/uk.json
Normal file
|
|
@ -0,0 +1,456 @@
|
|||
{
|
||||
"home": {
|
||||
"no-results": "Немає результатів пошуку",
|
||||
"no-data": "Дані не налаштовано",
|
||||
"no-items-section": "Поки що немає елементів для показу"
|
||||
},
|
||||
"search": {
|
||||
"search-label": "Пошук",
|
||||
"search-placeholder": "Почніть вводити текст для фільтрування",
|
||||
"clear-search-tooltip": "Очистити пошук",
|
||||
"enter-to-search-web": "Натисніть Enter для пошуку в Інтернеті"
|
||||
},
|
||||
"splash-screen": {
|
||||
"loading": "Завантаження"
|
||||
},
|
||||
"login": {
|
||||
"title": "Dashy",
|
||||
"guest-label": "Гостьовий доступ",
|
||||
"username-label": "Ім'я користувача",
|
||||
"password-label": "Пароль",
|
||||
"login-button": "Увійти",
|
||||
"remember-me-label": "Запам'ятати мене для",
|
||||
"remember-me-never": "Ніколи не запам'ятовувати",
|
||||
"remember-me-hour": "4 години",
|
||||
"remember-me-day": "1 день",
|
||||
"remember-me-week": "1 тиждень",
|
||||
"remember-me-long-time": "Довгий час",
|
||||
"error-missing-username": "Відсутнє ім'я користувача",
|
||||
"error-missing-password": "Відсутній пароль",
|
||||
"error-incorrect-username": "Користувача не знайдено",
|
||||
"error-incorrect-password": "Неправильний пароль",
|
||||
"success-message": "Вхід...",
|
||||
"logout-message": "Вихід",
|
||||
"already-logged-in-title": "Вхід вже виконано",
|
||||
"already-logged-in-text": "Ви увійшли як",
|
||||
"proceed-to-dashboard": "Перейти до інформаційної панелі",
|
||||
"log-out-button": "Вийти",
|
||||
"proceed-guest-button": "Продовжити як гість",
|
||||
"guest-intro-1": "У цій системі увімкнено гостьовий доступ.",
|
||||
"guest-intro-2": "Гості мають доступ лише для перегляду до інформаційних панелей, тому не можуть записати жодних змін на диск.",
|
||||
"error": "Помилка",
|
||||
"error-no-user-configured": "Автентифікацію не ввімкнено, або користувачі не налаштовані",
|
||||
"error-go-home-button": "Повернутися на головну",
|
||||
"logged-in-guest": "Ви увійшли як гість, перенаправлення...",
|
||||
"error-guest-access": "Гостьовий доступ не дозволено"
|
||||
},
|
||||
"app-info": {
|
||||
"title": "Інформація про програму",
|
||||
"error-log": "Журнал помилок",
|
||||
"no-errors": "Останніх помилок не виявлено",
|
||||
"help-support": "Допомога та підтримка",
|
||||
"help-support-description": "Щоб отримати підтримку щодо запуску чи налаштування Dashy, див.",
|
||||
"help-support-discussions": "Обговорення",
|
||||
"support-dashy": "Підтримка Dashy",
|
||||
"support-dashy-description": "Щоб дізнатися, як ви можете взяти участь, перегляньте",
|
||||
"support-dashy-link": "Сторінка внесків",
|
||||
"report-bug": "Повідомити про помилку",
|
||||
"report-bug-description": "Якщо ви вважаєте, що знайшли помилку, будь ласка",
|
||||
"report-bug-link": "повідомте про проблему",
|
||||
"more-info": "Докладніше",
|
||||
"source": "Джерело",
|
||||
"documentation": "Документація",
|
||||
"privacy-and-security": "Конфіденційність та безпека",
|
||||
"privacy-and-security-l1": "Для детальної інформації про те, як Dashy керує вашими даними, див.",
|
||||
"privacy-and-security-privacy-policy": "Політика конфіденційності",
|
||||
"privacy-and-security-advice": "Щоб отримати поради щодо захисту вашої інформаційної панелі, ви можете звернутися до розділу",
|
||||
"privacy-and-security-advice-link": "Документи керування",
|
||||
"privacy-and-security-security-issue": "Якщо ви виявили потенційну проблему з безпекою, повідомте про це згідно з нашою",
|
||||
"privacy-and-security-security-policy": "Політика безпеки",
|
||||
"license": "Ліцензія",
|
||||
"license-under": "Ліцензія згідно",
|
||||
"licence-third-party": "Ліцензії на сторонні модулі див.",
|
||||
"licence-third-party-link": "Юридична інформація",
|
||||
"list-contributors": "Повний список співавторів та подяки див.",
|
||||
"list-contributors-link": "Подяки",
|
||||
"version": "Версія"
|
||||
},
|
||||
"config": {
|
||||
"main-tab": "Головне меню",
|
||||
"view-config-tab": "Переглянути налаштування",
|
||||
"edit-config-tab": "Редагувати налаштування",
|
||||
"custom-css-tab": "Користувацькі стилі",
|
||||
"heading": "Параметри налаштування",
|
||||
"download-config-button": "Переглянути / Експортувати налаштування",
|
||||
"edit-config-button": "Редагувати налаштування",
|
||||
"edit-css-button": "Редагувати користувацький CSS",
|
||||
"cloud-sync-button": "Увімкнути хмарну синхронізацію",
|
||||
"edit-cloud-sync-button": "Редагувати хмарну синхронізацію",
|
||||
"rebuild-app-button": "Перебудувати програму",
|
||||
"change-language-button": "Змінити мову програми",
|
||||
"reset-settings-button": "Скинути локальні налаштування",
|
||||
"disabled-note": "Деякі функції налаштувань були вимкнені адміністратором",
|
||||
"small-screen-note": "Ви використовуєте дуже маленький екран, і деякі екрани в цьому меню можуть бути не найкращими",
|
||||
"app-info-button": "Інформація про програму",
|
||||
"backup-note": "Рекомендовано зробити резервну копію налаштування перед внесенням змін.",
|
||||
"reset-config-msg-l1": "Це видалить усі налаштування користувача з локального сховища, але не вплине на ваш файл 'conf.yml'.",
|
||||
"reset-config-msg-l2": "Ви повинні спочатку створити резервну копію будь-яких змін, які ви внесли локально, якщо ви хочете використовувати їх у майбутньому.",
|
||||
"reset-config-msg-l3": "Ви впевнені, що бажаєте продовжити?",
|
||||
"data-cleared-msg": "Дані успішно видалено",
|
||||
"actions-label": "Дії",
|
||||
"copy-config-label": "Копіювати налаштування",
|
||||
"data-copied-msg": "Налаштування скопійовано до буфера обміну",
|
||||
"reset-config-label": "Скинути налаштування",
|
||||
"css-save-btn": "Зберегти зміни",
|
||||
"css-note-label": "Примітка",
|
||||
"css-note-l1": "Вам потрібно буде оновити сторінку, щоб ваші зміни набули чинності.",
|
||||
"css-note-l2": "Заміни стилів зберігаються лише локально, тому рекомендується зробити копію вашого CSS.",
|
||||
"css-note-l3": "Щоб видалити всі користувацькі стилі, видаліть вміст та натисніть Зберегти зміни",
|
||||
"custom-css": {
|
||||
"title": "Користувацькі стилі",
|
||||
"base-theme": "Базова тема"
|
||||
}
|
||||
},
|
||||
"alternate-views": {
|
||||
"alternate-view-heading": "Змінити перегляд",
|
||||
"default": "За замовчуванням",
|
||||
"workspace": "Робочий простір",
|
||||
"minimal": "Мінімальний"
|
||||
},
|
||||
"settings": {
|
||||
"theme-label": "Тема",
|
||||
"layout-label": "Макет",
|
||||
"layout-auto": "Авто",
|
||||
"layout-horizontal": "Горизонтально",
|
||||
"layout-vertical": "Вертикально",
|
||||
"item-size-label": "Розмір елемента",
|
||||
"item-size-small": "Маленький",
|
||||
"item-size-medium": "Середній",
|
||||
"item-size-large": "Великий",
|
||||
"config-launcher-label": "Налаштування",
|
||||
"config-launcher-tooltip": "Оновити налаштування",
|
||||
"sign-out-tooltip": "Вийти",
|
||||
"sign-in-tooltip": "Увійти",
|
||||
"sign-in-welcome": "Вітаємо {username}!",
|
||||
"hide": "Приховати",
|
||||
"open": "Відкрити"
|
||||
},
|
||||
"updates": {
|
||||
"app-version-note": "Версія Dashy",
|
||||
"up-to-date": "Оновити",
|
||||
"out-of-date": "Оновлення доступне",
|
||||
"unsupported-version-l1": "Ви використовуєте непідтримувану версію Dashy",
|
||||
"unsupported-version-l2": "Для найкращого досвіду та останніх виправлень безпеки, будь ласка, оновіться"
|
||||
},
|
||||
"language-switcher": {
|
||||
"title": "Змінити мову програми",
|
||||
"dropdown-label": "Оберіть мову",
|
||||
"save-button": "Зберегти",
|
||||
"success-msg": "Мову оновлено"
|
||||
},
|
||||
"theme-maker": {
|
||||
"title": "Конфігуратор теми",
|
||||
"export-button": "Експорт змінних користувача",
|
||||
"reset-button": "Скинути стилі",
|
||||
"show-all-button": "Показати всі змінні",
|
||||
"change-fonts-button": "Змінити шрифти",
|
||||
"save-button": "Зберегти",
|
||||
"cancel-button": "Скасувати",
|
||||
"saved-toast": "{theme} успішно оновлена",
|
||||
"copied-toast": "Дані теми для {theme} скопійовано в буфер обміну",
|
||||
"reset-toast": "Видалені користувацькі кольори для {theme}"
|
||||
},
|
||||
"config-editor": {
|
||||
"save-location-label": "Місце збереження",
|
||||
"location-local-label": "Застосувати локально",
|
||||
"location-disk-label": "Записати зміни до файлу налаштування",
|
||||
"save-button": "Зберегти зміни",
|
||||
"preview-button": "Попередній перегляд змін",
|
||||
"valid-label": "Налаштування дійсне",
|
||||
"status-success-msg": "Завдання виконано",
|
||||
"status-fail-msg": "Не вдалося виконати завдання",
|
||||
"success-msg-disk": "Файл налаштування успішно записаний на диск",
|
||||
"success-msg-local": "Локальні зміни успішно збережено",
|
||||
"success-note-l1": "Програма повинна автоматично перебудуватися.",
|
||||
"success-note-l2": "Це може зайняти до хвилини.",
|
||||
"success-note-l3": "Вам потрібно буде оновити сторінку, щоб зміни набули чинності.",
|
||||
"error-msg-save-mode": "Будь ласка, виберіть режим збереження: локальний або файловий",
|
||||
"error-msg-cannot-save": "Під час збереження налаштування сталася помилка",
|
||||
"error-msg-bad-json": "Помилка у форматі JSON, можливо, некоректно сформований",
|
||||
"warning-msg-validation": "Попередження про перевірку",
|
||||
"not-admin-note": "Ви не можете записати зміни на диск, оскільки ви не увійшли як адміністратор"
|
||||
},
|
||||
"app-rebuild": {
|
||||
"title": "Перебудувати програму",
|
||||
"rebuild-note-l1": "Перебудова потрібна, щоб зміни, записані у файл conf.yml, набули чинності.",
|
||||
"rebuild-note-l2": "Це має статися автоматично, але якщо цього не сталося, ви можете запустити це звідси вручну.",
|
||||
"rebuild-note-l3": "Це не потрібно для змін, які зберігаються локально.",
|
||||
"rebuild-button": "Почати збірку",
|
||||
"rebuilding-status-1": "Збираємо...",
|
||||
"rebuilding-status-2": "Це може зайняти кілька хвилин",
|
||||
"error-permission": "У вас немає дозволу ініціювати цю дію",
|
||||
"success-msg": "Збірку завершено успішно",
|
||||
"fail-msg": "Помилка при виконанні збірки",
|
||||
"reload-note": "Тепер потрібно перезавантажити сторінку, щоб зміни набули чинності",
|
||||
"reload-button": "Перезавантажити сторінку"
|
||||
},
|
||||
"cloud-sync": {
|
||||
"title": "Резервне копіювання та відновлення у хмарі",
|
||||
"intro-l1": "Резервне копіювання та відновлення в хмарі є додатковою функцією, яка дає змогу завантажити ваше налаштування в Інтернет, а потім відновити її на будь-якому іншому пристрої чи екземплярі Dashy.",
|
||||
"intro-l2": "Усі дані повністю зашифровані за допомогою AES із використанням вашого пароля як ключа.",
|
||||
"intro-l3": "Для отримання додаткової інформації див.",
|
||||
"intro-docs": "документи",
|
||||
"backup-title-setup": "Створити резервну копію",
|
||||
"backup-title-update": "Оновити резервну копію",
|
||||
"password-label-setup": "Оберіть пароль",
|
||||
"password-label-update": "Введіть свій пароль",
|
||||
"backup-button-setup": "Резервна копія",
|
||||
"backup-button-update": "Оновити резервну копію",
|
||||
"backup-id-label": "Ваш ідентифікатор резервної копії",
|
||||
"backup-id-note": "Це використовується для відновлення з резервних копій пізніше. Тож має зберігатися разом із паролем у безпечному місці.",
|
||||
"restore-title": "Відновити резервну копію",
|
||||
"restore-id-label": "Відновити ідентифікатор",
|
||||
"restore-password-label": "Пароль",
|
||||
"restore-button": "Відновити",
|
||||
"backup-missing-password": "Відсутній пароль",
|
||||
"backup-error-unknown": "Неможливо обробити запит",
|
||||
"backup-error-password": "Неправильний пароль. Будь ласка, введіть поточний пароль.",
|
||||
"backup-success-msg": "Успішно завершено",
|
||||
"restore-success-msg": "Налаштування успішно відновлено"
|
||||
},
|
||||
"menu": {
|
||||
"open-section-title": "Відкрити в",
|
||||
"sametab": "Поточна вкладка",
|
||||
"newtab": "Нова вкладка",
|
||||
"modal": "Модальне спливаюче вікно",
|
||||
"workspace": "Перегляд робочого простору",
|
||||
"options-section-title": "Параметри",
|
||||
"edit-item": "Редагувати",
|
||||
"move-item": "Копіювати або перемістити",
|
||||
"remove-item": "Видалити"
|
||||
},
|
||||
"context-menus": {
|
||||
"item": {
|
||||
"open-section-title": "Відкрити в",
|
||||
"sametab": "Поточна вкладка",
|
||||
"newtab": "Нова вкладка",
|
||||
"modal": "Модальне спливаюче вікно",
|
||||
"workspace": "Перегляд робочої області",
|
||||
"clipboard": "Копіювати до буфера обміну",
|
||||
"options-section-title": "Параметри",
|
||||
"edit-item": "Редагувати",
|
||||
"move-item": "Копіювати або перемістити",
|
||||
"remove-item": "Видалити",
|
||||
"copied-toast": "URL скопійовано до буфера обміну"
|
||||
},
|
||||
"section": {
|
||||
"open-section": "Відкрити розділ",
|
||||
"edit-section": "Редагувати",
|
||||
"expand-collapse": "Розгорнути / Згорнути",
|
||||
"move-section": "Перемістити до",
|
||||
"remove-section": "Видалити"
|
||||
}
|
||||
},
|
||||
"footer": {
|
||||
"dev-by": "Розроблено",
|
||||
"licensed-under": "Ліцензія згідно",
|
||||
"get-the": "Отримати",
|
||||
"source-code": "Вихідний код"
|
||||
},
|
||||
"interactive-editor": {
|
||||
"menu": {
|
||||
"start-editing-tooltip": "Увійти в інтерактивний редактор",
|
||||
"edit-site-data-subheading": "Редагувати дані сайту",
|
||||
"edit-page-info-btn": "Редагувати інформацію про сторінку",
|
||||
"edit-page-info-tooltip": "Назва програми, опис, навігаційні посилання, текст нижнього колонтитула тощо",
|
||||
"edit-app-config-btn": "Редагувати налаштування програми",
|
||||
"edit-app-config-tooltip": "Усі інші параметри налаштування програми",
|
||||
"edit-pages-btn": "Редагувати сторінки",
|
||||
"edit-pages-tooltip": "Додати або видалити додаткові перегляди",
|
||||
"config-save-methods-subheading": "Параметри збереження налаштування",
|
||||
"save-locally-btn": "Зберегти локально",
|
||||
"save-locally-tooltip": "Зберегти налаштування локально у сховище браузера. Це не вплине на файл налаштування, але зміни буде збережено лише на цьому пристрої",
|
||||
"save-disk-btn": "Зберегти на диск",
|
||||
"save-disk-tooltip": "Збережіть налаштування у файл conf.yml на диску. Це створить резервну копію, а потім перезапише наявне налаштування",
|
||||
"export-config-btn": "Експорт налаштування",
|
||||
"export-config-tooltip": "Переглянути та експортувати нове налаштування у файл або в буфер обміну",
|
||||
"cloud-backup-btn": "Резервне копіювання у хмару",
|
||||
"cloud-backup-tooltip": "Зберегти зашифровану резервну копію налаштування у хмару",
|
||||
"edit-raw-config-btn": "Редагувати необроблене налаштування",
|
||||
"edit-raw-config-tooltip": "Переглянути та змінити необроблене налаштування за допомогою редактора JSON",
|
||||
"cancel-changes-btn": "Скасувати редагування",
|
||||
"cancel-changes-tooltip": "Скинути поточні зміни та вийти з режиму редагування. Це не вплине на вашу збережене налаштування",
|
||||
"edit-mode-name": "Режим редагування",
|
||||
"edit-mode-subtitle": "Ви перебуваєте в режимі редагування",
|
||||
"edit-mode-description": "Це означає, що ви можете вносити зміни до налаштування та переглядати результати, але поки ви не оберете збереження, жодні ваші зміни не будуть записані.",
|
||||
"save-stage-btn": "Зберегти",
|
||||
"cancel-stage-btn": "Скасувати",
|
||||
"save-locally-warning": "Якщо ви продовжите, зміни буде збережено лише у вашому браузері. Вам слід експортувати копію вашого налаштування для використання на інших машинах. Бажаєте продовжити?"
|
||||
},
|
||||
"edit-item": {
|
||||
"missing-title-err": "Потрібна назва елемента"
|
||||
},
|
||||
"edit-section": {
|
||||
"edit-section-title": "Редагувати розділ",
|
||||
"add-section-title": "Додати новий розділ",
|
||||
"edit-tooltip": "Натисніть, щоб редагувати, або клацніть правою кнопкою миші, щоб отримати додаткові параметри",
|
||||
"remove-confirm": "Ви впевнені, що хочете видалити цей розділ? Цю дію можна скасувати пізніше."
|
||||
},
|
||||
"edit-app-config": {
|
||||
"warning-msg-title": "Дійте з обережністю",
|
||||
"warning-msg-l1": "Ці параметри призначені для розширеного налаштування програми.",
|
||||
"warning-msg-l2": "Якщо ви не впевнені щодо будь-якого значення, зверніться до",
|
||||
"warning-msg-docs": "Документація",
|
||||
"warning-msg-l3": ", щоб уникнути небажаних наслідків."
|
||||
},
|
||||
"export": {
|
||||
"export-title": "Експорт налаштування",
|
||||
"copy-clipboard-btn": "Копіювати до буфера обміну",
|
||||
"copy-clipboard-tooltip": "Скопіювати всі налаштування програми до системного буфера обміну у форматі YAML",
|
||||
"download-file-btn": "Завантажити як файл",
|
||||
"download-file-tooltip": "Завантажте все налаштування програми на свій пристрій у файлі YAML",
|
||||
"view-title": "Переглянути налаштування"
|
||||
}
|
||||
},
|
||||
"critical-error": {
|
||||
"title": "Помилка завантаження налаштування",
|
||||
"subtitle": "Dashy не вдалося правильно завантажити через помилку налаштування.",
|
||||
"sub-ensure-that": "Переконайтеся в цьому",
|
||||
"sub-error-details": "Деталі помилки",
|
||||
"sub-next-steps": "Наступні кроки",
|
||||
"ignore-button": "Ігнорувати критичні помилки"
|
||||
},
|
||||
"widgets": {
|
||||
"general": {
|
||||
"loading": "Завантаження...",
|
||||
"show-more": "Розгорнути детальніше",
|
||||
"cpu-details": "Детальніше по ЦПУ",
|
||||
"mem-details": "Детальніше по пам'яті",
|
||||
"show-less": "Показати менше",
|
||||
"open-link": "Продовжити читання"
|
||||
},
|
||||
"pi-hole": {
|
||||
"status-heading": "Статус"
|
||||
},
|
||||
"stat-ping": {
|
||||
"up": "Онлайн",
|
||||
"down": "Офлайн"
|
||||
},
|
||||
"net-data": {
|
||||
"cpu-chart-title": "Історія ЦПУ",
|
||||
"mem-chart-title": "Використання пам'яті",
|
||||
"mem-breakdown-title": "Переривання пам'яті",
|
||||
"load-chart-title": "Завантаження системи"
|
||||
},
|
||||
"glances": {
|
||||
"disk-space-free": "Вільно",
|
||||
"disk-space-used": "Використано",
|
||||
"disk-mount-point": "Точка монтування",
|
||||
"disk-file-system": "Файлова система",
|
||||
"disk-io-read": "Читання",
|
||||
"disk-io-write": "Запис",
|
||||
"system-load-desc": "Середня кількість процесів, що очікують у черзі виконання, для всіх ядер"
|
||||
},
|
||||
"system-info": {
|
||||
"uptime": "Час роботи"
|
||||
},
|
||||
"flight-data": {
|
||||
"arrivals": "Прибуття",
|
||||
"departures": "Відправлення"
|
||||
},
|
||||
"tfl-status": {
|
||||
"good-service-all": "Якісний сервіс на всіх лініях",
|
||||
"good-service-rest": "Якісний сервіс на всіх інших лініях"
|
||||
},
|
||||
"synology-download": {
|
||||
"download": "Завантажити (Download)",
|
||||
"upload": "Вивантажити (Upload)",
|
||||
"downloaded": "Завантажено",
|
||||
"uploaded": "Вивантажено",
|
||||
"remaining": "Залишилося",
|
||||
"up": "Вгору",
|
||||
"down": "Вниз"
|
||||
},
|
||||
"gluetun-status": {
|
||||
"vpn-ip": "VPN IP",
|
||||
"country": "Країна",
|
||||
"region": "Регіон",
|
||||
"city": "Місто",
|
||||
"post-code": "Поштовий індекс",
|
||||
"location": "Розташування",
|
||||
"timezone": "Часовий пояс",
|
||||
"organization": "Організація"
|
||||
},
|
||||
"nextcloud": {
|
||||
"active": "активно",
|
||||
"and": "і",
|
||||
"applications": "програми",
|
||||
"available": "доступно",
|
||||
"away": "відсутнє",
|
||||
"cache-full": "КЕШ ЗАПОВНЕНИЙ",
|
||||
"chat-room": "кімната чату",
|
||||
"delete-all": "Видалити все",
|
||||
"delete-notification": "Видалити сповіщення",
|
||||
"disabled": "вимкнено",
|
||||
"disk-quota": "Дискова квота",
|
||||
"disk-space": "Простір на диску",
|
||||
"dnd": "Не турбувати",
|
||||
"email": "електронна пошта",
|
||||
"enabled": "увімкнено",
|
||||
"federated-shares-ucfirst": "Об'єднані спільні ресурси",
|
||||
"federated-shares": "об'єднані спільні ресурси",
|
||||
"files": "файл{множина}",
|
||||
"free": "вільний",
|
||||
"groups": "групи",
|
||||
"hit-rate": "рівень попадань",
|
||||
"hits": "попадання",
|
||||
"home": "головна",
|
||||
"in": "у",
|
||||
"keys": "ключі",
|
||||
"last-24-hours": "за останні 24 години",
|
||||
"last-5-minutes": "останні 5 хвилин",
|
||||
"last-hour": "за останню годину",
|
||||
"last-login": "Останній вхід",
|
||||
"last-restart": "Останній перезапуск",
|
||||
"load-averages": "Завантажити середні значення для всіх ядер ЦПУ",
|
||||
"local-shares": "Локальні спільні ресурси",
|
||||
"local": "локальний",
|
||||
"max-keys": "максимум ключів",
|
||||
"memory-used": "використана пам'ять",
|
||||
"memory-utilisation": "використання пам'яті",
|
||||
"memory": "пам'ять",
|
||||
"misses": "промахи",
|
||||
"no-notifications": "Немає сповіщень",
|
||||
"no-pending-updates": "немає очікуваних оновлень",
|
||||
"nothing-to-show": "Зараз тут нічого показувати",
|
||||
"of-which": "з яких",
|
||||
"of": "з",
|
||||
"offline": "Офлайн",
|
||||
"online": "Онлайн",
|
||||
"other": "інше",
|
||||
"overall": "Загалом",
|
||||
"private-link": "приватне посилання",
|
||||
"public-link": "публічне посилання",
|
||||
"quota-enabled": "Дискова квота {не}ввімкнена для цього користувача",
|
||||
"received": "отримано",
|
||||
"scripts": "скрипти",
|
||||
"sent": "надіслано",
|
||||
"started": "Розпочато",
|
||||
"storages-by-type": "Сховища за типом",
|
||||
"storages": "сховище{множина}",
|
||||
"strings-use": "рядки використання",
|
||||
"tasks": "Завдання",
|
||||
"total-files": "загальна кількість файлів",
|
||||
"total-users": "загальна кількість користувачів",
|
||||
"total": "усього",
|
||||
"until": "Доки",
|
||||
"updates-available-for": "Оновлення доступні для",
|
||||
"updates-available": "доступне оновлення{множина}",
|
||||
"used": "використано",
|
||||
"user": "користувач",
|
||||
"using": "використовуючи",
|
||||
"version": "версія",
|
||||
"wasted": "витрачено"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
"guest-label": "访客访问",
|
||||
"username-label": "用户名",
|
||||
"password-label": "密码",
|
||||
"login-button": "登陆",
|
||||
"login-button": "登录",
|
||||
"remember-me-label": "记住密码",
|
||||
"remember-me-never": "永不",
|
||||
"remember-me-hour": "4 小时",
|
||||
|
|
@ -29,10 +29,10 @@
|
|||
"error-missing-password": "密码空缺",
|
||||
"error-incorrect-username": "用户不存在",
|
||||
"error-incorrect-password": "密码不正确",
|
||||
"success-message": "登陆成功。",
|
||||
"success-message": "登录成功。",
|
||||
"logout-message": "注销",
|
||||
"already-logged-in-title": "已经成功登陆",
|
||||
"already-logged-in-text": "你的登陆身份",
|
||||
"already-logged-in-title": "已经成功登录",
|
||||
"already-logged-in-text": "你的登录身份",
|
||||
"proceed-to-dashboard": "前往仪表板",
|
||||
"log-out-button": "注销",
|
||||
"proceed-guest-button": "以游客身份前往",
|
||||
|
|
@ -41,7 +41,7 @@
|
|||
"error": "错误",
|
||||
"error-no-user-configured": "没有启用验证,或者未配置用户",
|
||||
"error-go-home-button": "Go Home",
|
||||
"logged-in-guest": "以访客身份登陆,正在跳转...",
|
||||
"logged-in-guest": "以访客身份登录,正在跳转...",
|
||||
"error-guest-access": "不允许访客访问"
|
||||
},
|
||||
"app-info": {
|
||||
|
|
@ -130,7 +130,7 @@
|
|||
"config-launcher-label": "设置",
|
||||
"config-launcher-tooltip": "更新设置",
|
||||
"sign-out-tooltip": "注销",
|
||||
"sign-in-tooltip": "登陆",
|
||||
"sign-in-tooltip": "登录",
|
||||
"sign-in-welcome": "你好 {username}!",
|
||||
"hide": "隐藏",
|
||||
"open": "打开"
|
||||
|
|
@ -402,7 +402,7 @@
|
|||
"last-24-hours": "24 小时内",
|
||||
"last-5-minutes": "5 分钟内",
|
||||
"last-hour": "1 小时内",
|
||||
"last-login": "最后登陆",
|
||||
"last-login": "最后登录",
|
||||
"last-restart": "最后重启",
|
||||
"load-averages": "所有CPU的平均负载",
|
||||
"local-shares": "本地分享",
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ export default {
|
|||
else if (img.includes('mdi-')) imgType = 'mdi';
|
||||
else if (img.includes('si-')) imgType = 'si';
|
||||
else if (img.includes('hl-')) imgType = 'home-lab-icons';
|
||||
else if (img.includes('sh-')) imgType = 'selfhst-icons';
|
||||
else if (img.includes('favicon-')) imgType = 'custom-favicon';
|
||||
else if (img === 'favicon') imgType = 'favicon';
|
||||
else if (img === 'generative') imgType = 'generative';
|
||||
|
|
@ -90,6 +91,7 @@ export default {
|
|||
case 'mdi': return img; // Material design icons
|
||||
case 'simple-icons': return this.getSimpleIcon(img);
|
||||
case 'home-lab-icons': return this.getHomeLabIcon(img);
|
||||
case 'selfhst-icons': return this.getSelfhstIcon(img); // selfh.st/icons
|
||||
case 'svg': return img; // Local SVG icon
|
||||
case 'emoji': return img; // Emoji/ unicode
|
||||
default: return '';
|
||||
|
|
@ -195,6 +197,10 @@ export default {
|
|||
}
|
||||
return icon.path;
|
||||
},
|
||||
getSelfhstIcon(img, cdn) {
|
||||
const imageName = img.slice(3).toLocaleLowerCase();
|
||||
return (cdn || iconCdns.sh).replace('{icon}', imageName);
|
||||
},
|
||||
/* Gets home-lab icon from GitHub */
|
||||
getHomeLabIcon(img, cdn) {
|
||||
const imageName = img.replace('hl-', '').toLocaleLowerCase();
|
||||
|
|
|
|||
66
src/components/Widgets/ChuckNorris.vue
Normal file
66
src/components/Widgets/ChuckNorris.vue
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
<template>
|
||||
<div class="chuckNorris-wrapper">
|
||||
<p class="chuckNorris chuckNorris-line">{{ chuckNorrisLine }}</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from 'axios';
|
||||
import WidgetMixin from '@/mixins/WidgetMixin';
|
||||
import { widgetApiEndpoints } from '@/utils/defaults';
|
||||
|
||||
export default {
|
||||
mixins: [WidgetMixin],
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
chuckNorrisLine: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
/* Format the users preferred categories */
|
||||
categories() {
|
||||
let usersChoice = this.options.categories;
|
||||
if (!usersChoice) return '';
|
||||
if (Array.isArray(usersChoice)) usersChoice = usersChoice.join(',');
|
||||
const categories = ["animal","career","celebrity","dev","explicit","fashion","food","history","money","movie","music","political","religion","science","sport","travel"];
|
||||
if (categories.some((cat) => usersChoice.toLowerCase().includes(cat))) return usersChoice;
|
||||
return '';
|
||||
},
|
||||
/* Combine data parameters for the API endpoint */
|
||||
endpoint() {
|
||||
if (this.categories !== '') return `${widgetApiEndpoints.chuckNorris}?category=${this.categories}`;
|
||||
return `${widgetApiEndpoints.chuckNorris}`;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
/* Make GET request to ChuckNorris API endpoint */
|
||||
fetchData() {
|
||||
axios.get(this.endpoint)
|
||||
.then((response) => {
|
||||
this.processData(response.data);
|
||||
})
|
||||
.catch((dataFetchError) => {
|
||||
this.error('Unable to fetch any Chuck Norris quote', dataFetchError);
|
||||
})
|
||||
.finally(() => {
|
||||
this.finishLoading();
|
||||
});
|
||||
},
|
||||
/* Assign data variables to the returned data */
|
||||
processData(data) {
|
||||
this.chuckNorrisLine = data.value;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.chuckNorris-wrapper {
|
||||
p.chuckNorris {
|
||||
color: var(--widget-text-color);
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
106
src/components/Widgets/CustomList.vue
Normal file
106
src/components/Widgets/CustomList.vue
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
<template>
|
||||
<div class="custom-list">
|
||||
<div class="custom-list-title" v-if="title">
|
||||
{{ title }}
|
||||
</div>
|
||||
<div v-for="(item, key) in data" :key="key" class="custom-list-row">
|
||||
<div v-if="item.link" class="custom-list-cell">
|
||||
<a :href="item.link.url" :title="item.link.title" target="_blank">
|
||||
{{ item.link.text }}
|
||||
</a>
|
||||
</div>
|
||||
<div v-if="item.value" class="custom-list-cell" :title="item.value.title">
|
||||
{{ item.value.text }}
|
||||
<span v-if="item.isNew" class="custom-list-new-value"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import WidgetMixin from '@/mixins/WidgetMixin';
|
||||
|
||||
export default {
|
||||
mixins: [WidgetMixin],
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
data: [],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
url() {
|
||||
return this.options.url || '';
|
||||
},
|
||||
title() {
|
||||
return this.options.title || '';
|
||||
},
|
||||
daysForNew() {
|
||||
return parseInt(Number(this.options.daysForNew)) || false;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
fetchData() {
|
||||
if (this.url) {
|
||||
this.startLoading();
|
||||
this.makeRequest(this.options.url).then(this.processData);
|
||||
}
|
||||
},
|
||||
processData(data) {
|
||||
let today = new Date();
|
||||
this.data = data.sort((a, b) => new Date(a.date) < new Date(b.date));
|
||||
if (this.daysForNew) {
|
||||
let threshold = this.daysForNew * 1000 * 60 * 60 * 24;
|
||||
this.data = this.data.map((item) => {
|
||||
item.isNew = (today - new Date(item.date) < threshold);
|
||||
return item;
|
||||
});
|
||||
}
|
||||
this.finishLoading();
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
.custom-list {
|
||||
.custom-list-title {
|
||||
outline: 2px solid transparent;
|
||||
border: 1px solid var(--outline-color);
|
||||
border-radius: var(--curve-factor);
|
||||
box-shadow: var(--item-shadow);
|
||||
color: var(--item-text-color);
|
||||
margin: .5rem;
|
||||
padding: 0.3rem;
|
||||
background: var(--item-background);
|
||||
text-align: center;
|
||||
|
||||
}
|
||||
.custom-list-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
color: var(--widget-text-color);
|
||||
font-size: 1.1rem;
|
||||
.custom-list-cell {
|
||||
display: inline-block;
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: var(--item-text-color);
|
||||
}
|
||||
.custom-list-new-value{
|
||||
width: 0.8rem;
|
||||
height: 0.8rem;
|
||||
border-radius: 50%;
|
||||
background-color: var(--success);
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
&:not(:last-child) {
|
||||
border-bottom: 1px dashed var(--widget-text-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -68,7 +68,7 @@ export default {
|
|||
networks.push({
|
||||
name: network.interface_name,
|
||||
speed: network.speed,
|
||||
online: network.speed ? 'up' : 'down', //v3 to v4 is_up no longer seems to be a default response field
|
||||
online: network.speed ? 'up' : 'down', // v3 to v4 is_up no longer seems to be a default response field
|
||||
currentDownload: network.bytes_recv,
|
||||
currentUpload: network.bytes_sent,
|
||||
totalDownload: network.bytes_recv_gauge,
|
||||
|
|
|
|||
258
src/components/Widgets/MinecraftStatus.vue
Normal file
258
src/components/Widgets/MinecraftStatus.vue
Normal file
|
|
@ -0,0 +1,258 @@
|
|||
<template>
|
||||
<div class="minecraft-wrapper">
|
||||
<a class="minecraft-link" :href="serverLinkEndpoint">
|
||||
<h3 class="minecraft-title">{{ title }}</h3>
|
||||
</a>
|
||||
<div class="minecraft-icon-wrapper">
|
||||
<img :src="icon" alt="server-icon" class="minecraft-icon" />
|
||||
</div>
|
||||
<div class="minecraft-content-wrapper">
|
||||
<StatusIndicator class="status-indicator" :statusSuccess="status ? online : undefined"
|
||||
:statusText="status ? statusTooltip : undefined" />
|
||||
<span v-if="title != server" class="minecraft-server">{{ server }}<br /></span>
|
||||
<span v-if="!online" class="minecraft-status">Server Offline</span>
|
||||
<span v-if="online" class="minecraft-version">
|
||||
{{ software || (bedrock ? "Bedrock" : "Minecraft") }} {{ version }}
|
||||
</span>
|
||||
<ul v-if="online" class="minecraft-motd">
|
||||
<li v-for="(line, idx) in motd" :key="idx">{{ line }}</li>
|
||||
</ul>
|
||||
<div v-if="showPlayers" class="player-list">
|
||||
<span>{{ onlinePlayers }}/{{ maxPlayers }} Players</span>
|
||||
<ul>
|
||||
<li v-for="{ name, uuid } in players" :key="uuid">
|
||||
<a :href="playerLinkEndpoint(uuid)">
|
||||
<img :src="playerIconEndpoint(uuid)" :alt="`${name}'s Head'`"/>{{ name }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div v-if="showMods" class="mod-list">
|
||||
<span>{{ mods.length }} Mods</span>
|
||||
<ul>
|
||||
<li v-for="{ name, version } in mods" :key="name">
|
||||
{{ name }}={{ version }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div v-if="showPlugins" class="plugin-list">
|
||||
<span>{{ plugins.length }} Plugins</span>
|
||||
<ul>
|
||||
<li v-for="{ name, version } in plugins" :key="name">
|
||||
{{ name }}={{ version }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import WidgetMixin from '@/mixins/WidgetMixin';
|
||||
import { widgetApiEndpoints } from '@/utils/defaults';
|
||||
import StatusIndicator from '@/components/LinkItems/StatusIndicator.vue';
|
||||
|
||||
export default {
|
||||
mixins: [WidgetMixin],
|
||||
components: {
|
||||
StatusIndicator,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
status: false,
|
||||
online: false,
|
||||
ip: '',
|
||||
port: 0,
|
||||
hostname: '',
|
||||
iconData: null,
|
||||
motd: null,
|
||||
version: null,
|
||||
software: null,
|
||||
gamemode: null,
|
||||
mods: [],
|
||||
plugins: [],
|
||||
players: [],
|
||||
onlinePlayers: null,
|
||||
maxPlayers: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
title() {
|
||||
return this.options.title || this.options.server || this.error('options.server not set');
|
||||
},
|
||||
alt() {
|
||||
return this.title;
|
||||
},
|
||||
icon() {
|
||||
return `https://api.mcsrvstat.us/icon/${this.server}`;
|
||||
},
|
||||
server() {
|
||||
return this.options.server || this.error('options.server not set');
|
||||
},
|
||||
bedrock() {
|
||||
return this.options.bedrock === true;
|
||||
},
|
||||
statusTooltip() {
|
||||
if (!this.status) {
|
||||
return 'Loading...';
|
||||
}
|
||||
if (!this.online) {
|
||||
return `${this.server} Offline`;
|
||||
}
|
||||
return `${this.onlinePlayers}/${this.maxPlayers} Online`;
|
||||
},
|
||||
showPlayers() {
|
||||
return this.options.showPlayers && this.players.length > 0;
|
||||
},
|
||||
showMods() {
|
||||
return this.options.showMods && this.mods.length > 0;
|
||||
},
|
||||
showPlugins() {
|
||||
return this.options.showPlugins && this.plugins.length > 0;
|
||||
},
|
||||
endpoint() {
|
||||
return `${widgetApiEndpoints.minecraftStatus}${this.bedrock ? 'bedrock/' : ''}3/${this.server}`;
|
||||
},
|
||||
serverLinkEndpoint() {
|
||||
return `${widgetApiEndpoints.minecraftServerLink}${this.server}`;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
playerIconEndpoint(uuid) {
|
||||
return `${widgetApiEndpoints.minecraftPlayerIcon}${uuid}/32.png`;
|
||||
},
|
||||
playerLinkEndpoint(uuid) {
|
||||
return `${widgetApiEndpoints.minecraftPlayerLink}${uuid}`;
|
||||
},
|
||||
/* Make GET request to McSrvStat.US API endpoint */
|
||||
fetchData() {
|
||||
this.startLoading();
|
||||
fetch(this.endpoint)
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
this.error('Network response was not ok');
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then(data => {
|
||||
this.processData(data);
|
||||
})
|
||||
.catch(dataFetchError => {
|
||||
this.error('Unable to fetch data', dataFetchError);
|
||||
})
|
||||
.finally(() => {
|
||||
this.finishLoading();
|
||||
});
|
||||
},
|
||||
/* Assign data variables to the returned data */
|
||||
processData(data) {
|
||||
this.online = data.online;
|
||||
this.ip = data.ip;
|
||||
this.port = data.port;
|
||||
this.hostname = data.hostname;
|
||||
if (this.online) {
|
||||
this.version = data.version;
|
||||
this.iconData = data.icon;
|
||||
this.software = data.software;
|
||||
this.gamemode = data.gamemode;
|
||||
this.motd = data.motd.clean || [];
|
||||
this.players = data.players.list || [];
|
||||
this.onlinePlayers = data.players.online;
|
||||
this.maxPlayers = data.players.max;
|
||||
this.mods = data.mods || [];
|
||||
this.plugins = data.plugins || [];
|
||||
}
|
||||
this.status = true;
|
||||
},
|
||||
update() {
|
||||
this.fetchData();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
.minecraft-wrapper {
|
||||
margin-top: -1em;
|
||||
display: grid;
|
||||
justify-content: center;
|
||||
grid-template-columns: 64px 1fr;
|
||||
color: var(--widget-text-color);
|
||||
padding-top: 0.5rem;
|
||||
|
||||
.minecraft-link {
|
||||
grid-column: 1 / span 2;
|
||||
text-decoration: none;
|
||||
|
||||
.minecraft-title {
|
||||
font-size: 1.2rem;
|
||||
margin: 0.25rem auto;
|
||||
border-bottom: 1px solid var(--widget-text-color);
|
||||
color: var(--widget-text-color);
|
||||
}
|
||||
}
|
||||
|
||||
.minecraft-icon {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
max-width: 64px;
|
||||
margin: 0.25rem auto 0;
|
||||
padding-top: 0.5rem;
|
||||
border-radius: var(--curve-factor);
|
||||
}
|
||||
|
||||
.minecraft-content-wrapper {
|
||||
position: relative;
|
||||
padding: 0.5rem;
|
||||
|
||||
ul.minecraft-motd {
|
||||
border-top: 1px dashed var(--widget-text-color);
|
||||
list-style-type: none;
|
||||
padding: 0.5rem 0;
|
||||
margin: 0.5rem 0 0 0;
|
||||
}
|
||||
|
||||
.player-list,
|
||||
.mod-list,
|
||||
.plugin-list {
|
||||
span {
|
||||
font-size: 1.2rem;
|
||||
border-top: 1px dashed var(--widget-text-color);
|
||||
padding: 0.25rem 0;
|
||||
display: block;
|
||||
}
|
||||
ul {
|
||||
list-style-type: '- ';
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
li {
|
||||
padding: 1rem 0;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.player-list {
|
||||
ul {
|
||||
li {
|
||||
padding: 0;
|
||||
list-style-type: none;
|
||||
img {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
float: left;
|
||||
position: relative;
|
||||
margin-right: 1em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style lang="scss">
|
||||
.minecraft-alt-tt {
|
||||
min-width: 20rem;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -38,7 +38,7 @@ export default {
|
|||
hostname() {
|
||||
const usersChoice = this.parseAsEnvVar(this.options.hostname);
|
||||
if (!usersChoice) this.error('You must specify the hostname for your Pi-Hole server');
|
||||
return usersChoice || 'http://pi.hole';
|
||||
return usersChoice;
|
||||
},
|
||||
apiKey() {
|
||||
const usersChoice = this.parseAsEnvVar(this.options.apiKey);
|
||||
|
|
@ -53,9 +53,7 @@ export default {
|
|||
hideInfo() { return this.options.hideInfo; },
|
||||
},
|
||||
filters: {
|
||||
capitalize(str) {
|
||||
return capitalize(str);
|
||||
},
|
||||
capitalize,
|
||||
},
|
||||
methods: {
|
||||
/* Make GET request to local pi-hole instance */
|
||||
|
|
|
|||
252
src/components/Widgets/PiHoleStatsV6.vue
Normal file
252
src/components/Widgets/PiHoleStatsV6.vue
Normal file
|
|
@ -0,0 +1,252 @@
|
|||
<template>
|
||||
<div class="pi-hole-stats-v6-wrapper">
|
||||
<!-- Current Status -->
|
||||
<div v-if="status && !hideStatus" class="status">
|
||||
<span class="status-lbl">{{ $t('widgets.pi-hole.status-heading') }}:</span>
|
||||
<span :class="`status-val ${getStatusColor(status)}`">{{ status | capitalize }}</span>
|
||||
</div>
|
||||
<!-- Block Pie Chart -->
|
||||
<p :id="chartId" class="block-pie"></p>
|
||||
<!-- More Data -->
|
||||
<div v-if="dataTable" class="data-table">
|
||||
<div class="data-table-row" v-for="(row, inx) in dataTable" :key="inx">
|
||||
<p class="row-label">{{ row.lbl }}</p>
|
||||
<p class="row-value">{{ row.val }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import WidgetMixin from '@/mixins/WidgetMixin';
|
||||
import ChartingMixin from '@/mixins/ChartingMixin';
|
||||
import { capitalize } from '@/utils/MiscHelpers';
|
||||
|
||||
export default {
|
||||
mixins: [WidgetMixin, ChartingMixin],
|
||||
data() {
|
||||
return {
|
||||
status: null,
|
||||
dataTable: null,
|
||||
csrfToken: null,
|
||||
sid: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
/* Let user select which comic to display: random, latest or a specific number */
|
||||
hostname() {
|
||||
const usersChoice = this.parseAsEnvVar(this.options.hostname);
|
||||
if (!usersChoice) this.error('You must specify the hostname for your Pi-Hole server');
|
||||
return usersChoice;
|
||||
},
|
||||
apiKey() {
|
||||
const usersChoice = this.parseAsEnvVar(this.options.apiKey);
|
||||
if (!usersChoice) this.error('App Password is required, please see the docs');
|
||||
return usersChoice;
|
||||
},
|
||||
hideStatus() { return this.options.hideStatus; },
|
||||
hideChart() { return this.options.hideChart; },
|
||||
hideInfo() { return this.options.hideInfo; },
|
||||
authHeader() {
|
||||
return {
|
||||
'X-FTL-SID': this.sid,
|
||||
'X-FTL-CSRF': this.csrfToken,
|
||||
Accept: 'application/json',
|
||||
};
|
||||
},
|
||||
authEndpoint() {
|
||||
return `${this.hostname}/api/auth`;
|
||||
},
|
||||
blockingStatusEndpoint() {
|
||||
return `${this.hostname}/api/dns/blocking`;
|
||||
},
|
||||
/* This is actually just the stats that are currently in memory, which amounts to 24hrs when the
|
||||
service first boots up, but will drift to be a little more than 24hrs worth of data as the
|
||||
server runs. If you need accurate stats to a particular timeframe, then the
|
||||
/api/stats/database/summary endpoint is the way to go. */
|
||||
statsEndpoint() {
|
||||
return `${this.hostname}/api/stats/summary`;
|
||||
},
|
||||
statsDatabaseEndpoint() {
|
||||
return `${this.hostname}/api/stats/database/summary`;
|
||||
},
|
||||
timestampTomorrowMidnight() {
|
||||
const calcDate = new Date();
|
||||
calcDate.setHours(0, 0, 0, 0);
|
||||
calcDate.setDate(calcDate.getDate() + 1);
|
||||
return parseInt(
|
||||
String(calcDate.getTime()).substring(0, String(calcDate.getTime()).length - 3),
|
||||
10,
|
||||
);
|
||||
},
|
||||
timestamp24HoursAgo() {
|
||||
const calcDate = new Date();
|
||||
calcDate.setDate(calcDate.getDate() - 1);
|
||||
return parseInt(
|
||||
String(calcDate.getTime()).substring(0, String(calcDate.getTime()).length - 3),
|
||||
10,
|
||||
);
|
||||
},
|
||||
},
|
||||
filters: {
|
||||
capitalize,
|
||||
},
|
||||
methods: {
|
||||
fetchData() {
|
||||
this.makeRequest(
|
||||
this.authEndpoint,
|
||||
{ 'Content-Type': 'application/json' },
|
||||
'POST',
|
||||
{ password: this.apiKey },
|
||||
)
|
||||
.then(this.processAuthData)
|
||||
.then(
|
||||
() => {
|
||||
if (!this.sid || !this.csrfToken) return;
|
||||
|
||||
Promise.all([
|
||||
this.fetchBlockingStatus(),
|
||||
this.fetchInMemoryStats(),
|
||||
this.fetchTodayStats(),
|
||||
this.fetchAllTimeStats(),
|
||||
]).then(this.processData);
|
||||
},
|
||||
);
|
||||
},
|
||||
processAuthData({ session }) {
|
||||
if (!session) {
|
||||
this.error('Missing session info in auth response');
|
||||
} else if (session.valid !== true) {
|
||||
this.error('Authentication failed: Invalid credentials or 2FA token required');
|
||||
} else {
|
||||
const { sid, csrf } = session;
|
||||
if (!sid || !csrf) {
|
||||
this.error('No CSRF token or SID received');
|
||||
} else {
|
||||
this.sid = sid;
|
||||
this.csrfToken = csrf;
|
||||
}
|
||||
}
|
||||
},
|
||||
fetchBlockingStatus() {
|
||||
return this.makeRequest(this.blockingStatusEndpoint, this.authHeader);
|
||||
},
|
||||
fetchInMemoryStats() {
|
||||
return this.makeRequest(this.statsEndpoint, this.authHeader);
|
||||
},
|
||||
fetchTodayStats() {
|
||||
const url = new URL(this.statsDatabaseEndpoint);
|
||||
url.searchParams.append('from', this.timestamp24HoursAgo);
|
||||
// Future date because we're looking for "up to present".
|
||||
url.searchParams.append('until', this.timestampTomorrowMidnight);
|
||||
return this.makeRequest(url.toString(), this.authHeader);
|
||||
},
|
||||
fetchAllTimeStats() {
|
||||
const url = new URL(this.statsDatabaseEndpoint);
|
||||
url.searchParams.append('from', 1); // Errors out with 0.
|
||||
url.searchParams.append('until', this.timestampTomorrowMidnight);
|
||||
return this.makeRequest(url.toString(), this.authHeader);
|
||||
},
|
||||
processData([blockingStatus, inMemoryStats, todayStats, allTimeStats]) {
|
||||
if (!this.hideStatus) {
|
||||
this.status = blockingStatus.blocking || 'unknown';
|
||||
}
|
||||
|
||||
if (!this.hideInfo) {
|
||||
this.dataTable = [
|
||||
{
|
||||
lbl: 'Active Clients',
|
||||
val: `${inMemoryStats.clients.active.toLocaleString('en-US')}/${allTimeStats.total_clients.toLocaleString('en-US')}`,
|
||||
},
|
||||
{ lbl: 'Ads Blocked Last 24 Hours', val: todayStats.sum_blocked.toLocaleString('en-US') },
|
||||
{ lbl: 'DNS Queries Last 24 Hours', val: todayStats.sum_queries.toLocaleString('en-US') },
|
||||
{ lbl: 'Total DNS Queries', val: allTimeStats.sum_queries.toLocaleString('en-US') },
|
||||
{
|
||||
lbl: 'Domains on Block List',
|
||||
val: inMemoryStats.gravity.domains_being_blocked.toLocaleString('en-US'),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
if (!this.hideChart) {
|
||||
this.generateBlockPie(
|
||||
Math.round(todayStats.percent_blocked * 10) / 10,
|
||||
);
|
||||
}
|
||||
},
|
||||
getStatusColor(status) {
|
||||
if (status === 'enabled') return 'green';
|
||||
if (status === 'disabled') return 'red';
|
||||
return 'blue';
|
||||
},
|
||||
/* Generate pie chart showing the proportion of queries blocked */
|
||||
generateBlockPie(blockedTodayPercentage) {
|
||||
const chartData = {
|
||||
labels: ['Blocked', 'Allowed'],
|
||||
datasets: [{
|
||||
values: [blockedTodayPercentage, 100 - blockedTodayPercentage],
|
||||
}],
|
||||
};
|
||||
return new this.Chart(`#${this.chartId}`, {
|
||||
title: 'Block Percent Last 24 Hours',
|
||||
data: chartData,
|
||||
type: 'donut',
|
||||
height: 250,
|
||||
strokeWidth: 18,
|
||||
colors: ['#f80363', '#20e253'],
|
||||
tooltipOptions: {
|
||||
formatTooltipY: d => `${Math.round(d * 10) / 10}%`,
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.pi-hole-stats-v6-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.status {
|
||||
margin: 0.5rem 0;
|
||||
.status-lbl {
|
||||
color: var(--widget-text-color);
|
||||
font-weight: bold;
|
||||
}
|
||||
.status-val {
|
||||
margin-left: 0.5rem;
|
||||
font-family: var(--font-monospace);
|
||||
&.green { color: var(--success); }
|
||||
&.red { color: var(--danger); }
|
||||
&.blue { color: var(--info); }
|
||||
}
|
||||
}
|
||||
img.block-percent-chart {
|
||||
margin: 0.5rem auto;
|
||||
max-width: 8rem;
|
||||
width: 100%;
|
||||
}
|
||||
.block-pie {
|
||||
margin: 0;
|
||||
}
|
||||
.data-table {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.data-table-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
p {
|
||||
margin: 0.2rem 0;
|
||||
color: var(--widget-text-color);
|
||||
font-size: 0.9rem;
|
||||
&.row-value {
|
||||
font-family: var(--font-monospace);
|
||||
}
|
||||
}
|
||||
&:not(:last-child) {
|
||||
border-bottom: 1px dashed var(--widget-text-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -103,5 +103,4 @@ export default {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
|||
159
src/components/Widgets/PiHoleTopQueriesV6.vue
Normal file
159
src/components/Widgets/PiHoleTopQueriesV6.vue
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
<template>
|
||||
<div class="pi-hole-queries-wrapper" v-if="results">
|
||||
<div v-for="section in results" :key="section.id" class="query-section">
|
||||
<p class="section-title">{{ section.title }}</p>
|
||||
<div v-for="(query, i) in section.results" :key="i" class="query-row">
|
||||
<p class="domain">{{ query.domain }}</p>
|
||||
<p class="count">{{ query.count }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import WidgetMixin from '@/mixins/WidgetMixin';
|
||||
import { showNumAsThousand } from '@/utils/MiscHelpers';
|
||||
|
||||
export default {
|
||||
mixins: [WidgetMixin],
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
results: null,
|
||||
csrfToken: null,
|
||||
sid: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
/* Let user select which comic to display: random, latest or a specific number */
|
||||
hostname() {
|
||||
const usersChoice = this.parseAsEnvVar(this.options.hostname);
|
||||
if (!usersChoice) this.error('You must specify the hostname for your Pi-Hole server');
|
||||
return usersChoice;
|
||||
},
|
||||
apiKey() {
|
||||
const usersChoice = this.parseAsEnvVar(this.options.apiKey);
|
||||
if (!usersChoice) this.error('App Password is required, please see the docs');
|
||||
return usersChoice;
|
||||
},
|
||||
count() {
|
||||
const usersChoice = this.options.count;
|
||||
if (usersChoice && typeof usersChoice === 'number') return usersChoice;
|
||||
return 10;
|
||||
},
|
||||
authHeader() {
|
||||
return {
|
||||
'X-FTL-SID': this.sid,
|
||||
'X-FTL-CSRF': this.csrfToken,
|
||||
Accept: 'application/json',
|
||||
};
|
||||
},
|
||||
authEndpoint() {
|
||||
return `${this.hostname}/api/auth`;
|
||||
},
|
||||
/* This is actually just the stats that are shown on the Pi-Hole dashboard, which amounts to
|
||||
24hrs when the service first boots up, but will drift to be a little more than 24hrs worth of
|
||||
data as the server runs. If you need accurate stats to a particular timeframe, then the
|
||||
/api/stats/database/top_domains endpoint is the way to go. However, that endpoint does not
|
||||
return sorted results, so you would have to get everything and sort it yourself, which presents
|
||||
logistical problems. */
|
||||
topDomainsEndpoint() {
|
||||
return `${this.hostname}/api/stats/top_domains`;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
fetchData() {
|
||||
this.makeRequest(
|
||||
this.authEndpoint,
|
||||
{ 'Content-Type': 'application/json' },
|
||||
'POST',
|
||||
{ password: this.apiKey },
|
||||
)
|
||||
.then(this.processAuthData)
|
||||
.then(
|
||||
() => {
|
||||
if (!this.sid || !this.csrfToken) return;
|
||||
|
||||
Promise.all([
|
||||
this.fetchTopAllowedDomains(),
|
||||
this.fetchTopBlockedDomains(),
|
||||
]).then(this.processData);
|
||||
},
|
||||
);
|
||||
},
|
||||
processAuthData({ session }) {
|
||||
if (!session) {
|
||||
this.error('Missing session info in auth response');
|
||||
} else if (session.valid !== true) {
|
||||
this.error('Authentication failed: Invalid credentials or 2FA token required');
|
||||
} else {
|
||||
const { sid, csrf } = session;
|
||||
if (!sid || !csrf) {
|
||||
this.error('No CSRF token or SID received');
|
||||
} else {
|
||||
this.sid = sid;
|
||||
this.csrfToken = csrf;
|
||||
}
|
||||
}
|
||||
},
|
||||
fetchTopAllowedDomains() {
|
||||
const url = new URL(this.topDomainsEndpoint);
|
||||
url.searchParams.append('blocked', false);
|
||||
url.searchParams.append('count', this.count);
|
||||
return this.makeRequest(url.toString(), this.authHeader);
|
||||
},
|
||||
fetchTopBlockedDomains() {
|
||||
const url = new URL(this.topDomainsEndpoint);
|
||||
url.searchParams.append('blocked', true);
|
||||
url.searchParams.append('count', this.count);
|
||||
return this.makeRequest(url.toString(), this.authHeader);
|
||||
},
|
||||
processData([topAllowedDomains, topBlockedDomains]) {
|
||||
const topAds = [];
|
||||
topBlockedDomains.domains.forEach(({ domain, count }) => {
|
||||
topAds.push({ domain, count: showNumAsThousand(count) });
|
||||
});
|
||||
const topQueries = [];
|
||||
topAllowedDomains.domains.forEach(({ domain, count }) => {
|
||||
topQueries.push({ domain, count: showNumAsThousand(count) });
|
||||
});
|
||||
this.results = [
|
||||
{ id: '01', title: 'Top Ads Blocked', results: topAds },
|
||||
{ id: '02', title: 'Top Queries', results: topQueries },
|
||||
];
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.pi-hole-queries-wrapper {
|
||||
color: var(--widget-text-color);
|
||||
.query-section {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
p.section-title {
|
||||
margin: 0.75rem 0 0.25rem;
|
||||
font-size: 1.2rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
.query-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin: 0.25rem;
|
||||
p.domain {
|
||||
margin: 0.25rem 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
p.count {
|
||||
margin: 0.25rem 0;
|
||||
font-family: var(--font-monospace);
|
||||
}
|
||||
&:not(:last-child) {
|
||||
border-bottom: 1px dashed var(--widget-text-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
130
src/components/Widgets/PiHoleTrafficV6.vue
Normal file
130
src/components/Widgets/PiHoleTrafficV6.vue
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
<template>
|
||||
<div :id="chartId" class="pi-hole-traffic"></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import WidgetMixin from '@/mixins/WidgetMixin';
|
||||
import ChartingMixin from '@/mixins/ChartingMixin';
|
||||
|
||||
export default {
|
||||
mixins: [WidgetMixin, ChartingMixin],
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
csrfToken: null,
|
||||
sid: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
/* Let user select which comic to display: random, latest or a specific number */
|
||||
hostname() {
|
||||
const usersChoice = this.parseAsEnvVar(this.options.hostname);
|
||||
if (!usersChoice) this.error('You must specify the hostname for your Pi-Hole server');
|
||||
return usersChoice;
|
||||
},
|
||||
apiKey() {
|
||||
const usersChoice = this.parseAsEnvVar(this.options.apiKey);
|
||||
if (!usersChoice) this.error('App Password is required, please see the docs');
|
||||
return usersChoice;
|
||||
},
|
||||
authHeader() {
|
||||
return {
|
||||
'X-FTL-SID': this.sid,
|
||||
'X-FTL-CSRF': this.csrfToken,
|
||||
Accept: 'application/json',
|
||||
};
|
||||
},
|
||||
authEndpoint() {
|
||||
return `${this.hostname}/api/auth`;
|
||||
},
|
||||
historyEndpoint() {
|
||||
return `${this.hostname}/api/history`;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
fetchData() {
|
||||
this.makeRequest(
|
||||
this.authEndpoint,
|
||||
{ 'Content-Type': 'application/json' },
|
||||
'POST',
|
||||
{ password: this.apiKey },
|
||||
)
|
||||
.then(this.processAuthData)
|
||||
.then(
|
||||
() => {
|
||||
if (!this.sid || !this.csrfToken) return;
|
||||
|
||||
this.fetchHistory().then((response) => {
|
||||
if (this.validate(response)) {
|
||||
this.processData(response);
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
},
|
||||
processAuthData({ session }) {
|
||||
if (!session) {
|
||||
this.error('Missing session info in auth response');
|
||||
} else if (session.valid !== true) {
|
||||
this.error('Authentication failed: Invalid credentials or 2FA token required');
|
||||
} else {
|
||||
const { sid, csrf } = session;
|
||||
if (!sid || !csrf) {
|
||||
this.error('No CSRF token or SID received');
|
||||
} else {
|
||||
this.sid = sid;
|
||||
this.csrfToken = csrf;
|
||||
}
|
||||
}
|
||||
},
|
||||
fetchHistory() {
|
||||
return this.makeRequest(this.historyEndpoint, this.authHeader);
|
||||
},
|
||||
validate(data) {
|
||||
if (!data || !Array.isArray(data['history'])) {
|
||||
this.error('Got success, but found no results, possible authorization error');
|
||||
} else if (data.history.length < 1) {
|
||||
this.error('Request completed succesfully, but no data in Pi-Hole yet');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
processData({ history }) {
|
||||
const timeData = [];
|
||||
const domainsData = [];
|
||||
const adsData = [];
|
||||
history.forEach(({ timestamp, total, blocked }) => {
|
||||
timeData.push(this.formatTime(timestamp * 1000));
|
||||
domainsData.push(total - blocked);
|
||||
adsData.push(blocked);
|
||||
});
|
||||
const chartData = {
|
||||
labels: timeData,
|
||||
datasets: [
|
||||
{ name: 'Queries', type: 'bar', values: domainsData },
|
||||
{ name: 'Ads Blocked', type: 'bar', values: adsData },
|
||||
],
|
||||
};
|
||||
this.generateChart(chartData);
|
||||
},
|
||||
generateChart(chartData) {
|
||||
return new this.Chart(`#${this.chartId}`, {
|
||||
title: 'Recent Queries & Ads',
|
||||
data: chartData,
|
||||
type: 'axis-mixed',
|
||||
height: this.chartHeight,
|
||||
colors: ['#20e253', '#f80363'],
|
||||
truncateLegends: true,
|
||||
lineOptions: {
|
||||
regionFill: 1,
|
||||
hideDots: 1,
|
||||
},
|
||||
axisOptions: {
|
||||
xIsSeries: true,
|
||||
xAxisMode: 'tick',
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -26,7 +26,7 @@ export default {
|
|||
return `${widgetApiEndpoints.publicIp2}?apiKey=${this.apiKey}`;
|
||||
} else if (this.provider === 'ip2location.io') {
|
||||
return `${widgetApiEndpoints.publicIp4}?key=${this.apiKey}`;
|
||||
} else if (this.provider === 'ipapi') {
|
||||
} else if (this.provider === 'ip-api') {
|
||||
return widgetApiEndpoints.publicIp3;
|
||||
}
|
||||
return widgetApiEndpoints.publicIp;
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ export default {
|
|||
const posts = [];
|
||||
let { length } = items;
|
||||
if (this.limit) {
|
||||
length = this.limit;
|
||||
length = Math.min(length, this.limit);
|
||||
}
|
||||
for (let i = 0; length > i; i += 1) {
|
||||
posts.push({
|
||||
|
|
|
|||
|
|
@ -60,10 +60,10 @@ export default {
|
|||
},
|
||||
/* Create authorisation header for the instance from the apiKey */
|
||||
authHeaders() {
|
||||
if (!this.options.apiKey) {
|
||||
if (!this.apiKey) {
|
||||
return {};
|
||||
}
|
||||
const encoded = window.btoa(`:${this.options.apiKey}`);
|
||||
const encoded = window.btoa(`:${this.apiKey}`);
|
||||
return { Authorization: `Basic ${encoded}` };
|
||||
},
|
||||
},
|
||||
|
|
@ -144,7 +144,7 @@ export default {
|
|||
return copy;
|
||||
},
|
||||
getRowValue(row) {
|
||||
return this.getValueWithRegex(row, /\b\d+\b$/);
|
||||
return this.getValueWithRegex(row, /\b(\d+)(\.\d+)*\b$/);
|
||||
},
|
||||
getRowMonitorName(row) {
|
||||
return this.getValueWithRegex(row, /monitor_name="([^"]+)"/);
|
||||
|
|
@ -193,7 +193,7 @@ export default {
|
|||
white-space: nowrap;
|
||||
vertical-align: baseline;
|
||||
padding: .35em .65em;
|
||||
margin: 1em 0.5em;
|
||||
margin: 0.1em 0.5em;
|
||||
min-width: 64px;
|
||||
|
||||
&.up {
|
||||
|
|
|
|||
|
|
@ -49,14 +49,16 @@ const COMPAT = {
|
|||
anonaddy: 'addy.io',
|
||||
apod: 'Apod',
|
||||
'blacklist-check': 'BlacklistCheck',
|
||||
chucknorris: 'ChuckNorris',
|
||||
clock: 'Clock',
|
||||
'code-stats': 'CodeStats',
|
||||
'covid-stats': 'CovidStats',
|
||||
'crypto-price-chart': 'CryptoPriceChart',
|
||||
'crypto-watch-list': 'CryptoWatchList',
|
||||
'custom-search': 'CustomSearch',
|
||||
'custom-list': 'CustomList',
|
||||
'cve-vulnerabilities': 'CveVulnerabilities',
|
||||
'domain-monitor': 'DomainMonitor',
|
||||
'code-stats': 'CodeStats',
|
||||
'covid-stats': 'CovidStats',
|
||||
'drone-ci': 'DroneCi',
|
||||
embed: 'EmbedWidget',
|
||||
'eth-gas-prices': 'EthGasPrices',
|
||||
|
|
@ -80,15 +82,16 @@ const COMPAT = {
|
|||
'gl-network-traffic': 'GlNetworkTraffic',
|
||||
'gl-system-load': 'GlSystemLoad',
|
||||
'gl-cpu-temp': 'GlCpuTemp',
|
||||
'gluetun-status': 'GluetunStatus',
|
||||
'health-checks': 'HealthChecks',
|
||||
'hackernews-trending': 'HackernewsTrending',
|
||||
'gluetun-status': 'GluetunStatus',
|
||||
iframe: 'IframeWidget',
|
||||
image: 'ImageWidget',
|
||||
joke: 'Jokes',
|
||||
linkding: 'Linkding',
|
||||
'minecraft-status': 'MinecraftStatus',
|
||||
'mullvad-status': 'MullvadStatus',
|
||||
mvg: 'Mvg',
|
||||
linkding: 'Linkding',
|
||||
'mvg-connection': 'MvgConnection',
|
||||
'nd-cpu-history': 'NdCpuHistory',
|
||||
'nd-load-history': 'NdLoadHistory',
|
||||
|
|
@ -101,8 +104,11 @@ const COMPAT = {
|
|||
'nextcloud-user': 'NextcloudUser',
|
||||
'nextcloud-user-status': 'NextcloudUserStatus',
|
||||
'pi-hole-stats': 'PiHoleStats',
|
||||
'pi-hole-stats-v6': 'PiHoleStatsV6',
|
||||
'pi-hole-top-queries': 'PiHoleTopQueries',
|
||||
'pi-hole-top-queries-v6': 'PiHoleTopQueriesV6',
|
||||
'pi-hole-traffic': 'PiHoleTraffic',
|
||||
'pi-hole-traffic-v6': 'PiHoleTrafficV6',
|
||||
'proxmox-lists': 'Proxmox',
|
||||
'public-holidays': 'PublicHolidays',
|
||||
'public-ip': 'PublicIp',
|
||||
|
|
|
|||
|
|
@ -136,6 +136,14 @@ const ThemingMixin = {
|
|||
} else if (hasExternal) {
|
||||
this.applyRemoteTheme(this.externalThemes[initialTheme]);
|
||||
}
|
||||
|
||||
// Detect OS theme preference and apply the corresponding theme
|
||||
const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
const osTheme = prefersDark ? this.appConfig.nightTheme : this.appConfig.dayTheme;
|
||||
if (osTheme) {
|
||||
this.$store.commit(Keys.SET_THEME, osTheme);
|
||||
this.updateTheme(osTheme);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1142,6 +1142,104 @@ html[data-theme='glow'], html[data-theme=glow-colorful] {
|
|||
}
|
||||
}
|
||||
|
||||
html[data-theme='glow-dark'] {
|
||||
--primary: #8faeff;
|
||||
--background: #11111b;
|
||||
--background-darker: #0a0a0f;
|
||||
--curve-factor: 12px;
|
||||
--item-group-background: #1b1b29;
|
||||
--item-group-outer-background: #171724;
|
||||
--item-background: #1d1d2b;
|
||||
--font-headings: 'Sniglet', cursive;
|
||||
|
||||
--item-group-heading-text-color: var(--primary);
|
||||
--item-group-heading-text-color-hover: #a0bfff;
|
||||
--item-group-shadow: 0 5px 16px 0 #5c6da933;
|
||||
--item-background-hover: #33334d;
|
||||
--item-shadow: 0 1px 5px 0 #5c6da980;
|
||||
--item-hover-shadow: 0 1px 8px 0 #5c6da9a6;
|
||||
--item-icon-transform: drop-shadow(1px 2px 3px var(--transparent-50)) saturate(1.1);
|
||||
--item-icon-transform-hover: drop-shadow(1px 2px 4px var(--transparent-50)) saturate(1.1);
|
||||
--footer-height: 120px;
|
||||
--transparent-50: #00000080;
|
||||
|
||||
header {
|
||||
padding: 0.5rem;
|
||||
background: var(--background-darker);
|
||||
.page-titles {
|
||||
h1 {
|
||||
font-size: 1.8rem;
|
||||
color: var(--primary);
|
||||
}
|
||||
span.subtitle {
|
||||
font-size: 0.8rem;
|
||||
color: #ccc;
|
||||
text-shadow: none;
|
||||
}
|
||||
}
|
||||
.nav .nav-item {
|
||||
padding: 0.2rem 0.4rem;
|
||||
box-shadow: none;
|
||||
color: #ddd;
|
||||
}
|
||||
}
|
||||
|
||||
.settings-outer {
|
||||
box-shadow: 0 4px 5px 0 #5c6da91a;
|
||||
.options-container {
|
||||
padding: 0.25rem 1.5rem 0.25rem 1rem;
|
||||
background: var(--background-darker);
|
||||
}
|
||||
}
|
||||
|
||||
footer {
|
||||
background: var(--background-darker);
|
||||
box-shadow: 0 -4px 5px 0 #5c6da91a;
|
||||
}
|
||||
|
||||
.search-wrap input {
|
||||
background: #2a2a3d;
|
||||
color: #eee;
|
||||
box-shadow: 0 1px 5px 0 #5c6da980;
|
||||
}
|
||||
|
||||
div.collapsable:nth-child(1n) {
|
||||
a.item { color: #a88bff; }
|
||||
--item-group-shadow: 0 5px 16px 0 #9f72ff33;
|
||||
--item-group-heading-text-color: #bfa2ff;
|
||||
--item-group-heading-text-color-hover: #cbb8ff;
|
||||
--item-background-hover: #3a3a55;
|
||||
--item-shadow: 0 1px 5px 0 #8656ef80;
|
||||
--item-hover-shadow: 0 1px 8px 0 #8656efa6;
|
||||
--item-icon-transform: drop-shadow(1px 2px 3px #8656ef80) saturate(1.1);
|
||||
--item-icon-transform-hover: drop-shadow(1px 2px 4px #8656ef80) saturate(1.1);
|
||||
}
|
||||
|
||||
div.collapsable:nth-child(2n) {
|
||||
a.item { color: #e58fff; }
|
||||
--item-group-shadow: 0 5px 16px 0 #728cff33;
|
||||
--item-group-heading-text-color: #eaaaff;
|
||||
--item-group-heading-text-color-hover: #f0c2ff;
|
||||
--item-background-hover: #3a3a55;
|
||||
--item-shadow: 0 1px 5px 0 #d356ef80;
|
||||
--item-hover-shadow: 0 1px 8px 0 #d356efa6;
|
||||
--item-icon-transform: drop-shadow(1px 2px 3px #d356ef80) saturate(1.1);
|
||||
--item-icon-transform-hover: drop-shadow(1px 2px 4px #d356ef80) saturate(1.1);
|
||||
}
|
||||
|
||||
div.collapsable:nth-child(3n) {
|
||||
a.item { color: #56e0f0; }
|
||||
--item-group-shadow: 0 5px 16px 0 #728cff33;
|
||||
--item-group-heading-text-color: #7feeff;
|
||||
--item-group-heading-text-color-hover: #a0f5ff;
|
||||
--item-background-hover: #3a3a55;
|
||||
--item-shadow: 0 1px 5px 0 #56ddef80;
|
||||
--item-hover-shadow: 0 1px 8px 0 #56ddefa6;
|
||||
--item-icon-transform: drop-shadow(1px 2px 3px #56ddef80) saturate(1.1);
|
||||
--item-icon-transform-hover: drop-shadow(1px 2px 4px #56ddef80) saturate(1.1);
|
||||
}
|
||||
}
|
||||
|
||||
html[data-theme='cyberpunk'] {
|
||||
--pink: #ff2a6d;
|
||||
--pale: #d1f7ff;
|
||||
|
|
|
|||
|
|
@ -31,7 +31,19 @@ const getUsers = () => {
|
|||
return []; // Support for old data structure now removed
|
||||
}
|
||||
// Otherwise, return the users array, if available
|
||||
return auth.users || [];
|
||||
|
||||
const users = auth.users || [];
|
||||
if (isOidcEnabled()) {
|
||||
if (localStorage[localStorageKeys.USERNAME]) {
|
||||
const user = {
|
||||
user: localStorage[localStorageKeys.USERNAME],
|
||||
type: localStorage[localStorageKeys.ISADMIN] === 'true' ? 'admin' : 'normal',
|
||||
};
|
||||
users.push(user);
|
||||
}
|
||||
}
|
||||
|
||||
return users;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -80,6 +92,17 @@ export const makeBasicAuthHeaders = () => {
|
|||
export const isLoggedIn = () => {
|
||||
const users = getUsers();
|
||||
const cookieToken = getCookieToken();
|
||||
|
||||
if (isOidcEnabled()) {
|
||||
const username = localStorage[localStorageKeys.USERNAME]; // Get username
|
||||
if (!username) return false; // No username
|
||||
return users.some((user) => {
|
||||
if (user.user === username || generateUserToken(user) === cookieToken) {
|
||||
return true;
|
||||
} else return false;
|
||||
});
|
||||
}
|
||||
|
||||
return users.some((user) => {
|
||||
if (generateUserToken(user) === cookieToken) {
|
||||
localStorage.setItem(localStorageKeys.USERNAME, user.user);
|
||||
|
|
|
|||
|
|
@ -566,6 +566,18 @@
|
|||
"type": "string",
|
||||
"description": "ClientId from OIDC provider"
|
||||
},
|
||||
"adminRole" : {
|
||||
"title": "Admin Role",
|
||||
"type": "string",
|
||||
"default": false,
|
||||
"description": "The role that will be considered as admin. If not set, no roles will be considered as admin"
|
||||
},
|
||||
"adminGroup" : {
|
||||
"title": "Admin Group",
|
||||
"type": "string",
|
||||
"default": false,
|
||||
"description": "The group that will be considered as admin. If not set, no groups will be considered as admin"
|
||||
},
|
||||
"scope" : {
|
||||
"title": "OIDC Scope",
|
||||
"type": "string",
|
||||
|
|
@ -941,7 +953,7 @@
|
|||
"title": "Icon",
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "An icon, either as a font-awesome, simple-icon or mdi identifier, emoji, favicon, generative or the URL/ path to a local or remote icon asset"
|
||||
"description": "An icon, either as a font-awesome, simple-icon, selfh.st, or mdi identifier, emoji, favicon, generative or the URL/path to a local or remote icon asset"
|
||||
},
|
||||
"url": {
|
||||
"title": "Service URL",
|
||||
|
|
|
|||
|
|
@ -13,7 +13,13 @@ const getAppConfig = () => {
|
|||
class OidcAuth {
|
||||
constructor() {
|
||||
const { auth } = getAppConfig();
|
||||
const { clientId, endpoint, scope } = auth.oidc;
|
||||
const {
|
||||
clientId,
|
||||
endpoint,
|
||||
scope,
|
||||
adminGroup,
|
||||
adminRole,
|
||||
} = auth.oidc;
|
||||
const settings = {
|
||||
userStore: new WebStorageStateStore({ store: window.localStorage }),
|
||||
authority: endpoint,
|
||||
|
|
@ -25,6 +31,8 @@ class OidcAuth {
|
|||
filterProtocolClaims: true,
|
||||
};
|
||||
|
||||
this.adminGroup = adminGroup;
|
||||
this.adminRole = adminRole;
|
||||
this.userManager = new UserManager(settings);
|
||||
}
|
||||
|
||||
|
|
@ -43,22 +51,27 @@ class OidcAuth {
|
|||
if (user === null) {
|
||||
await this.userManager.signinRedirect();
|
||||
} else {
|
||||
const { roles, groups } = user.profile;
|
||||
const { roles = [], groups = [] } = user.profile;
|
||||
const info = {
|
||||
groups,
|
||||
roles,
|
||||
};
|
||||
const isAdmin = (Array.isArray(groups) && groups.includes(this.adminGroup))
|
||||
|| (Array.isArray(roles) && roles.includes(this.adminRole))
|
||||
|| false;
|
||||
|
||||
statusMsg(`user: ${user.profile.preferred_username}`, JSON.stringify(info));
|
||||
statusMsg(`user: ${user.profile.preferred_username} admin: ${isAdmin}`, JSON.stringify(info));
|
||||
|
||||
localStorage.setItem(localStorageKeys.KEYCLOAK_INFO, JSON.stringify(info));
|
||||
localStorage.setItem(localStorageKeys.USERNAME, user.profile.preferred_username);
|
||||
localStorage.setItem(localStorageKeys.ISADMIN, isAdmin);
|
||||
}
|
||||
}
|
||||
|
||||
async logout() {
|
||||
localStorage.removeItem(localStorageKeys.USERNAME);
|
||||
localStorage.removeItem(localStorageKeys.KEYCLOAK_INFO);
|
||||
localStorage.removeItem(localStorageKeys.ISADMIN);
|
||||
|
||||
try {
|
||||
await this.userManager.signoutRedirect();
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ module.exports = {
|
|||
'bee',
|
||||
'tiger',
|
||||
'glow',
|
||||
'glow-dark',
|
||||
'vaporware',
|
||||
'cyberpunk',
|
||||
'material-original',
|
||||
|
|
@ -136,6 +137,7 @@ module.exports = {
|
|||
MOST_USED: 'mostUsed',
|
||||
LAST_USED: 'lastUsed',
|
||||
KEYCLOAK_INFO: 'keycloakInfo',
|
||||
ISADMIN: 'isAdmin',
|
||||
DISABLE_CRITICAL_WARNING: 'disableCriticalWarning',
|
||||
},
|
||||
/* Key names for cookie identifiers */
|
||||
|
|
@ -210,6 +212,7 @@ module.exports = {
|
|||
fa: 'https://kit.fontawesome.com',
|
||||
mdi: 'https://cdn.jsdelivr.net/npm/@mdi/font@7.0.96/css/materialdesignicons.min.css',
|
||||
si: 'https://unpkg.com/simple-icons@v7/icons',
|
||||
sh: 'https://cdn.jsdelivr.net/gh/selfhst/icons@latest/webp/{icon}.webp',
|
||||
generative: 'https://api.dicebear.com/7.x/identicon/svg?seed={icon}',
|
||||
generativeFallback: 'https://evatar.io/{icon}',
|
||||
localPath: './item-icons',
|
||||
|
|
@ -224,6 +227,7 @@ module.exports = {
|
|||
anonAddy: 'https://app.addy.io',
|
||||
astronomyPictureOfTheDay: 'https://apod.as93.net/apod',
|
||||
blacklistCheck: 'https://api.blacklistchecker.com/check',
|
||||
chuckNorris: 'https://api.chucknorris.io/jokes/random',
|
||||
codeStats: 'https://codestats.net/',
|
||||
covidStats: 'https://disease.sh/v3/covid-19',
|
||||
cryptoPrices: 'https://api.coingecko.com/api/v3/coins/',
|
||||
|
|
@ -240,6 +244,10 @@ module.exports = {
|
|||
holidays: 'https://kayaposoft.com/enrico/json/v2.0/?action=getHolidaysForDateRange',
|
||||
jokes: 'https://v2.jokeapi.dev/joke/',
|
||||
news: 'https://api.currentsapi.services/v1/latest-news',
|
||||
minecraftPlayerIcon: 'https://mc-heads.net/avatar/',
|
||||
minecraftPlayerLink: 'https://minecraftuuid.com/?search=',
|
||||
minecraftServerLink: 'https://mcsrvstat.us/server/',
|
||||
minecraftStatus: 'https://api.mcsrvstat.us/',
|
||||
mullvad: 'https://am.i.mullvad.net/json',
|
||||
mvg: 'https://www.mvg.de/api/fib/v2/',
|
||||
publicIp: 'https://ipapi.co/json',
|
||||
|
|
@ -312,7 +320,6 @@ module.exports = {
|
|||
/* Progressive Web App settings, used by Vue Config */
|
||||
pwa: {
|
||||
name: 'Dashy',
|
||||
manifestPath: './manifest.json',
|
||||
themeColor: '#00af87',
|
||||
msTileColor: '#0b1021',
|
||||
mode: 'production',
|
||||
|
|
@ -324,5 +331,26 @@ module.exports = {
|
|||
maskIcon: './web-icons/dashy-logo.png',
|
||||
msTileImage: './web-icons/dashy-logo.png',
|
||||
},
|
||||
workboxOptions: {
|
||||
exclude: [
|
||||
// https://developer.chrome.com/docs/workbox/modules/workbox-build#properties_14
|
||||
/\.map$/,
|
||||
/^manifest.*\.js$/, // default value
|
||||
/\.nojekyll$/,
|
||||
/\.gitignore$/,
|
||||
/conf\.yml$/, // ignore config for runtimeCaching
|
||||
],
|
||||
// https://developer.chrome.com/docs/workbox/modules/workbox-build#type-RuntimeCaching
|
||||
runtimeCaching: [
|
||||
{
|
||||
urlPattern: /conf\.yml$/,
|
||||
handler: 'NetworkFirst',
|
||||
options: {
|
||||
cacheName: 'config-cache',
|
||||
networkTimeoutSeconds: 3,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ import sk from '@/assets/locales/sk.json';
|
|||
import sl from '@/assets/locales/sl.json';
|
||||
import sv from '@/assets/locales/sv.json';
|
||||
import tr from '@/assets/locales/tr.json';
|
||||
import ua from '@/assets/locales/ua.json';
|
||||
import uk from '@/assets/locales/uk.json';
|
||||
import zhCN from '@/assets/locales/zh-CN.json';
|
||||
import zhTW from '@/assets/locales/zh-TW.json';
|
||||
import pirate from '@/assets/locales/zz-pirate.json';
|
||||
|
|
@ -184,8 +184,8 @@ export const languages = [
|
|||
},
|
||||
{ // Ukrainian
|
||||
name: 'Ukrainian',
|
||||
code: 'ua',
|
||||
locale: ua,
|
||||
code: 'uk',
|
||||
locale: uk,
|
||||
flag: '🇺🇦',
|
||||
},
|
||||
{ // Chinese
|
||||
|
|
|
|||
|
|
@ -75,8 +75,9 @@ export default {
|
|||
},
|
||||
},
|
||||
mounted() {
|
||||
this.setTheme();
|
||||
this.initiateFontAwesome();
|
||||
this.initiateMaterialDesignIcons();
|
||||
this.setTheme();
|
||||
this.url = this.getInitialUrl();
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"incremental": true,
|
||||
"tsBuildInfoFile": "/app/.tsbuildinfo",
|
||||
"target": "esnext",
|
||||
"module": "esnext",
|
||||
"strict": false,
|
||||
|
|
|
|||
|
|
@ -96,5 +96,8 @@ module.exports = {
|
|||
devServer,
|
||||
chainWebpack: config => {
|
||||
config.module.rules.delete('svg');
|
||||
config.cache({
|
||||
type: 'filesystem',
|
||||
});
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9201,10 +9201,10 @@ signal-exit@^3.0.0, signal-exit@^3.0.2:
|
|||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
|
||||
integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
|
||||
|
||||
simple-icons@^12.2.0:
|
||||
version "12.2.0"
|
||||
resolved "https://registry.yarnpkg.com/simple-icons/-/simple-icons-12.2.0.tgz#dade5fdcb8f9d7833e7b8630028bda45c7867f25"
|
||||
integrity sha512-q8Qpts9HIW1PP1gdwT2/NqJBgou3XG44Z4xDGvdqFZYG+eINDyHu7PEidHkPFHpP5TLcB9s4Ne70Uy5u83u7Ig==
|
||||
simple-icons@^14.4.0:
|
||||
version "14.4.0"
|
||||
resolved "https://registry.yarnpkg.com/simple-icons/-/simple-icons-14.4.0.tgz#64226b8deb841bcffe4c42b269049753297f6e11"
|
||||
integrity sha512-eR4WWGF2/dMn6Na7wQZ9nUnGQg4CC9MnqYUlKKfIO0kQ79BdwyFS2L+X/MIxArULsh/IE0U48d4r9N4JVPicIQ==
|
||||
|
||||
simple-swizzle@^0.2.2:
|
||||
version "0.2.2"
|
||||
|
|
|
|||
Loading…
Reference in a new issue