Merge branch 'master' into opt1-search

This commit is contained in:
aspen 2025-11-13 20:35:56 +00:00
commit d1c5a42c08
8 changed files with 670 additions and 9 deletions

View file

@ -8,6 +8,16 @@
<b><a href="./docs/showcase.md">User Showcase</a></b> | <b><a href="https://demo.dashy.to">Live Demo</a></b> | <b><a href="./docs/quick-start.md">Getting Started</a></b> | <b><a href="https://dashy.to/docs">Documentation</a></b> | <b><a href="https://github.com/Lissy93/dashy">GitHub</a></b>
</p>
---
<p align="center">
<sup>Dashy is kindly sponsored by <a href="https://www.lambdatest.com/?utm_source=dashy&utm_medium=sponsor">LambdaTest</a> - Browser Testing</sup><br>
<a href="https://www.lambdatest.com/?utm_source=dashy&utm_medium=sponsor" target="_blank">
<img src="https://www.lambdatest.com/blue-logo.png" width="400" alt="LambdaTest" />
</a>
</p>
<p align="center">
<br>
<sup>Dashy is kindly sponsored by <a href="https://umbrel.com?ref=dashy">Umbrel</a> - the personal home cloud and OS for self-hosting</sup><br>
@ -16,6 +26,7 @@
</a>
</p>
> [!NOTE]
> Version [3.0.0](https://github.com/Lissy93/dashy/releases/tag/3.0.0) has been released, and requires some changes to your setup, see [#1529](https://github.com/Lissy93/dashy/discussions/1529) for details.
@ -411,6 +422,7 @@ Dashy supports multiple languages and locales. When available, your language sho
- 🇩🇪 **German**: `de` - Contributed by **[@Niklashere](https://github.com/Niklashere)**
- 🇬🇷 **Greek**: `el` - Contributed by **[@aviolaris](https://github.com/aviolaris)**
- 🇮🇳 **Hindi**: `hi` - _Auto-generated_
- 🇭🇺 **Hungarian**: `hu` - Contributed by **[@apgyorfi](https://github.com/apgyorfi)**
- 🇮🇹 **Italian**: `it` - Contributed by **[@alexdelprete](https://github.com/alexdelprete)**
- 🇯🇵 **Japanese**: `ja` - _Auto-generated_
- 🇰🇷 **Korean**: `ko` - Contributed by **[@boggy-cs](https://github.com/boggy-cs)**

View file

@ -72,6 +72,7 @@ Dashy has support for displaying dynamic content in the form of widgets. There a
- [Drone CI Build](#drone-ci-builds)
- [Linkding](#linkding)
- [Uptime Kuma](#uptime-kuma)
- [Uptime Kuma Status Page](#uptime-kuma-status-page)
- [Tactical RMM](#tactical-rmm)
- **[System Resource Monitoring](#system-resource-monitoring)**
- [CPU Usage Current](#current-cpu-usage)
@ -1491,6 +1492,7 @@ Allows web search using multiple user-defined search engines and other websites.
--- | --- | --- | ---
**`engines`** | `array` | required | An array of search engine objects. Each search engine object should have two required properties: **title** and **url**. See the example below.
**`placeholder`** | `string` | optional | Placeholder text in the search box.
**`openingMethod`** | `string` | optional | Open search in one of `newtab`, `sametab` or `workspace`.
#### Notes
- The first search engine in the engines array will be treated as the default search engine, and used when the user presses `Enter` in the search box.
@ -2670,6 +2672,40 @@ Linkding is a self-hosted bookmarking service, which has a clean interface and i
---
### Uptime Kuma Status Page
[Uptime Kuma](https://github.com/louislam/uptime-kuma) is an easy-to-use self-hosted monitoring tool.
#### Options
| **Field** | **Type** | **Required** | **Description** |
| ------------------ | -------- | ------------ | --------------------------------------------------------------------------------- |
| **`host`** | `string` | Required | The URL of the Uptime Kuma instance |
| **`slug`** | `string` | Required | The slug of the status page |
| **`monitorNames`** | `strins` | _Optional_ | Names of monitored services (in the same order as on the kuma uptime status page) |
#### Example
```yaml
- type: uptime-kuma-status-page
options:
host: http://localhost:3001
slug: another-beautiful-status-page
monitorNames:
- "Name1"
- "Name2"
```
#### Info
- **CORS**: 🟢 Enabled
- **Auth**: 🟢 Not Needed
- **Price**: 🟢 Free
- **Host**: Self-Hosted (see [Uptime Kuma](https://github.com/louislam/uptime-kuma) )
- **Privacy**: _See [Uptime Kuma](https://github.com/louislam/uptime-kuma)_
---
### Tactical RMM
[Tactical RMM](https://github.com/amidaware/tacticalrmm) is a self-hosted remote monitoring & management tool.

385
src/assets/locales/hu.json Normal file
View file

@ -0,0 +1,385 @@
{
"home": {
"no-results": "Nincs találat a keresésre",
"no-data": "Nincs beállítva adat",
"no-items-section": "Még nincs mit megjeleníteni"
},
"search": {
"search-label": "Keresés",
"search-placeholder": "Kezdj el gépelni a szűréshez",
"clear-search-tooltip": "Keresés törlése",
"enter-to-search-web": "Nyomj entert a webes kereséshez"
},
"splash-screen": {
"loading": "Betöltés"
},
"login": {
"title": "Dashy",
"guest-label": "Vendég hozzáférés",
"username-label": "Felhasználónév",
"password-label": "Jelszó",
"login-button": "Bejelentkezés",
"remember-me-label": "Emlékezz rám",
"remember-me-never": "Soha",
"remember-me-hour": "4 óráig",
"remember-me-day": "1 napig",
"remember-me-week": "1 hétig",
"remember-me-long-time": "Hosszabb ideig",
"error-missing-username": "Hiányzó felhasználónév",
"error-missing-password": "Hiányzó jelszó",
"error-incorrect-username": "A felhasználó nem található",
"error-incorrect-password": "Hibás jelszó",
"success-message": "Bejelentkezés folyamatban...",
"logout-message": "Kijelentkezve",
"already-logged-in-title": "Már be vagy jelentkezve",
"already-logged-in-text": "Be vagy jelentkezve mint",
"proceed-to-dashboard": "Tovább az irányítópultra",
"log-out-button": "Kijelentkezés",
"proceed-guest-button": "Belépés vendégként",
"guest-intro-1": "Ez a rendszer engedélyezi a vendég hozzáférést.",
"guest-intro-2": "A vendég felhasználók csak megtekinthetik az irányítópultokat, módosításokat nem tudnak menteni.",
"error": "Hiba",
"error-no-user-configured": "A hitelesítés nincs engedélyezve, vagy nincs beállított felhasználó",
"error-go-home-button": "Vissza a főoldalra",
"logged-in-guest": "Vendégként bejelentkezve, átirányítás...",
"error-guest-access": "A vendég hozzáférés nem engedélyezett"
},
"app-info": {
"title": "App Info",
"error-log": "Hibanapló",
"no-errors": "Nem található friss hiba",
"help-support": "Súgó és támogatás",
"help-support-description" : "Ha segítségre van szükséged a Dashy futtatásához vagy beállításához, nézd meg a",
"help-support-discussions": "fórumot",
"support-dashy": "Dashy támogatása",
"support-dashy-description": "Ha szeretnél részt venni a projektben, nézd meg a",
"support-dashy-link": "közreműködők oldalát",
"report-bug": "Hiba bejelentése",
"report-bug-description": "Ha úgy gondolod, hogy hibát találtál, kérlek",
"report-bug-link": "jelentsd be itt",
"more-info": "További információ",
"source": "Forráskód",
"documentation": "Dokumentáció",
"privacy-and-security": "Adatvédelem és biztonság",
"privacy-and-security-l1": "Ha szeretnéd megtudni, hogyan kezeli a Dashy az adataidat, nézd meg az",
"privacy-and-security-privacy-policy": "adatvédelmi irányelveinket",
"privacy-and-security-advice": "Ha tanácsot keresel az irányítópultod biztonságossá tételéhez, olvasd el a",
"privacy-and-security-advice-link": "kezelési útmutatót",
"privacy-and-security-security-issue": "Ha biztonsági hibát találtál, jelezd azt a",
"privacy-and-security-security-policy": "biztonsági szabályzatunk alapján",
"license": "Licenc",
"license-under": "Licenc típusa:",
"licence-third-party": "A harmadik féltől származó modulok licenceiért látogasd meg a",
"licence-third-party-link": "jogi oldalunkat",
"list-contributors": "A teljes közreműködői lista és köszönetnyilvánítás itt található:",
"list-contributors-link": "Készítők",
"version": "Verzió"
},
"config": {
"main-tab": "Főmenü",
"view-config-tab": "Beállítások megtekintése",
"edit-config-tab": "Beállítások szerkesztése",
"custom-css-tab": "Egyéni stílusok",
"heading": "Beállítási lehetőségek",
"download-config-button": "Megtekintés / Exportálás",
"edit-config-button": "Beállítások szerkesztése",
"edit-css-button": "Egyéni CSS szerkesztése",
"cloud-sync-button": "Szinkronizálás bekapcsolása",
"edit-cloud-sync-button": "Szinkronizálási beállítások szerkesztése",
"rebuild-app-button": "Alkalmazás újraépítése",
"change-language-button": "Nyelv módosítása",
"reset-settings-button": "Helyi beállítások visszaállítása",
"disabled-note": "Néhány beállítási lehetőséget a rendszergazda letiltott",
"small-screen-note": "Kis képernyőt használsz, ezért néhány menüelem nem tud jól megjelenni",
"app-info-button": "App infó",
"backup-note": "Módosítás előtt érdemes biztonsági mentést készíteni a beállításokról.",
"reset-config-msg-l1": "Ez törli az összes helyi beállítást, de nem módosítja a 'conf.yml' fájlt.",
"reset-config-msg-l2": "Mentsd el a helyi változtatásokat, ha később is használni akarod őket",
"reset-config-msg-l3": "Biztosan folytatod?",
"data-cleared-msg": "Az adatok sikeresen törölve",
"actions-label": "Műveletek",
"copy-config-label": "Beállítások másolása",
"data-copied-msg": "A konfiguráció a vágólapra másolva",
"reset-config-label": "Beállítások visszaállítása",
"css-save-btn": "Változtatások mentése",
"css-note-label": "Megjegyzés",
"css-note-l1": "A változtatások életbe lépéséhez frissítened kell az oldalt.",
"css-note-l2": "A stílusmódosítások csak helyben vannak mentve, ezért ajánlott másolatot készíteni a CSS-ről.",
"css-note-l3": "Az összes egyéni stílus eltávolításához töröld a tartalmat, majd mentsd a változtatásokat.",
"custom-css": {
"title": "Egyéni CSS",
"base-theme": "Alaptéma"
}
},
"alternate-views": {
"alternate-view-heading": "Váltás másik nézetre",
"default": "Alapértelmezett",
"workspace": "Munkaterület",
"minimal": "Minimalista"
},
"settings": {
"theme-label": "Téma",
"layout-label": "Elrendezés",
"layout-auto": "Automatikus",
"layout-horizontal": "Vízszintes",
"layout-vertical": "Függőleges",
"item-size-label": "Elem mérete",
"item-size-small": "Kicsi",
"item-size-medium": "Közepes",
"item-size-large": "Nagy",
"config-launcher-label": "Beállítások",
"config-launcher-tooltip": "Beállítások frissítése",
"sign-out-tooltip": "Kijelentkezés",
"sign-in-tooltip": "Bejelentkezés",
"sign-in-welcome": "Szia, {username}!",
"hide": "Elrejtés",
"open": "Megnyitás"
},
"updates": {
"app-version-note": "Dashy verzió",
"up-to-date": "Naprakész",
"out-of-date": "Frissítés elérhető",
"unsupported-version-l1": "A Dashy nem támogatott verzióját használod",
"unsupported-version-l2": "A legjobb élmény és a biztonsági javítások érdekében frissíts a következő verzióra"
},
"language-switcher": {
"title": "Alkalmazás nyelvének módosítása",
"dropdown-label": "Válassz nyelvet",
"save-button": "Mentés",
"success-msg": "A nyelv frissítve erre:"
},
"theme-maker": {
"title": "Téma szerkesztő",
"export-button": "Egyéni változók exportálása",
"reset-button": "Stílus visszaállítása ehhez:",
"show-all-button": "Összes változó megjelenítése",
"change-fonts-button": "Betűtípus módosítása",
"save-button": "Mentés",
"cancel-button": "Mégse",
"saved-toast": "{theme} sikeresen frissítve",
"copied-toast": "{theme} témához tartozó adatok a vágólapra másolva",
"reset-toast": "A(z) {theme} egyéni színei törölve"
},
"config-editor": {
"save-location-label": "Mentés helye",
"location-local-label": "Helyi mentés",
"location-disk-label": "Változások mentése a konfigurációs fájlba",
"save-button": "Változtatások mentése",
"preview-button": "Változtatások előnézete",
"valid-label": "A konfiguráció érvényes",
"status-success-msg": "Feladat sikeresen befejezve",
"status-fail-msg": "A feladat sikertelen volt",
"success-msg-disk": "A konfigurációs fájl sikeresen mentve a lemezre",
"success-msg-local": "A helyi változtatások sikeresen elmentve",
"success-note-l1": "A változtatások érvényesítéséhez frissítened kell az oldalt.",
"success-note-l2": "",
"success-note-l3": "",
"error-msg-save-mode": "Válaszd ki a mentés módját: helyi vagy fájlba mentés",
"error-msg-cannot-save": "Hiba történt a konfiguráció mentése közben",
"error-msg-bad-json": "Hibás JSON-formátum, valószínűleg rosszul van megadva",
"warning-msg-validation": "Érvényesítési figyelmeztetés",
"not-admin-note": "Nem írhatsz a lemezre, mert nem rendszergazdaként vagy bejelentkezve"
},
"app-rebuild": {
"title": "Alkalmazás újraépítése",
"rebuild-note-l1": "A változtatások érvényesítéséhez már nem szükséges újraépítés.",
"rebuild-note-l2": "Bizonyos beállítások (például a belépési pont és a hitelesítés) csak az építés során kerülnek betöltésre, ezért ezekhez újraépítést kell indítani.",
"rebuild-note-l3": "Ez a funkció csak Node és Docker telepítéseken érhető el, statikus verziókban nem.",
"rebuild-button": "Build indítása",
"rebuilding-status-1": "Build folyamatban...",
"rebuilding-status-2": "Ez néhány percet igénybe vehet",
"error-permission": "Nincs jogosultságod a folyamat elindításához",
"success-msg": "Az újraépítés sikeresen befejeződött",
"fail-msg": "Az újraépítés sikertelen volt",
"reload-note": "A változtatások érvényesítéséhez frissíteni kell az oldalt",
"reload-button": "Oldal újratöltése"
},
"cloud-sync": {
"title": "Mentés felhőbe, visszaállítás",
"intro-l1": "A mentés felhőbe, visszaállítás egy választható funkció, amellyel feltöltheted a beállításaidat az internetre, majd bármely másik Dashy példányban visszaállíthatod azokat.",
"intro-l2": "Minden adat teljes körűen AES titkosítással védett, ahol a jelszavad szolgál kulcsként.",
"intro-l3": "További információért lásd a",
"intro-docs": "dokumentációt",
"backup-title-setup": "Biztonsági mentés készítése",
"backup-title-update": "Mentés frissítése",
"password-label-setup": "Válassz jelszót",
"password-label-update": "Add meg a jelszavad",
"backup-button-setup": "Biztonsági mentés",
"backup-button-update": "Biztonsági mentés frissítése",
"backup-id-label": "Biztonsági mentés azonosítója",
"backup-id-note": "Ezt az azonosítót a későbbi visszaállításhoz használhatod, ezért őrizd meg biztonságos helyen a jelszavaddal együtt.",
"restore-title": "Biztonsági mentés visszaállítása",
"restore-id-label": "Visszaállítási azonosító",
"restore-password-label": "Jelszó",
"restore-button": "Visszaállítás",
"backup-missing-password": "Hiányzó jelszó",
"backup-error-unknown": "A kérés feldolgozása nem sikerült",
"backup-error-password": "Hibás jelszó. Kérlek, add meg a helyes jelszót.",
"backup-success-msg": "Sikeresen befejezve",
"restore-success-msg": "A beállítások sikeresen visszaállítva"
},
"menu": {
"open-section-title": "Megnyitás itt",
"sametab": "Jelenlegi fülön",
"newtab": "Új fülön",
"modal": "Felugró ablakban",
"workspace": "Munkaterület nézet",
"options-section-title": "Beállítások",
"edit-item": "Szerkesztés",
"move-item": "Másolás vagy áthelyezés",
"remove-item": "Eltávolítás"
},
"context-menus": {
"item": {
"open-section-title": "Megnyitás itt",
"sametab": "Jelenlegi fülön",
"newtab": "Új fülön",
"modal": "Felugró ablakban",
"workspace": "Munkaterület nézet",
"clipboard": "Másolás vágólapra",
"options-section-title": "Beállítások",
"edit-item": "Szerkesztés",
"move-item": "Másolás vagy áthelyezés",
"remove-item": "Eltávolítás",
"copied-toast": "Az URL a vágólapra másolva"
},
"section": {
"open-section": "Szakasz megnyitása",
"edit-section": "Szerkesztés",
"expand-collapse": "Kinyitás / Összecsukás",
"move-section": "Áthelyezés ide",
"remove-section": "Eltávolítás"
}
},
"footer": {
"dev-by": "Fejlesztette",
"licensed-under": "Licenc típusa:",
"get-the": "Nézd meg a",
"source-code": "forráskódot"
},
"interactive-editor": {
"menu": {
"start-editing-tooltip": "Belépés az interaktív szerkesztőbe",
"edit-site-data-subheading": "Oldaladatok szerkesztése",
"edit-page-info-btn": "Oldalinformációk szerkesztése",
"edit-page-info-tooltip": "Alkalmazás címe, leírása, menülinkek, lábléc szöveg stb.",
"edit-app-config-btn": "Alkalmazás beállításainak szerkesztése",
"edit-app-config-tooltip": "Az alkalmazás összes további beállítási lehetősége",
"edit-pages-btn": "Oldalak szerkesztése",
"edit-pages-tooltip": "További nézetek hozzáadása vagy eltávolítása",
"config-save-methods-subheading": "Mentési beállítások",
"save-locally-btn": "Mentés helyileg",
"save-locally-tooltip": "A konfiguráció helyi mentése a böngészőben. Ez nem módosítja a konfigurációs fájlt, és csak ezen az eszközön marad meg.",
"save-disk-btn": "Mentés lemezre",
"save-disk-tooltip": "A konfiguráció mentése a conf.yml fájlba. Biztonsági mentést készít, majd felülírja a meglévő beállításokat.",
"export-config-btn": "Beállítások exportálása",
"export-config-tooltip": "A beállítások megtekintése és exportálása fájlba vagy vágólapra",
"cloud-backup-btn": "Mentés felhőbe",
"cloud-backup-tooltip": "Titkosított konfigurációs mentés feltöltése a felhőbe",
"edit-raw-config-btn": "Nyers konfiguráció szerkesztése",
"edit-raw-config-tooltip": "A nyers konfiguráció megtekintése és módosítása JSON szerkesztőben",
"cancel-changes-btn": "Szerkesztés megszakítása",
"cancel-changes-tooltip": "A jelenlegi módosítások visszaállítása és a szerkesztési mód bezárása. A mentett beállításokat nem érinti.",
"edit-mode-name": "Szerkesztési mód",
"edit-mode-subtitle": "Jelenleg szerkesztési módban vagy",
"edit-mode-description": "Ez azt jelenti, hogy módosíthatod a beállításokat és megtekintheted az eredményt, de a változtatások nem lesznek automatikusan mentve, amíg kézzel el nem mented azokat.",
"save-stage-btn": "Mentés",
"cancel-stage-btn": "Mégse",
"save-locally-warning": "Ha folytatod, a változtatások csak a böngészőben kerülnek mentésre. Javasolt egy másolat exportálása más eszközök használatához. Szeretnéd folytatni?"
},
"edit-item": {
"missing-title-err": "Hiányzó elemcím"
},
"edit-section": {
"edit-section-title": "Szakasz szerkesztése",
"add-section-title": "Új szakasz hozzáadása",
"edit-tooltip": "Kattints a szerkesztéshez, vagy jobb klikk a további lehetőségekért",
"remove-confirm": "Biztosan törölni szeretnéd ezt a szakaszt? Ez a művelet később nem vonható vissza."
},
"edit-app-config": {
"warning-msg-title": "Csak óvatosan!",
"warning-msg-l1": "A következő beállítások haladó konfigurációhoz valók.",
"warning-msg-l2": "Ha nem vagy biztos benne, hogy melyik mező mire való, olvass utána a",
"warning-msg-docs": "dokumentációban,",
"warning-msg-l3": "hogy elkerüld a nem kívánt következményeket."
},
"export": {
"export-title": "Konfiguráció exportálása",
"copy-clipboard-btn": "Másolás vágólapra",
"copy-clipboard-tooltip": "Az összes beállítás másolása a vágólapra YAML formátumban",
"download-file-btn": "Letöltés fájlként",
"download-file-tooltip": "Az összes beállítás letöltése YAML fájlként az eszközre",
"view-title": "Beállítások megtekintése"
}
},
"critical-error": {
"title": "Konfigurációs betöltési hiba",
"subtitle": "A Dashy nem tudott megfelelően betöltődni a konfigurációs hiba miatt.",
"sub-ensure-that": "Győződj meg róla, hogy",
"sub-error-details": "Hiba részletei",
"sub-next-steps": "Következő lépések",
"ignore-button": "Kritikus hibák figyelmen kívül hagyása"
},
"widgets": {
"general": {
"loading": "Betöltés",
"show-more": "Részletek megjelenítése",
"cpu-details": "CPU adatai",
"mem-details": "Mamória adatai",
"show-less": "Kevesebb megjelenítése",
"open-link": "Tovább olvasás"
},
"pi-hole": {
"status-heading": "Állapot"
},
"stat-ping": {
"up": "Online",
"down": "Offline"
},
"net-data": {
"cpu-chart-title": "CPU-használat",
"mem-chart-title": "Memóriahasználat",
"mem-breakdown-title": "Memória-összeomlás",
"load-chart-title": "Rendszerterhelés"
},
"glances": {
"disk-space-free": "Szabad",
"disk-space-used": "Foglalt",
"disk-mount-point": "Csatolás helye",
"disk-file-system": "Fájlrendszer",
"disk-io-read": "Olvasás",
"disk-io-write": "Írás",
"system-load-desc": "A futási sorban várakozó folyamatok száma, az összes mag átlaga"
},
"system-info": {
"uptime": "Rendszer futási ideje"
},
"flight-data": {
"arrivals": "Érkezések",
"departures": "Indulások"
},
"tfl-status": {
"good-service-all": "Minden vonalon zavartalan a közlekedés",
"good-service-rest": "Minden más vonalon zavartalan a közlekedés"
},
"synology-download": {
"download": "Letöltés",
"upload": "Feltöltés",
"downloaded": "Letöltve",
"uploaded": "Feltöltve",
"remaining": "Hátralévő",
"up": "Feltöltés",
"down": "Letöltés"
},
"gluetun-status": {
"vpn-ip": "VPN IP-cím",
"country": "Ország",
"region": "Vármegye / Régió",
"city": "Város",
"post-code": "Irányítószám",
"location": "Cím / Földrajzi hely",
"timezone": "Időzóna",
"organization": "Szervezet"
}
}
}

View file

@ -7,7 +7,7 @@
<div class="buttons">
<button
v-for="(engine, key) in engines" :key="key"
v-on:click="search(engine)">
v-on:click="search(engine, openingMethod)">
{{ engine.title }}
</button>
</div>
@ -15,7 +15,9 @@
</template>
<script>
import router from '@/router';
import WidgetMixin from '@/mixins/WidgetMixin';
import ErrorHandler from '@/utils/ErrorHandler';
export default {
mixins: [WidgetMixin],
@ -35,11 +37,28 @@ export default {
defaultEngine() {
return this.engines[0];
},
openingMethod() {
return this.options.openingMethod || '';
},
},
methods: {
search(engine) {
search(engine, openingMethod) {
if (engine !== undefined && this.query !== '') {
window.open(engine.url + this.query, '_blank');
const url = engine.url + this.query;
switch (openingMethod) {
case 'newtab':
window.open(url, '_blank');
break;
case 'sametab':
window.open(url, '_self');
break;
case 'workspace':
router.push({ name: 'workspace', query: { url } });
break;
default:
ErrorHandler(`Unknown opening method: ${openingMethod}`);
window.open(url, '_blank');
}
}
},
},

View file

@ -5,7 +5,7 @@
Live {{ direction !== 'both' ? direction: 'flight' }} data from {{ airport }}
</p>
<!-- Departures -->
<div v-if="departures.length > 0" class="flight-group">
<div v-if="direction !== 'arrival' && departures.length > 0" class="flight-group">
<h3 class="flight-type-subtitle" v-if="direction === 'both'">
{{ $t('widgets.flight-data.departures') }}
</h3>
@ -16,7 +16,7 @@
</div>
</div>
<!-- Arrivals -->
<div v-if="arrivals.length > 0" class="flight-group">
<div v-if="direction !== 'departure' && arrivals.length > 0" class="flight-group">
<h3 class="flight-type-subtitle" v-if="direction === 'both'">
{{ $t('widgets.flight-data.arrivals') }}
</h3>
@ -137,10 +137,12 @@ export default {
flights.forEach((flight) => {
results.push({
number: flight.number,
airline: flight.airline.name,
aircraft: flight.aircraft.model,
airport: flight.movement.airport.name,
time: flight.movement.actualTimeUtc,
airline: flight.airline?.name ?? "unknown airline",
aircraft: flight.aircraft?.model ?? "unknown aircraft",
airport: flight.movement?.airport?.name ?? "unknown airport",
time: flight.movement
? (flight.movement?.revisedTime?.local ?? flight.movement?.scheduledTime?.local ?? "unknown time")
: "unknown time"
});
});
return results;

View file

@ -0,0 +1,199 @@
<template>
<div @click="openStatusPage" class="clickable-widget">
<template v-if="errorMessage">
<div class="error-message">
<span class="text">{{ errorMessage }}</span>
</div>
</template>
<template v-else-if="lastHeartbeats">
<div
v-for="(heartbeat, index) in lastHeartbeats"
:key="index"
class="item-wrapper"
>
<div class="item monitor-row">
<div class="title-title">
<span class="text">
{{
monitorNames && monitorNames[index]
? monitorNames[index]
: `Monitor ${index + 1}`
}}
</span>
</div>
<div class="monitors-container">
<div class="status-container">
<span
class="status-pill"
:class="getStatusClass(heartbeat.status)"
>
{{ getStatusText(heartbeat.status) }}
</span>
</div>
</div>
</div>
</div>
</template>
</div>
</template>
<script>
import WidgetMixin from '@/mixins/WidgetMixin';
export default {
mixins: [WidgetMixin],
data() {
return {
lastHeartbeats: null,
errorMessage: null,
errorMessageConstants: {
missingHost: 'No host set',
missingSlug: 'No slug set',
},
};
},
computed: {
host() {
return this.parseAsEnvVar(this.options.host);
},
slug() {
return this.parseAsEnvVar(this.options.slug);
},
monitorNames() {
return this.options.monitorNames || [];
},
endpoint() {
return `${this.host}/api/status-page/heartbeat/${this.slug}`;
},
statusPageUrl() {
return `${this.host}/status/${this.slug}`;
},
},
mounted() {
this.fetchData();
},
methods: {
update() {
this.startLoading();
this.fetchData();
},
fetchData() {
const { host, slug } = this;
if (!this.optionsValid({ host, slug })) {
return;
}
this.makeRequest(this.endpoint)
.then(this.processData)
.catch((error) => {
this.errorMessage = error.message || 'Failed to fetch data';
});
},
processData(response) {
const { heartbeatList } = response;
const lastHeartbeats = [];
// Use Object.keys to safely iterate over heartbeatList
Object.keys(heartbeatList).forEach((monitorId) => {
const heartbeats = heartbeatList[monitorId];
if (heartbeats.length > 0) {
const lastHeartbeat = heartbeats[heartbeats.length - 1];
lastHeartbeats.push(lastHeartbeat);
}
});
this.lastHeartbeats = lastHeartbeats;
},
optionsValid({ host, slug }) {
const errors = [];
if (!host) errors.push(this.errorMessageConstants.missingHost);
if (!slug) errors.push(this.errorMessageConstants.missingSlug);
if (errors.length > 0) {
this.errorMessage = errors.join('\n');
return false;
}
return true;
},
openStatusPage() {
window.open(this.statusPageUrl, '_blank');
},
getStatusText(status) {
switch (status) {
case 1:
return 'Up';
case 0:
return 'Down';
case 2:
return 'Pending';
case 3:
return 'Maintenance';
default:
return 'Unknown';
}
},
getStatusClass(status) {
switch (status) {
case 1:
return 'up';
case 0:
return 'down';
case 2:
return 'pending';
case 3:
return 'maintenance';
default:
return 'unknown';
}
},
},
};
</script>
<style scoped lang="scss">
.clickable-widget {
cursor: pointer;
}
.status-pill {
border-radius: 50em;
box-sizing: border-box;
font-size: 0.75em;
display: inline-block;
font-weight: 700;
text-align: center;
white-space: nowrap;
vertical-align: baseline;
padding: 0.35em 0.65em;
margin: 0.1em 0.5em;
min-width: 64px;
&.up {
background-color: #5cdd8b;
color: black;
}
&.down {
background-color: #dc3545;
color: white;
}
&.pending {
background-color: #f8a306;
color: black;
}
&.maintenance {
background-color: #1747f5;
color: white;
}
&.unknown {
background-color: gray;
color: white;
}
}
.monitor-row {
display: flex;
justify-content: space-between;
padding: 0.35em 0.5em;
align-items: center;
}
.title-title {
font-weight: bold;
}
.error-message {
color: red;
font-weight: bold;
}
</style>

View file

@ -123,6 +123,7 @@ const COMPAT = {
'tfl-status': 'TflStatus',
trmm: 'TacticalRMM',
'uptime-kuma': 'UptimeKuma',
'uptime-kuma-status-page': 'UptimeKumaStatusPage',
'wallet-balance': 'WalletBalance',
weather: 'Weather',
'weather-forecast': 'WeatherForecast',

View file

@ -10,6 +10,7 @@ import el from '@/assets/locales/el.json';
import es from '@/assets/locales/es.json';
import fr from '@/assets/locales/fr.json';
import hi from '@/assets/locales/hi.json';
import hu from '@/assets/locales/hu.json';
import it from '@/assets/locales/it.json';
import ja from '@/assets/locales/ja.json';
import ko from '@/assets/locales/ko.json';
@ -98,6 +99,12 @@ export const languages = [
locale: hi,
flag: '🇮🇳',
},
{ // Hungarian
name: 'Magyar',
code: 'hu',
locale: hu,
flag: '🇭🇺',
},
{ // Italian
name: 'Italiano',
code: 'it',